用例题看懂操作符sizeof与strlen函数在数组中的运用

前言:首先要明确的是,sizeof不是函数,只是作为一个操作符,用于计算某一量所占空间大小,这个量可以是任意类型,计算结果的单位是字节;而strlen是一个函数,在使用时需要引用头文件<string.h>,其作用只是用来计算字符串的大小,单位同样是字节,此外,strlen函数计算的是字符'\0'之前的字符,在遇到'\0'后停止,而sizeof对于'\0'同样会计算其大小,这点需要我们注意,不要混淆。接下来就让我们来看几组题目,来理清楚sizeof以及strlen函数的使用。


题1:sizeof相关

在做这道题之前,首先我们需要知道有关数组名的知识:

般情况下,数组名都是表示数组的首元素的地址,但有两个例外需要我们特别注意,

  1. 1.取地址加数组名,此时的地址为整个数组的地址大小,如此题的&a;
  2. 2.数组名单独出现在sizeof中,此时的a表示的是整个数组大小,如此题中的sizeof(a);

知道了这个知识,我们再来看这道题:

首先第一个打印的结果为16,如上面所说, 这里的a是单独出现在sizeof中,属于第二种特殊情况,此时计算的是整个数组大小,不难知道,此数组是有4个int型的元素组成,故其结果为4*4=16。

第二个打印结果,sizeof中的a并不是单独的出现,此时的a为数组的首元素地址,而首元素地址a+0,其结果不变,此时sizeof计算的是指针(地址)大小,而我们知道,指针在不同平台下大小不同, 但其大小都是为4或8个字节大小,这里是64位环境下编译,所以得到结果为8。

第三个打印结果,sizeof中的a也不是单独出现,此时的a表示首元素1的地址,对a进行解引用操作(即*a),得到首元素地址处的元素1,其类型为int型,占4个字节,所以得到结果为4。

第四个打印结果,sizeof中a+1表示数组第二个元素地址,同样在64位环境下得到结果8

第五个打印结果,sizeof中a[1]无疑表示为数组第二个元素,计算int型大小,得到结果4

第六个打印结果,sizeof中&a表示整个数组地址,但由于地址大小固定为4或8个字节,在64位环境下得到结果8。

剩余三个结果与第六个结果相同,sizeof计算的都为地址大小,所以得到结果8,值得一提的是,&a+1表示的是从首元素地址处跳过整个数组大小的地址,也就是首元素加上4*4大小后的地址。


题2:sizeof相关

首先我们要知道,p为一个指针,其存储的地址是为字符串”abcdef“首地址'a'的地址

前两个打印结果均为8,原因是p为sizeof计算的为'a'的地址,p+1为sizeof计算的为'b'的地址,在64位编译环境下,得到结果8

第三个结果为1,无疑,*p表示的是首元素'a',计算char型的字符,得到结果。

第四个结果也为1,这里的p[0]实际上可以表示为*(p+0),也就是从首元素地址a+0,再对该地址解引用,其结果也是得到元素'a',所以最终结果也为1。

最后三个结果都是地址,结果为计算指针大小,所以能够很容易得到结果8,但值得一提的是,&p表示的是指针p的地址,而&p+1,表示的则是指针p的地址加上1后的地址,这两个地址都与字符串地址没有任何关系。


 题3:sizeof相关

 关于二维数组相关的知识,其数组名的规则与一维数组相同,但其数组名表示首元素地址的时候,代表的是第一行的地址,而不是第一行第一列元素的地址。

第一个打印结果为48,数组名单独出现在sizeof中,符合第一种特殊情况,代表整个数组的大小,即3*4*4=48。

第二个结果为16,二维数组可以抽象看成一个一维数组,其中每个元素又是一个一维数组所构成,所以这里的a[0]相当于二维数组第一行的数组名,而数组名单独出现在sizeof则表示整个数组,也就是表示为第一行的全部元素,该二维数组每行共4个元素,且都为int型,所以结果为4*4=16。

