接受每一个人的批评,可是保留你自己的判断。 ——莎士比亚
当我们会想起sizeof是什么的时候,我们本能的应该会想到strlen的函数。而在刚刚开始学习的时候,我总是不知不觉的把两个类似作用的函数搞混,那么为了确定一下两者的具体意思。可以去官网搜一下strlen,sizeof这里我就大概搜了一下,截图一下。sizeof应该是标准库,没搜到,下面听我解释吧,应该是能明白是什么意思的。
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’出现的位置是不确定的,如果再别的地方去再试一次也会出现不同的答案。
#include
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的数值,但是其他三个都能正确的判断吗?不懂可以回去再看看。
根据这篇文章,下面开始结合那天复习的内容,来点难一点的题目。
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。第七题也这样,就不再多说了。
第六题,对于既取地址,又解引用,导致最后相当于还是最单纯的首元素地址,所以答案和第一题一样。
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的传参的内容。与题目六和题目七是同样的
sizeof | strlen |
---|---|
操作符 | 库函数,使用得包含string.h |
计算操作数所占内存大小,单位是字节 | 求字符串长度,统计的是’\0‘之前的字符个数 |
不关注求的是什么类型 | 关注是否有’\0‘,若不存在,则可能会越界,只计算字符串类型 |