基于sizeof和strlen的指针和数组笔试题解析

一、概念

        sizeof:

sizeof操作符的结果类型为size_t,(它在头文件用typedfe定义为unsigned int类型),计算的是分配空间的实际字节数。sizeof是运算符,可以以类型、函数、做参数 。

        strlen:

strlen结果类型也为size_t(size_t strlen( const char *string )),但strlen是计算的空间中字符的个数(不包括‘\0’)。strlen是函数,只能以char*(字符串)做参数。而且,要想得到的结果正确必须包含 ‘\0’(通过strlen的实现得知)。

二、例题及解析

        首先我们需要知道数组名的意义:

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

        2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。

        3.除此之外所有的数组名都表示首元素的地址。

2.1  一维数组

int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));		   //16  a是整个数组的大小,sizeof计算出结果为16字节
	printf("%d\n", sizeof(a+0));       //4   a是首元素的地址
	printf("%d\n", sizeof(*a));		   //4	  首元素地址的解引用
	printf("%d\n", sizeof(a+1));	   //4   2的地址
	printf("%d\n", sizeof(a[1]));      //4
	printf("%d\n", sizeof(&a));		   //4   &a数组的地址,4个字节
	printf("%d\n", sizeof(*&a));       //16  *和&抵消
	printf("%d\n", sizeof(&a+1));      //4   4个字节的地址,跳过了4
	printf("%d\n", sizeof(&a[0]));	   //4
	printf("%d\n", sizeof(&a[0]+1));   //4
	//总结: 只要是地址,不论什么类型,大小都为4个字节

2.2 字符数组

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));		//6
	printf("%d\n", sizeof(arr+0));		//4  首元素地址为4个字节
	printf("%d\n", sizeof(*arr));		//1
	printf("%d\n", sizeof(arr[1]));		//1
	printf("%d\n", sizeof(&arr));		//4
	printf("%d\n", sizeof(&arr+1));		//4
	printf("%d\n", sizeof(&arr[0]+1));	//4

	printf("%d\n", strlen(arr));		//随机值 strlen要找到\0才能返回数据的长度
	printf("%d\n", strlen(arr+0));		//随机值
	printf("%d\n", strlen(*arr));		//err strlen(a)会把a的ASCII码值97当作地址往后找
	printf("%d\n", strlen(arr[1]));		//err
	printf("%d\n", strlen(&arr));		//随机值
	printf("%d\n", strlen(&arr+1));		//随机值
	printf("%d\n", strlen(&arr[0]+1));	//随机值
char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));			//7  arr是数组的地址
	printf("%d\n", sizeof(arr + 0));		//4  arr是首元素的地址
	printf("%d\n", sizeof(*arr));			//1
	printf("%d\n", sizeof(arr[1]));			//1
	printf("%d\n", sizeof(&arr));			//4  数组的地址 4个字节
	printf("%d\n", sizeof(&arr + 1));		//4
	printf("%d\n", sizeof(&arr[0] + 1));	//4

	printf("%d\n", strlen(arr));			//6
	printf("%d\n", strlen(arr + 0));		//6
	printf("%d\n", strlen(*arr));			//err 
	printf("%d\n", strlen(arr[1]));			//err
	printf("%d\n", strlen(&arr));			//6
	printf("%d\n", strlen(&arr + 1));		//随机值
	printf("%d\n", strlen(&arr[0] + 1));	//5
char *p = "abcdef";
	printf("%d\n", sizeof(p));			//4  p是指针变量,求指针变量的大小,为4个字节
	printf("%d\n", sizeof(p + 1));		//4  p+1为b的地址
	printf("%d\n", sizeof(*p));			//1
	printf("%d\n", sizeof(p[0]));		//1
	printf("%d\n", sizeof(&p));;		//4  指针p的地址
	printf("%d\n", sizeof(&p + 1));		//4
	printf("%d\n", sizeof(&p[0] + 1));	//4  b的地址

	printf("%d\n", strlen(p));			//6
	printf("%d\n", strlen(p + 1));		//5
	printf("%d\n", strlen(*p));			//err strlen需要传入地址
	printf("%d\n", strlen(p[0]));		//err
	printf("%d\n", strlen(&p));			//随机值
	printf("%d\n", strlen(&p + 1));		//随机值
	printf("%d\n", strlen(&p[0] + 1));	//5  从b开始数

2.3 二维数组

	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));			 
	//48  二维数组中sizeof(a),a同样表示整个数组
	printf("%d\n", sizeof(a[0][0]));	 
	//4 
	printf("%d\n", sizeof(a[0]));		 
	//16 a[0]可看作第一行的数组名,sizeof(数组名)计算第一行数组大小
	printf("%d\n", sizeof(a[0] + 1)); 	 
	//4  a[0]表示第一行首元素地址,即a[0][0]地址,再+1为a[0][1]地址
	printf("%d\n", sizeof(*(a[0] + 1))); 
	//4  
	printf("%d\n", sizeof(a + 1));		 
	//4  a为第一行一维数组的地址,+1为第二行的地址
	printf("%d\n", sizeof(*(a + 1)));	 
	//16 第二行地址的解引用,是数组指针的解引用,访问的是一个数组的大小
	printf("%d\n", sizeof(&a[0] + 1));	 
	//4  第一行地址+1,得第二行地址
	printf("%d\n", sizeof(*(&a[0] + 1)));
	//16 第二行的大小
	printf("%d\n", sizeof(*a));			 
	//16 第一行地址解引用是第一行的大小
	printf("%d\n", sizeof(a[3]));		 
	//16 计算第四行的大小(即使没有第四行)

三、总结

        这些都是来自往年的笔试题,非常重要!!!学废了吗?!

        建议收藏反复阅读思考,加深对指针、数组和内存的理解!!!

        

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿龙还在写代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值