第三个结果为8,这里的a[0]不是单独出现的,此时的a[0]表示的是第一行元素的首元素地址,也就是第一行第一列的地址,在a[0]的基础上加上1,则表示为第一行第二个元素的地址,而地址在64位编译环境下表示的大小是8个字节,所以得到结果为8。

第四个结果为4,a[0]+1第一行第二个元素地址,再对其进行解引用操作得到该地址处元素,最后sizeof计算自然得到结果4。

第五个结果为8,a为二维数组首元素地址,即第一行地址,加1后得到第二行的地址,sizeof计算地址大小,在64位编译环境下得到结果8。

第六个结果为16,我们知道a+1为第二行的地址,对其解引用操作后对第二行元素进行访问,代表整个第二行所有元素,sizeof计算得到4*4=16。也可以理解为*(a+1)表示a[1],此时也表示为第二行所有元素,同样得到结果16。

第七个结果为8,这里的&a[0]表示第一行的地址,此处的指针为数组指针类型int(*)[4]加上1之后要跳过一行元素,即加1之后得到第二行的地址,同样64位环境下得到结果8。

最后一个结果为16,在&a[0]+1的基础上对其解引用操作,访问第二行的元素,sizeof计算第二行全部元素,得到结果4*4=16。


题1:strlen相关

第一个打印结果,strlen中的arr表示,数组首元素的地址,从首元素地址处往后计算大小,但我们会发现,数组arr中没有结束转义字符'\0',所以,strlen函数将会一直读取字符,直到出现'\0',而我们并不知道,内存中后续空间中会第几个读取到'\0',所以最后打印出来的结果是任意的随机值。

第二个结果,arr+0表示数组首元素地址,同样会得到与第一个相同的结果。

第三个结果,&a表示的是整个数组的地址,这里我们需要知道的是,整个数组的地址与数组的首元素地址是相同的,所以,再次出现结果随机值。

第四个结果,&arr+1则表示从数组的首元素跳过整个数组大小的地址,指向的是字符f后一个字节空间处的地址,同样的,我们也并不清楚读取到'\0'时的位置,所以打印结果仍然是随机值。

再来看最后两个结果,与前面不同,这两结果出奇的是报错,运行不了,首先*arr表示的是数组第一个元素,也就是'a',而我们知道,strlen函数在计算字符串大小是所传递的参数本质上都是地址,通过地址依次往后访问,直到读取到'\0',而这里的'a'在ASCLL码表值中表示的是97,所以,'a'在被当做参数传递给strlen函数后,被转化为十六进制的地址97往后进行访问,而这就造成了非法访问,程序编译无法运行,同样的arr[1]为'b',在传递到strlen函数作为参数时,被转化为地址98,同样是非法访问,程序无法运行。


题2:strlen相关

 与前一题有所不同,字符串的末尾会默认添加一个转义字符'\0'。

前两个结果,arr代表首元素地址,从首元素处开始统计字符串个数,直到读取到最后一个字符f后隐藏的字符'\0'的到字符串长度,同理arr+0也表示从首元素地址处开始读取字符,最后得到结果6。

第三,四个的结果都为错误,无法运行,原因与上一题相同,*arr表示首元素'a',而arr[1]表示第二个元素'b',这两个被作为参数传递在strlen函数中,分别表示地址97,98,进而导致非法访问。

第五个结果为6,中&arr表示整个数组的地址,而首元素地址与整个数组的地址是相同的,所以从首元素地址处开始读取字符,得到结果6。

第六个结果为随机值,&arr+1,所表示的地址是,首元素地址跳过整个数组大小后的地址,也就是首元素地址加上7后的地址,此时我们不能知道读取到下一个'\0',需要读取多少字符,所以结果为随机值。

最后一个结果为5,原因是arr[0]为首元素地址,而arr[0]+1则表示为第二个元素地址,所以从第二个元素地址开始读取字符,得到结果5。


结语:相信如果看完的小伙伴们应该对sizeof操作符以及strlen函数的了解更加深刻了,看到这里,关于一些题目的分享就结束了,如果对你有帮助的话,还请不要吝啬你的点赞哦,如果有其他有意义的题目,我也会分享出来,我们下期再见啦!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值