寒假每日提升(2)[关于sizeof相关计算]

本文探讨了sizeof和strlen在C语言中的功能、区别,以及在处理字符串和数组时的计算行为,强调了sizeof用于计算内存占用,而strlen用于求字符串长度,特别指出在无终止符的情况下的可能问题。
摘要由CSDN通过智能技术生成

接受每一个人的批评,可是保留你自己的判断。 ——莎士比亚


1、sizeof是什么

当我们会想起sizeof是什么的时候,我们本能的应该会想到strlen的函数。而在刚刚开始学习的时候,我总是不知不觉的把两个类似作用的函数搞混,那么为了确定一下两者的具体意思。可以去官网搜一下strlen,sizeof在这里插入图片描述这里我就大概搜了一下,截图一下。sizeof应该是标准库,没搜到,下面听我解释吧,应该是能明白是什么意思的。

2、sizeof和strlen的区别

1、strlen是C语言库函数,功能是求字符串长度,正因为这样所以才要‘\0’的存在。
2、sizeof是计算变量在内存的占空间的大小,单位是字节。但是不需要‘\0’,因为这是计算空间大小而已。
attention:意味着对于一个字符串来说,虽然我们对于hello这种字符串以为只是 h,e,l,l,o这五个字符但是,对于计算机来说可不是这样。

int main()
{
	char s[] = { "abcdf" };
	return 0;
}

在这里插入图片描述
对于这段代码来说,计算机认为,只有字符串的时候,会在末尾加上’\0’,然后再sizeof的理解下,会将最后的这个计算在内(‘\0’)。而对于strlen,却和sizeof有点区别,strlen的计算是类似寻找‘\0’的位置,然后在找到‘\0’的时候计算出之前所有的个数,就像这样
在这里插入图片描述
当然,对于strlen来说,如果是计算一个这样的在这里插入图片描述
他将会报错,并且结果也不可相信,因为在我们定义的数组之外,‘\0’出现的位置是不确定的,如果再别的地方去再试一次也会出现不同的答案。

3、关于此类的计算题目

3、1、题目一

#include <stdio.h>
int main()
{
 char arr1[3] = {'a', 'b', 'c'};
 char arr2[] = "abc";
 printf("%d\n", strlen(arr1));
 printf("%d\n", strlen(arr2));
 /
 printf("%d\n", sizeof(arr1));
 printf("%d\n", sizeof(arr2));
 return 0;
}


很显然,这里strlen算不出arr1的数值,但是其他三个都能正确的判断吗?不懂可以回去再看看。

3、2、题目二(sizeof专题)

根据这篇文章,下面开始结合那天复习的内容,来点难一点的题目。

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%zd\n", sizeof(a));//1
	printf("%zd\n", sizeof(a + 0));//2
	printf("%zd\n", sizeof(*a));//3
	printf("%zd\n", sizeof(a + 1));//4
	printf("%zd\n", sizeof(&a));//5
	printf("%zd\n", sizeof(*&a));//6
	printf("%zd\n", sizeof(&a[0] + 1));//7
	return 0;
}

在这里插入图片描述
答案分别是这个,你写对了吗?
那么关于这题,细细道来。
第一题,毫无疑问数组名就是数组首元素的地址,并且在sizeof里面时,只有数组名的时候,是会认为是整个的数组,因而确定了数组地址之后,就会按照数组里面的内容进行一次访问,直到结束。所以又是因为是按照字节的方式去计算,所以毫无疑问是16。
第二题,由于第一题里面讲过了,所以说这里引进不再是单纯的数组名,所以这里就算是地址。并且这个的地址指向的就是第一个元素,所以根据地址来说,他应该是4/8。
第三题,对a进行解引用,那么这也不算是真正的数组名了,所以解引用之后也就变成了首个元素而已了。所以答案是4。
第四题,同理,不是单纯的首元素地址,并且没有解引用的存在,所以是地址。所以答案是4/8。
第五题,不用说了,直接是取地址,所以答案是4/8。第七题也这样,就不再多说了。
第六题,对于既取地址,又解引用,导致最后相当于还是最单纯的首元素地址,所以答案和第一题一样。

3、3、题目三(strlen专题)

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", strlen(arr));//1
	printf("%d\n", strlen(arr + 0));//2
	printf("%d\n", strlen(*arr));//3
	printf("%d\n", strlen(arr[1]));//4
	printf("%d\n", strlen(&arr));//5
	printf("%d\n", strlen(&arr + 1));//6
	printf("%d\n", strlen(&arr[0] + 1));//7
	return 0;
}

对于strlen来说,计算的必要条件是是遇见‘\0’,所以对于一个这样的数组,本身是没有‘\0‘的,所以对于题目一来说,他的答案是随机的。
题目二记住strlen是一个C语言库函数,功能是求字符串长度,所以这时候才会和之前的sizeof有所区别,区别就是此时,他还是会照样的像题目一一样,访问,但是没有’\0‘,所以还是随机访问。
题目三,解引用数组名,也就是首元素,所以应该是’a‘(97),但是对于strlen来说,这样子算是非法访问,会出现错误情况。题目四同理,只不过是’b‘(98)而已。
题目五,还是随机值,照样是和第一题答案是相同的。因为要明白==size_t strlen ( const char * str );==是strlen的传参的内容。与题目六和题目七是同样的

4、简单总结

sizeofstrlen
操作符库函数,使用得包含string.h
计算操作数所占内存大小,单位是字节求字符串长度,统计的是’\0‘之前的字符个数
不关注求的是什么类型关注是否有’\0‘,若不存在,则可能会越界,只计算字符串类型
  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值