sizeof与strlen具体区别

在c语言中,我们通常使用sizeof和strlen来计算各种长度,如字符串长度,整形或者字符型所占字节等等。但当结合到指针以后,这些题目便显得略微复杂了。那么,要如何正确的利用好sizeof和strlen呢?下文,就是我的学习经历。

首先,sizeof是操作符,是不需要额外添加头文件的。sizeof它的工作是计算变量所占字节大小,它不关心变量内容,它只关心类型。

而strlen是从属与string.h的库函数,它的功能是求字符串长度。其原型如下:

size_t strlen(const char *str);

它的工作原理是从传入的地址出发,向后进行查询,直到找到\0,它会返回从初始位置到\0的所有数据的数量。当没找到\0时,它会返回一个随机值。

而利用sizeof与strlen,我们可以更好的理解数组与指针的相关细微知识点。

int main()
{

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr+1));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr+1));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(*&arr));
	printf("%d\n", sizeof(&arr+1));
	printf("%d\n", sizeof(&arr[0]));
	printf("%d\n", sizeof(&arr[0]+1));
	return 0;

首先,我们先小试牛刀,利用一维数字数组来试试看。

第一行打印的是arr的大小,在这里,arr单独存在于sizeof内部,所以它计算的是数组所有字节加起来的大小。答案是40.

第二行打印的是(arr+1)的大小,在这里arr不是表示数组名的,而是表示数组首元素地址,但凡是地址,大小就是4/8个字节。

第三行打印的是(*arr)的大小,这里的arr是首元素地址,所以它是计算arr[0]的大小,arr[0]就是1,1是int类型的数据,答案就是4.

第四行打印的(arr+1)的大小,这里arr也表示数组首元素,所以它计算的是2这个数字的地址,地址大小是4/8

第五行打印的是arr[1]的大小,arr[1]是2,是int类型的数据,其大小就是4.

第六行打印的是&arr的大小,计算的是arr整个数组的地址,是地址就是4/8.

第七行打印的是*&arr,先取地址后又解引用,相当于没有进行操作,所以算的是arr的大小,答案是40.

第八行打印的是(&arr+1)的值,相当于arr的地址整个加一,跳过40字节,但是打印出来的依旧是一个地址,答案是4/8.

第九行打印的是(&arr[0]),就是取1的地址,,最终结果就是arr[0]的地址,答案是4/8

第十行打印的与第九行类似,依旧是计算地址,所以答案依旧是4/8.

综上,我们简单概括一下几点:

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

2:&数组名,这里的数组名表示的也是整个数组,取地址以后得到的就是整个数组的地址.

3:除此以外所有数组名都是表示首元素的地址,无论是多了个*或者是[].

一维字符数组字符的sizeof计算与上面类似,我们重点讲一下字符数组与strlen的关系.

	char arr[] = { 'a','b','c','d','e' };
	printf("%d\n", strlen(arr));
    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));
	return 0;

如图,这个字符数组并不包含\0,所以他会导致许多问题,只有arr是作为整个数组的地址出现的时候,他才能得到一个值.

第一个打印的是arr的地址,也是首元素地址,它从首元素到最后都没有找到\0,于是返回结果是随机值.

第二个打印的和第一个打印的一样.

第三个打印的是*arr,解引用以后得到的是'a',a的ascii值是97,相当于把97作为地址传给了strlen,相当于传递了一个野指针,代码有问题.

第四个打印的问题与第三个一样.传递过去'b'的ascii值.

第五个打印的与第一个类似.得到随机值x.

第六个打印的是取了arr数组的地址,加一以后跳过整个数组,得到的结果是x-6.

	char arr[] = { "abcdef"};
	printf("%d\n", strlen(arr));
    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));

这张图是字符串数组,其中大部分答案与上面字符数组类似,但是他的内部是自带\0的,所有当它是以首元素为初始地址往后计算字符串长度时,是有具体结果的,比如这个字符串,他的结果就是6.

而对于数组指针又是有些不同.

	char * arr[] = { "abcdef"};
	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));
	printf("%d\n", strlen(&arr+1));
	printf("%d\n", strlen(&arr[0]+1));

第一行打印的是从arr首元素地址往后数直到\0的长度,是个固定值6.

第二行打印的是从arr首元素地址往后加一,在数直到\0的长度,是5.

第三个打印的是从解引用arr首元素,得到的是'a',ascii值为97,地址为野指针.

第四个与第三个类似,得到也是一个野指针.

第五个取的是arr数组的二级指针,与原先的'abcdef'没什么关系,所以得到随机值.

第六个同第五个的理.

第七个取的是arr[0]的地址再加一,于是是从'2'的位置开始往后数得到的结果就是5.

关于一维数组的内容我们已经介绍完毕,那么,二维数组呢?

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

这是一个二维数组,我们通过这个二维数组,能够较为清晰的总结二维数组的知识点与sizeof的知识点.

第一行求的arr整个数组的大小,答案是60.

第二行求的是(arr+1)的地址的大小,这里的arr指的是arr的首元素的地址,那么arr数组的首元素是多少呢?很多人会认为是0,但其实不是,是arr[0].但是由于所有类型的地址大小一样,都是4/8,所以最终答案是8.

第三行求的是arr[0]的大小,arr[0]就是第一行,他的大小是4*5=20.

第四行求的是解引用后(arr[0]+1)的大小,就是arr[1]

第五行求的是&arr的大小,本质是一个地址,大小就是4/8.

第六行与第五行本质一样.

第七行求(&arr[0]+1)的值,本质是一个地址,大小4/8.

第八行求的是arr[0][0]的大小,就是int的大小,答案为4.

第九行求的是&arr[0]的大小,就是地址大小,答案为4/8.

第十行求的是arr[1]的大小,答案是20

第十一行求的是*arr,也就是arr[0]的大小,答案是20.

最后两行也都是地址,答案也都是4/8

就此,sizeof与strlen的大部分区别都已经标出来了,谢谢观看.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值