C语言:sizeof和strle/n

"本文详细分析了C语言中sizeof和strlen函数在处理不同数据类型(如整型数组、字符数组、字符串数组、字符指针和二维数组)时的行为。通过实例展示了sizeof返回内存占用大小,strlen计算字符串长度(以''为结束符)。总结了两者在处理数组和字符串时的区别,强调了指针和数组地址的理解,以及strlen对''的依赖性。"
摘要由CSDN通过智能技术生成


核心知识点

  在此需要明确以下三条信息:(1)sizeof( 数组名) 表示整个数组的大小;(2)&数组名,表示整个数组的地址;(3)除前两条所提及的使用方法外,其他所有数组名均表示首元素地址


一、例题分析和展示

1.整型数组

代码如下:

	//整型数组
	int a[] = { 1, 2, 3, 4 };
	//sizeof
	printf("%d\n", sizeof(a));			//4*4=16
	printf("%d\n", sizeof(a+0));		//4,首元素地址,32位系统--指针地址大小为4
	printf("%d\n", sizeof(*a));			//4,首元素类型--int--大小4
	printf("%d\n", sizeof(a[1]));		//4,a[1]->*(a+1),第二个元素类型大小
	printf("%d\n", sizeof(&a));			//4,数组地址
	printf("%d\n", sizeof(*&a));		//16,*(&a)--所有数组元素 4*4=16
	printf("%d\n", sizeof(&a+1));		//4,下一个数组地址,不会访问,仅获取其类型大小  ** 下图帮助解释**
	printf("%d\n", sizeof(&a[0]));		//4,首元素地址 a[0]->(a+0)

下一个数组内容未知,但并不妨碍获取其类型大小

2.字符数组

代码如下:

//字符数组
	char arr1[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	//sizeof
	printf("%d\n", sizeof(arr1));			//6,6*1=6
	printf("%d\n", sizeof(arr1 + 0));		//4,首元素地址
	printf("%d\n", sizeof(*arr1));			//1,首元素类型
	printf("%d\n", sizeof(arr1[1]));		//1,首元素类型
	printf("%d\n", sizeof(&arr1));			//4,数组地址
	printf("%d\n", sizeof(&arr1 + 1));		//4,第二个元素的地址
	printf("%d\n", sizeof(&arr1[0]));		//4,首元素地址


	//strlen
	printf("%d\n", strlen(arr1));			//随机值 没有'\0' 
	printf("%d\n", strlen(arr1 + 0));		//随机值
	printf("%d\n", strlen(*arr1));			//err,*a->97  传递非法
	printf("%d\n", strlen(arr1[1]));		//err,同上
	printf("%d\n", strlen(&arr1));			//随机值
	printf("%d\n", strlen(*&arr1));			//随机值r
	printf("%d\n", strlen(&arr1 + 1));		//随机值r-6
	printf("%d\n", strlen(&arr1[0]));		//随机值r-1

此处需要注意strlen的函数声明为:
size_t strlen(const char *string);
其中可以看出函数对应的形参未常量字符,而函数返回类型未size_t,即无符号整型(unsigned int)。由此可以得出,在调用该函数时需要传递一个字符串的地址,并且该字符串需要含有’\0’,若没有则会返回一个随机数。

3.字符串数组

代码如下:

//字符串数组
	char arr2[] = "abcdef";
	//sizeof
	printf("%d\n", sizeof(arr2));			//7,算上'\0',一共七个
	printf("%d\n", sizeof(arr2 + 0));		//4,首元素地址
	printf("%d\n", sizeof(*arr2));			//1,首元素类型
	printf("%d\n", sizeof(arr2[1]));		//1,首元素类型
	printf("%d\n", sizeof(&arr2));			//4,数组地址
	printf("%d\n", sizeof(&arr2 + 1));		//4,第二个元素的地址
	printf("%d\n", sizeof(&arr2[0]+1));		//4,同上

	//strlen
	printf("%d\n", strlen(arr2));			//6,6*1 不算'\0'
	printf("%d\n", strlen(arr2 + 0));		//6
	printf("%d\n", strlen(*arr2));			//error
	printf("%d\n", strlen(arr2[1]));		//error
	printf("%d\n", strlen(&arr2));			//6
	printf("%d\n", strlen(&arr2 + 1));		//随机值
	printf("%d\n", strlen(&arr2[0]+1));		//5

相对于字符串,sizeof()与strlen()的主要区别如下图所示,这也表明strlen对’\0’的极端依赖。
sizeof'与strlen的区别

4.字符指针

代码如下:

//字符指针
	char *p = "abcdef";
	//sizeof
	printf("%d\n", sizeof(p));				//4,指针地址
	printf("%d\n", sizeof(p + 1));			//4,第二个字符地址
	printf("%d\n", sizeof(*p));				//1,首元素类型
	printf("%d\n", sizeof(p[0]));			//1,首元素类型
	printf("%d\n", sizeof(&p));				//4,地址
	printf("%d\n", sizeof(&p + 1));			//4,地址
	printf("%d\n", sizeof(&p[0] + 1));		//4,地址

	//strlen
	printf("%d\n", strlen(p));				//6·
	printf("%d\n", strlen(p + 1));			//5
	printf("%d\n", strlen(*p));				//error
	printf("%d\n", strlen(p[1]));			//error
	printf("%d\n", strlen(&p));				//随机值
	printf("%d\n", strlen(&p + 1));			//随机值
	printf("%d\n", strlen(&p[0] + 1));		//5

5.二维数组

代码如下:

	//二维整形数组
	int arr3[3][4] = { 0 };
	//sizeof
	printf("%d\n", sizeof(arr3));			//12*4=48 
	printf("%d\n", sizeof(arr3[0][0]));		//4 arr3[0][0] -> *(*(arr3+0)+0) 第一行第一列元素类型
	printf("%d\n", sizeof(arr3[0]));		//4*4=16  第一行全部元素
	printf("%d\n", sizeof(arr3[0]+1));		//4 第一行第二列地址
	printf("%d\n", sizeof(*(arr3[0]+1)));	//4 第一行第二列元素类型
	printf("%d\n", sizeof(arr3 + 1));		//4 第二行地址
	printf("%d\n", sizeof(*(arr3+ 1)));		//4*4=16 第二行元素
	printf("%d\n", sizeof(&arr3[0] + 1));	//4 第二行地址
	printf("%d\n", sizeof(*(&arr3[0]+1)));	//4*4=16
	printf("%d\n", sizeof(*arr3));			//4*4=16 第一行元素
	printf("%d\n", sizeof(arr3[3]));		//4*4=16 第四行元素,未访问,只看类型

二维数组在使用数组名进行调用时,需要注意(&arr3+1)指的是第二行四个元素的地址需要注意,下图有助于理解二维数组名的使用。
二维数组名的使用


总结

  这其中的例题是在听网课是跟着学习的,我认为帮助挺大的,画了几张图有助于将抽象知识给表征出来。指针真是一个非常强大的工具,简直将冯·诺依曼结构的特点完美的展现出来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值