当前位置: 首页 > news >正文

E29.【C语言】练习:sizeof和strlen的习题集(A)

目录:

Exercise 1:szioef 一维数组

Exercise 2:sizeof 字符数组

Exercise 3:strlen 字符数组

Exercise 1:szioef 一维数组

求下列代码打印结果

#define CRT_NO_WARNINGNESS 1
#include <stdio.h>
int main()
{int a[] = { 1,2,3,4 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a + 0));printf("%zd\n", sizeof(*a));printf("%zd\n", sizeof(a + 1));printf("%zd\n", sizeof(a[1]));printf("%zd\n", sizeof(&a));printf("%zd\n", sizeof(*&a));printf("%zd\n", sizeof(&a + 1));printf("%zd\n", sizeof(&a[0]));printf("%zd\n", sizeof(&a[0] + 1));return 0;
}

答案速查:

x86环境

x64环境

分析:

☑ printf("%zd\n", sizeof(a));

在这篇文章40.【C语言】指针(重难点)(E) 曾经讲过:

*注意:“数组名就是数组首元素的地址”有两个例外:

1.sizeof(数组名):这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

详细见20.5.【C语言】求长度(sizeof和strlen)的两种方式

2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(不等同于数组首元素的地址)

sizeof(数组名);结果为16

☑printf("%zd\n", sizeof(a + 0));

注意这里的sizeof(a+0);不等于sizeof(a);!!!

a+0代表数组的首元素地址+0,因此sizeof(地址);,结果为4/8

4/8含义:4或8个字节

x86环境:4个字节

x64环境:8个字节

☑ printf("%zd\n", sizeof(*a));

a是数组名,是数组首元素的地址,*a解引用为数组首元素,因此sizeof(元素);,又因为int类型,结果为4

☑ printf("%zd\n", sizeof(a + 1));

a+0代表数组的首元素地址+1,+1跳过4个字节,为第2个元素的地址,因此sizeof(地址);,结果为4/8

☑ printf("%zd\n", sizeof(a[1]));

a[1]是数组的首元素,因此sizeof(元素);,又因为int类型,结果为4

☑ printf("%zd\n", sizeof(&a));

&a为取a的地址(整个数组的地址),因此sizeof(地址);,结果为4/8

☑ printf("%zd\n", sizeof(*&a));

*与&抵消,即*&a等于a,等同于printf("%zd\n", sizeof(a));sizeof(数组名);结果为16

☑ printf("%zd\n", sizeof(&a + 1));

&a为取a的地址(整个数组的地址),地址+1还是地址,因此sizeof(地址);,结果为4/8

☑ printf("%zd\n", sizeof(&a[0]));

&a[0]是取数组首元素的地址,因此sizeof(地址);,结果为4/8

☑ printf("%zd\n", sizeof(&a[0] + 1));

地址+1还是地址,因此sizeof(地址);,结果为4/8

Exercise 2:sizeof 字符数组

求下列代码打印结果

#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr + 0));printf("%zd\n", sizeof(*arr));printf("%zd\n", sizeof(arr[1]));printf("%zd\n", sizeof(&arr));printf("%zd\n", sizeof(&arr + 1));printf("%zd\n", sizeof(&arr[0] + 1));return 0;
}

答案速查:

x86环境

x64环境

分析:

 ☑ printf("%zd\n", sizeof(arr));

sizeof(数组名);结果为6(char类型一个字符占一个字节,6*1==6)

 ☑ printf("%zd\n", sizeof(arr + 0));

解释同Exercise 1 ,结果为4/8

 ☑ printf("%zd\n", sizeof(*arr));

解释同Exercise 1 ,对arr解引用,代表首个字符'a',结果为1

 ☑ printf("%zd\n", sizeof(arr[1]));

sizeof(元素);,又因为char类型,结果为1

 ☑ printf("%zd\n", sizeof(&arr));

解释同Exercise 1 ,结果为4/8

☑ printf("%zd\n", sizeof(&arr + 1));

解释同Exercise 1 ,结果为4/8

☑ printf("%zd\n", sizeof(&arr[0] + 1));

解释同Exercise 1 ,结果为4/8

******一定要区分sizeof(地址);sizeof(元素);******

Exercise 3:strlen 字符数组

把Exercise 2代码中的sizeof全改成strlen并加上头文件#include <string.h>,求打印结果

附:strlen的声明和定义

_Check_return_
size_t __cdecl strlen(_In_z_ char const* _Str);

答案速查:

随机值

随机值

报错

报错

随机值

随机值

☑ printf("%zd\n", strlen(arr));

见20.5.【C语言】求长度(sizeof和strlen)的两种方式 结果为随机值

☑ printf("%zd\n", strlen(arr + 0));

arr是首元素的地址,+0还是首元素的地址,strlen从该地址向后统计直至遇到\0(此处和sizeof不一样),结果为随机值

细节部分:由strlen的声明和定义知,strlen接收的是const char* str,而arr代表char(*)[6],因此会发生强制类型转换

★★★ printf("%zd\n", strlen(*arr));

先看运行结果,发生报错

注意细节:0x0000061有点眼熟,查询字符a的ASCII码值,发现恰好61!

把首元素改成字符A,看看结果

0x0000041恰好是字符A的ASCII码值!

显然strlen(*arr)的逻辑是:把*arr转换成首元素,把首元素转换成ASCII码值并将后者当成地址去访问内存空间(从该地址处向后统计字符串直到遇见\0)

总结:strlen(字符)==strlen(字符所对应的ASCII码)==sizoef(地址)

Q:按理说应该能访问,为什么会报错?

A:当前程序并没有运行在0x0000041和0x0000061处,因此访问会报错

☑ printf("%zd\n", strlen(arr[1]));

arr[1]是数组第二个元素,解释同上一个

☑ printf("%zd\n", strlen(&arr));

&arr是数组的地址,也是数组开始位置的编号,strlen从该地址向后统计直至遇到\0(同arr和arr+0),结果为随机值

☑ printf("%zd\n", strlen(&arr + 1));

&arr + 1跳过整个数组,strlen向后统计直至遇到\0,结果为随机值

☑ printf("%zd\n", strlen(&arr[0] + 1));

&arr[0]+1是第二个元素的地址,strlen从该地址向后统计直至遇到\0,结果为随机值


http://www.mrgr.cn/news/14040.html

相关文章:

  • matlab 将数组从左向右翻转
  • 电子电气架构 --- 车载网简史(上)
  • 迷雾大陆辅助:VMOS云手机助力升级装备系统秘籍!
  • Python——xml.etree.ElementTree
  • SQL 注入之 sqlmap 实战
  • (二)、软硬件全开源智能手表,可全面高精度采集生命体征数据,进行健康检测。(HealthyPi Move)
  • 使用Python将应用程序添加进Linux/Windows/MacOS登录项
  • 异或+与+或
  • JavaWeb学习——原理篇学习
  • WHAT - 通过 react-use 源码学习 React(UI 篇)
  • 新华三H3C HCL配置IS-IS基本配置
  • 揭秘无线领夹麦克风五大行业隐秘:音质失真、隐私泄露需警惕!
  • 【kafa系列】kafka如何保证消息不丢失
  • 豆包 MarsCode试用体验
  • 中资优配:如何利用趋势线分析股票?还有哪些股票指标?
  • 关闭银河麒麟系统Qt Creator调试程序运行提示安全授权认证窗口
  • 极狐GitLab 17.3 重点功能解读
  • MySQL学习笔记之数据操作语言(DML)
  • 【C++第十五章】继承
  • 大模型在安全领域的十大应用场景及实现路径