关于sizeof()与strlen()的详解与题例

🎁🎁创作不易,关注作者不迷路🎀🎀


前言

本章将详解strlen与sizeof(),几乎覆盖到与之对应所有相关重难点,不管您是编程小白,还是行业大佬,相信阅读过后对您有一定启发。如果您有任何不懂的地方,欢迎您将疑惑点置于评论区,让更多人看到,一起讨论或许是不错的解决办法哟,当然也欢迎您私信我,看到后也将为您详细解答,能够帮助到他人是我莫大的荣幸。如果您觉得作者写得不错,抑或对您有所帮助,不妨给俺点个免费的赞和玩玩呢?     关注俺不迷路,后续将有更多原创内容更新哟


一、两者的定义

1.sizeof和strlen的对⽐

sizeof()

 sizeof 计算变量所占内存内存空间⼤⼩的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据

strlen()

strlen 是C语⾔库函数,功能是求字符串⻓度。函数原型如下:
size_t strlen ( const char * str );                          一定要注意其参数是字符类型的指针
统计的是从 strlen 函数的参数 str 中这个地址开始向后'\0' 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为⽌,所以可能存在越界查找

2.sizeof()和strlen()的对⽐

sizeof()strlen()
1. sizeof是操作符
2. sizeof计算操作数所占内存的⼤⼩,单位是字节
3. 不关注内存中存放什么数据

1. strlen是库函数,使⽤需要包含头⽂件 string.h 2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数

3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能会越界

二、就重难点与易错的点播

在此知识点的考察中,数组名是重点考察对象。

多数情况下,可以认为数组名就是数组首元素的地址,但排除以下两种情况:

sizeof(arr)表示的是整个数组
&arr表示的是整个数组的地址

三、题例分析

1.一维数组

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]+1));

sizeof(a+0)a没有以sizeof(a)的形式出现,因此a为首元素的地址。a+0依然表示是元素地址,地址与元素类型、大小均无关仅与编译环境有关。在x86环境下为4字节,在x64环境下为8字节4或8
sizeof(*a)a没有以sizeof(a)的形式出现,因此a为首元素的地址。*a解引用得到整数1。4
sizeof(&a)&a得到的是整个数组的地址,而地址与元素类型、大小均无关,仅与编译环境有关。在x86环境下为4字节,在x64环境下为8字节。4或8
sizeof(*&a)&a得到的是整个数组的地址,解引用得到整个数组16
sizeof(&a+1)&a+1跳过了整个数组后的那个地址,但也是地址4或8
sizeof(&a[0]+1)&a[0]+1得到的是第二个元素的地址4或8

2.字符数组

字符数组(一)

    strlen

char arr[] = {"a,b,c,d,e,f"};
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
strlen(arr+0))arr得到的是首元素的地址6
strlen(*arr))对arr解引用得到的是首元素‘a’,其ASCII 码值是97,因此计算机将从为97的地址向后寻找‘\0’这显然是不合理的因此其结果为err(错误)err
strlen(arr[1]))arr[1]得到第二个元素,与上同理,亦为errerr
 strlen(&arr))&arr得到整个数组的地址,指针同样在首元素的前边6
strlen(&arr+1))得到第二个元素的地址5
strlen(&arr[0]+1))第二个元素的地址5

sizeof()

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
sizeof(arr)数组arr中不仅包含六个字母字符,还包含字符‘\0’7

字符数组(二)

注意:p为指针,存放的是数组首元素的地址

sizeof()

char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p[0]+1));
sizeof(p)p为首元素的地址4或8
sizeof(*p)对p解引用得到首元素1
sizeof(p[0])p[0]就等价于*(p+0)因此得到的还是首元素1
sizeof(&p)得到的是指针p的存储地址4或8
sizeof(&p[0]+1)首元素地址加一得到的是第二个元素的地址4或8

strlen

char *p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));

strlen(p)

p为首元素的地址6
strlen(*p)解引用得到首元素,结果为err(详解见上)err
strlen(p[0])p[0]等价于*(p+0),结果为errerr
strlen(&p)随机值
strlen(&p+1)随机值
strlen(&p[0]+1)p[0]等价于*(p+0)得到‘a’,再取其地址,指针再向后移动一位5

3.二维数组

注:对于二维数组来讲,其数组名是第一行的地址

int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(a[3]));

sizeof(a)以sizeof(a)形式出现,表示整个数组  3*4*448
sizeof(a[0])以sizeof(a[0])形式出现,表示第一行 4*416
sizeof(a[0]+1)a[0]并没有单独出现在sizeof()内部因此a[0]表示的是第一行的首元素的地址,即此处a[0]等价于a[0][0]的地址4或8
sizeof(&a[0]+1)a[0]以&a[0]的形式出现,表示第一行的地址,后移一位,得到第二行的地址4或8
sizeof(*(&a[0]+1))得到的是第二行 16
sizeof(a[3])注意:此处并不存在越界,因为不会真是访问空间内存,仅通过推导便可得到长度16

  • 如果对大家有帮助,请三连支持一下!
  • 有问题欢迎评论区留言,及时帮大家解决!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值