手把手教你区分strlen与sizeof

前言

相信很多老铁第一次接触C语言的时候,脑子里会莫名的把strlen和sizeof相混淆,这里就是来给大家区分一下 strlen 和 sizeof。

本篇文章所有代码链接:test_6_20 · hunter/C_NS - 码云 - 开源中国 (gitee.com)


strlen:

  • 一个库函数(是C语言本身自带的函数)。
  • 使用函数的时候需要引用头文件#include <stdio.h>。
  • 作用是求字符串长度的函数,遇到\0就停止。

sizeof:

  • 单目操作符、关键字
  • 计算变量/类型/数组所占空间的大小。
  • 单位是字节(byte)。
  • sizeof是编译的时候确定大小的。

下面我们通过一些习题来带领着老铁深入了解。

首先我们这里要知道数组名是什么?

数组名的意义:

  • sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  • 除此之外所有的数组名都表示首元素的地址。

PS:

  • sizeof内部的数字是不进行真实的运算的,只是根据其类型计算其大小。
  • 二维数组在运用时可以想象成一维数组 一行就是一个元素。
  • 对于地址的大小,在32位机器上是4大小,在64位的机器是8字节大小。
  • 字符串是在结尾处有'\0'结尾的,strlen是以'\0'为结束标志的,当遇到'\0'才会停止,没有遇到将会往后无限查找,直到在后面的未知空间找到'\0'然后停止。
  • sizeof是不以'\0'为结束标志的(在编译的的时候会确定大小)反而会把其当成一个数组的元素加到其总和里面。

温馨提示:下面代码每一行都有解释,请各位自行观看。

sizeof

int main()
{
	
	int a[] = { 1,2,3,4 };//4*4 = 16
	printf("%d\n", sizeof(a));//16 sizeof(数组名)-计算的是数组总大小-单位是字节-16
	printf("%d\n", sizeof(a + 0));//4/8  数组名这里表示收元素的值,a+8还是首元素地址,地址的大小就是4/8个字节
    printf("%d\n", sizeof(*a));//4  数组名表示首元素地址,*a就是首元素,sizeof(*a)就是4
	printf("%d\n", sizeof(a + 1));//4/8 数组名这里表示收元素的值,a+1第2个元素的地址,地址的大小就是4/8个字节
    printf("%d\n", sizeof(a[1])); //4 第2个元素的大小
	printf("%d\n", sizeof(&a));//4/8 &a取出的是数组的地址,但是数组的地址那也是地址,地址的大小就是4/8个字节
	printf("%d\n", sizeof(*&a));//16  &a数组的地址,数组的地址解引用访问的数组,sizeof计算的就是数组的大小单位是字节
    printf("%d\n", sizeof(&a + 1));//4/8 &a是数组的地址,&a+1虽然地址跳过整个数组,但还是地址,所以是4/8个字节
	printf("%d\n", sizeof(&a[0]));//4/8 &a[0]是第一个元素的地址
	printf("%d\n", sizeof(&a[0] + 1));//4/8 &a[0]+1 是第二个元素的地址
	return 0;
}


int main()
{
	char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
	printf("%d\n", sizeof(arr) );//6 sizeof计算机的是数组大小,6*1 = 6字节
	printf("%d\n", sizeof(arr + 0));//4/8 arr是首元素的地址,arr+8还是首元素的地址地址的大小是4/8字节
	printf("%d\n", sizeof(*arr));//arr是首元素的地址,*arr就是首元素,首元素是字符大小是一个字节
	printf("%d\n", sizeof(arr[1])); //1
	printf("%d\n", sizeof(&arr)); //&arr虽然是数组的地址,但还是地址,地址大小是4 / 8个字节
	printf("%d\n", sizeof(&arr + 1));//&arr+1是跳讨整个数组后的地址.地址大小是4/8个字节
	return 0;
}


