菜鸡的C学习日志---sizeof和strlen下的指针和数组(1)

叠甲:纯新人学习,讲的都是很简单的内容,就是想让我这种傻瓜也看得懂的,不喜勿喷。有错误或者不好的地方可以帮忙指出,非常感谢!

一.sizeof()

sizeof()是一个运算符。它用于计算括号内操作数在内存上所占的空间大小,以字节为单位(一个字节就输出1)。操作数可以是一种数据类型,也可以是变量,还可以是一个表达式。

看看这个图,

 由图可知。int类型在内存上所占空间的大小为4个字节;char类型的变量a在内存上所占的空间大小为1个字节;float的变量b*double的变量c表达式返回的类型在内存上所占的空间大小为8个字节。

二.strlen()

strlen()是一个库函数,头文件是<string.h>。库里面的定义是 size_t strlen(const char *str),也就是说其传参是一个 const char*类型的,是一个地址。

肤浅的理解strlen被用来求字符串长度,在括号内给一个字符串变量,他就会数有多少个字符。

  注意:字符串是有结束符“\0”的。strlen就是检测是否有“\0”,检测到了,就停了,如何合计\0前面的字符数量。b数组这边我给它加了个\0,所以两次的长度不一样,这里就是\0搞的鬼。

三.开干!

这里的题是我观看b站“BV1cq4y1U7sg”视频里面的题,共有五大板块

第一板块

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

第一板块 printf打印的结果是什么?整体的答案在这道题结束时公布。现在我们来一条一条看(先代码后解释,别看错位置了)

printf("%d\n", sizeof(a));//16

sizeof求操作数在内存上所占空间大小,这个数组a单独用代表整个数组,整个数组有4个int,所以输出 16

printf("%d\n", sizeof(a + 0));// 4 or 8

数组a没有单独使用,所以是首元素地址,a+0代表首元素地址+0,结果还是个地址。这里sizeof就是求这个首元素地址+0的地址空间大小,地址空间大小32位系统是4 64位系统是8
 

printf("%d\n", sizeof(*a));//4

数组a没有单独使用,这里的a代表首元素地址。*a就是解引用首元素地址,解出来是首元素,首元素是int类型,输出4

printf("%d\n", sizeof(a + 1));//4 or 8

数组a没有单独使用,这里的a代表首元素地址。a+1就是首元素地址+1,结果是个地址。这里sizeof就是求这个首元素地址+1的地址空间大小,地址空间大小32位系统是4 64位系统是8
 

printf("%d\n", sizeof(a[1]));//4

a[1]代表数组中的第二位元素,该数组第二位元素是int类型,输出4

printf("%d\n", sizeof(&a));//4 or 8

这是&a代表取整个数组的地址,数组的地址还是个地址。地址空间大小32位系统是4 64位系统是8
 

printf("%d\n", sizeof(*&a));//16

这是&a代表取整个数组的地址,* &a就是对整个数组的地址进行解引用。取出地址再解引用它,*&a等价a。参考第一条
 

printf("%d\n", sizeof(&a[0]));//4 or 8
printf("%d\n", sizeof(&a[0] + 1));//4 or 8
printf("%d\n", sizeof(&a + 1));//4 or 8

这三条一起看会更好

&a[0] 和 &a[0]+1分别代表数组第一位和第二位元素的地址,地址嘛上面说了,32-4 64-8。然后这个&a+1的ehh?(皱了下眉头),这&a+1,是取首元素地址+1,还是取整个数组地址+1啊?

我们来验证一下

 分别取出三位大哥的地址(这里是16进制的)

算出对应的差值

 

 16进制的10代表 10进制的16。C代表12

所以我们可以知道&a+1和&a[0]相差16,和&a[0]+1相差12。结合该题,即前者相差4位int大小,后者相差3位。由此可以得出&a+1,是取整个数组的地址进行+1,也就是跳到下一个不知道什么东西去了,但是还是地址,是地址就   32-4 64-8

(内存上大概是这样的) 

答案(64位平台 就是地址是 8的)

第一板块总结:数组a单独使用,代表整个数组,&a的a也是代表整个数组,&a就是取整个数组地址。其余都是首元素地址

-------------------------------------------------------------------

第二板块

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

第二板块 printf打印的结果是什么?整体的答案在这道题结束时公布。现在我们来一条一条看(先代码后解释,别看错位置了)

sizeof部分

printf("%d\n", sizeof(arr));//6

前面说了,arr单独使用代表整个数组,该数组共有6位且是char类型,输出6
 

printf("%d\n", sizeof(arr + 0));//4 or 8

前面还是说了,arr+0就不单独了,这里arr代表首元素,首元素地址+0,还是个地址嘛,32-4 64-8(你懂的)

printf("%d\n", sizeof(*arr));//1

解引用arr,解引用首元素地址,解出来是首元素吗?是的,首元素是a且是char类型,输出1
 

printf("%d\n", sizeof(arr[1]));//1

arr[1]代表数组第二位元素--b,是char类型,输出1

printf("%d\n", sizeof(&arr));//6

第一板块总结里说了,&arr就是代表整取个数组的地址,该数组共有6位且是char类型,输出6
 

printf("%d\n", sizeof(&arr + 1));//4 or 8

第一板块总结里说了,&arr就是代表取整个数组地址,整个数组+1,跳过一个数组的地址,指向一个不知道什么东西的,但是地址都是32-4 64-8
 

printf("%d\n", sizeof(&arr[0] + 1));//4 or 8

&arr[0]是首元素地址,+1就是第二位元素地址,地址就是 32-4 64-8

strlen部分

printf("%d\n", strlen(arr));//随机值

arr代表整个数组,strlen求长度遇到\0就停,这个数组里面没有\0,会输出一个随机数

printf("%d\n", strlen(arr + 0));//随机值

arr代表首元素地址,首元素地址+0,还是从首元素开始算,strlen求长度遇到\0就停,这个数组里面没有\0,会输出一个随机数

printf("%d\n", strlen(*arr));//error

解引用首元素,传进去一个字符‘a’,这什么东西?a在ASCII码表上的地址是97,也就是这里传入了地址97。97?这不是一个合法的地址,这里就错误了err。

printf("%d\n", strlen(arr[1]));//error

arr[1]是‘b',b在ASCII码表上的地址是98,传入这种地址会错误的
 

printf("%d\n", strlen(&arr));//随机值

&arr就是取arr整个数组地址,arr数组的地址就是首元素地址。这里&arr取出来的类型是char(*)[6],但是到strlen里面它就是会转化成char*,就是说strlen依然认为你传入了首元素‘a’的地址,所以会从‘a’开始算,是个随机值(同1 2)

printf("%d\n", strlen(&arr + 1));//随机值

&arr就是取arr整个数组地址,+1,便跳过arr数组,指向下一个我们不知道的东西,并且从那里开始数,到\0结束,随机值哦。
 

printf("%d\n", strlen(&arr[0] + 1));//随机值

&arr[0]的就是取首元素的地址,+1,指向‘b’,从b开始数,会是一个随机值。

答案(64位平台 就是地址是 8的)

 第二板块总结:好吧我这边其实觉得没什么总结,但是有一个思考。

思考:strlen这边的随机值之间有规律吗?有的

观察上面的答案,可以看出来1 arr arr+0 &arr的随机值都是42,2&arr+1的是36,3&arr[0]+1的是41。12相差6,23相差5,31相差1。

内存上可以这么表示,这里的42仅是我的电脑的编译器的随机值。每个电脑和编译器都不一样。

 part1到此结束

以上!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值