int main()
{

	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7 sizeof(arr)计算的数组的大小,单位是字节:7
	printf("%d\n", sizeof(arr + 0));//4/8 计算的是地址的大小-arr + 0是首元素的地址
	printf("%d\n", sizeof(*arr));//1 *arr是首元素,sizeof(*arr)计算首元素的大小
	printf("%d\n", sizeof(arr[1]));//1 arr[1]是第二个元素,sizeof(arr[1])计算的是第二个元素的大小
	printf("%d\n", sizeof(&arr));//4/8 &arr虽然是数组的地址,但也是地址,所以是4/8个字节
	printf("%d\n", sizeof(&arr + 1));//4/8 &arr+1是跳过整个数组后的地址,但也是地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 &arr[0]+1第二个元素的地址
	return 0;
}


int main()
{
	//二维数组
	int a[3][4] = { 0 };
	printf("%d\n",sizeof(a)) ;//48
	printf("%d\n", sizeof(a[0][0]));//4
	printf("%d\n", sizeof(a[0]));//16 a[0]相当于第一行做为一维数组的数组名,
	//sizeof(arr[e])把数组名单独放在sizeof()内,计算的是第一行的大小
			
	printf("%d\n", sizeof(a[0] + 1));//4/8 - a[0]是第一行的数组名,数组名此时是首元素的地址,a[0]其实就是第一行第一个元素的地址
	//所以a[0]+1就是第一行第二个元素的地址-地址大小是4/8个字节

	printf("%d\n", sizeof(*(a[0] + 1)));//4 -*(a[0] + 1))是第一行第二个元素,大小是4个字节
	printf("%d\n", sizeof(a + 1));//4/8 a是二维数组的数组名,没有sizeof(a),也没有&(a),所以a是首元素地址
	//而把二维数组看成一维数组时,二维数组的首元素是他的第一行,a就是第一行(首元素)的地址
	//a + 1就是第二行的地址
		
	printf("%d\n", sizeof(*(a + 1)));//16 sizeof(a[1])计算第二行的大小,单位是字节
	printf("%d\n", sizeof(&a[0] + 1));//4/8 第二行的地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//16 计算第二行的大小,单位是字节
	printf("%d\n", sizeof(*a));//16  a是首元素地址-第一行的地址,*a就是第一行,sizeof(*a)就是计算第一行的大小
	printf("%d\n", sizeof(a[3]));//16 
	//sizeof内部的数字是不进行真实的运算的,只是根据其类型计算其大小
}


strlen 

int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", strlen(arr));//随机值
	printf("%d \n", strlen(arr + 0));//随机值
 
	//printf( "%d\n", strlen(*arr)); //error
	//printf("%d\n", strlen(arr[1]));//error 
	//error原因:arr是数组名一 > 是首元素地址—* arr一 > 首元素一 > 'a'—ASCIl— > 97,随机值strlen会把其当成地址进行查找一>非法访问
	
 printf("%d\n", strlen(&arr));//随机值
	printf("%d\n", strlen(&arr + 1));//随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1
}


int main()
{
	char arr[] = "abcdef";
	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
 
	//printf("%d\n", strlen(*arr)); //error
	//printf("%d\n",strlen(arr[1]));//error
 //*arr是首元素地址,strlen("const, char*. str")char*接收的是地址,传进去就是'a'这个字符,'a'的ASCII对应的数字是97,就会造成非法访问。
 
	printf("%d\n", strlen(&arr));//6 &arr - 数组的地址-数组指针 char(*p)[7] = &arr
	printf("%d\n",strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5
	return 0;
}


PS:

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。形如:a

小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。形如:b

 

int main()
{
	char* p = "abcdef";
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p +1));//5
	
	//printf("%d\n", strlen(*p));//error 
	//printf("%d\n", strlen(p[0]));//error
	//*p是指针,存放的是a的地址,p是从初所开辟的空间来看的,而不是存放字符串的" abcdef”的所开辟的空间来看,
	//而却的地址延存放' a'的地址,地址是16进制数字例如0x0O12=>大部分小端存放=>1200 strlen就是数到0
	
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] +1));//5
	return 0;
}


结语:

希望本篇文章对各位了解C语言的strlen和sizeof有所帮助,对于别的知识点C语言的知识点的讲解,各位老铁可以看我别的文章,相信能对各位老铁了解C语言有帮助。各位老铁有什么问题欢迎在下方留言。感谢各位老铁的观看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值