char *p = "abcdef";
printf("%d\n", sizeof(p));
p是指针变量(地址),地址就是地址,大小就是4/8字节
printf("%d\n", sizeof(p+1));
p+1是b的地址,还是地址 4/8字节
printf("%d\n", sizeof(*p));
*p是‘a’,sizeof(*p)计算的是字符的大小,是1字节
printf("%d\n", sizeof(p[0]));
p[0]==*(p+0)=*p,跟上面一样
printf("%d\n", sizeof(&p));
&p是二级指针,是指针大小是4/8字节
printf("%d\n", sizeof(&p+1));
&p+1是跳过p变量后的地址,4/8字节
printf("%d\n", sizeof(&p[0]+1));
p[0]是‘a’,&p[0]是a的地址,+1后,就是b的地址,是地址就是4/8
printf("%d\n", strlen(p));
6,求字符串的长度
printf("%d\n", strlen(p+1));
p+1就是b的地址,求字符串长度,5
printf("%d\n", strlen(*p));
p本来就是地址,解引用后变成首元素,即‘a’,非法,错误
printf("%d\n", strlen(p[0]));
同上面
printf("%d\n", strlen(&p));
&p拿到的是p这个指针变量的起始地址,也就是说它拿到的并不是“abcdef\0”这个地址,
而是重新创建了一个,从这里开始求字符串长度也是随机值
printf("%d\n", strlen(&p+1));
&p+1跳过p变量的地址,从这里开始求字符串长度也是随机值,原理跟上面差不多
printf("%d\n", strlen(&p[0]+1));
&p[0]+1拿到的是b的地址,从b开始计算,5
首先,在此之前,我们先了解下面的知识:
1.sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,
这里说数组名是单独的,什么意思呢,看下面:
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",sizeof(arr)); //这样子是数组名是表示单独的
printf("%d",sizeof(arr+1); //这样子是不单独的
2.&数组名,数组名表示整个数组,取出的是整个数组的地址
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",sizeof(&arr));
3.除此之外,所以的数组名都是数组首元素的地址
注意:是地址就是4/8字节,下面慢慢就理解这句话了。
了解了上面的认识后,下面开始我们的正文:
int a[] = {1,2,3,4}; //大小:4*4=16--四个元素*一个int类型为4字节
printf("%d\n",sizeof(a)); //这是不是符合我们上面所说的数组单独放在sizeof里面,so:4*4=16
printf("%d\n",sizeof(a+0)); //a+0 其实是数组第一个元素的地址,是地址就是4/8字节
printf("%d\n",sizeof(*a)); //这里是不是属于第三种情况,所以*a是数组首元素,计算的是数组首元素的大小,单位字节,4
printf("%d\n",sizeof(a+1)); //这里是不是也是第三种,a+1,是第二个元素的地址,是地址大小就是4/8
printf("%d\n",sizeof(a[1])); //这是数组中第二个元素“2”吧,计算的是数组首元素的大小,单位字节,4
printf("%d\n",sizeof(&a));&a是整个元素的地址,但是整个元素的地址也是地址,地址的大小就是4/8字节
//这里可以仔细想一想开始时我说注意的那句话。
printf("%d\n",sizeof(*&a)); //&a是数组的地址,*&a就是拿到了数组,*&a--》a,a就是地址名,
sizeof(*&a)-->sizeof(a),计算的是整个数组的大小,单位是字节16
printf("%d\n",sizeof(&a+1)); //&a是数组的地址,&a+,跳过整个数组,指向数组后面的空间,是一个地址,大小是4/8字节
//开始时我说注意的那句话
printf("%d\n",sizeof(&a[0])); //首元素的地址,计算的是首元素地址的大小,4/8字节
printf("%d\n",sizeof(&a[0]+1)) //&a[0]+1是第二个元素得到地址,地址的大小就是4/8字节
1.sizeof是根据类型来推断它的大小的,即只关注占用内存空间的大小,单位是字节,不关心内存中存放的是什么
2.strlen是根据\0标志点,是求字符串的长度,统计的是\0之前出现的字符个数,一定要找到\0才算结束,所以可能存在越界访问
3.sizeof是操作符,strlen是库函数
//char arr[] = "abcdef";
这个有\0,本质上:abcdef\0,注意这个\0也要算上去sizeof
//printf("%d\n", sizeof(arr));
结果7,数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节
//printf("%d\n", sizeof(arr+0));
arr+0是数组首元素的地址,大小是4/8
//printf("%d\n", sizeof(*arr));
*arr是首个元素,大小为1字节
//printf("%d\n", sizeof(arr[1]));
arr[1]是第二个元素,大小为1字节
//printf("%d\n", sizeof(&arr));
&arr是数组的地址,数组的地址也是地址,是4/8字节
//printf("%d\n", sizeof(&arr+1));
跳过一个数组的地址,同上
//printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1是第二个元素的地址,是4/4字节
//printf("%d\n", strlen(arr));
6,arr是数组首位元素的地址,strlen从首元素的地址开始统计\0之前出现的字符串个数
//printf("%d\n", strlen(arr+0));
6同上面
//printf("%d\n", strlen(*arr));
*arr是'a'是97,传给strlen是一个非法地址,造成非法访问
//printf("%d\n", strlen(arr[1]));
非法,同上面
//printf("%d\n", strlen(&arr));
结果6
//printf("%d\n", strlen(&arr+1));
随机值,跳过整个数组,也跳过了\0的地方,于是在后面找不到\0了,结果就成了随机值
//printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1,是b的地址,从第二个元素开始统计,结果是5
char arr[] = {'a','b','c','d','e','f'}; //6个元素
//首先我们得分清的是,这种是没有\0的
//printf("%d\n", sizeof(arr));
这是数组单独情况,访问是整个数组,对吧。因为char,每个字节为1 所以结果为:1*6=6
//printf("%d\n", sizeof(arr+0));
这是arr+0是数组首元素的地址,地址就是地址,so:4/8字节
//printf("%d\n", sizeof(*arr));
这是第三种情况,arr是首元素的地址,解引用*arr就是数组的首元素, 结果为1
//printf("%d\n", sizeof(arr[1]));
arr[1]是第二个元素,大小是1字节
//printf("%d\n", sizeof(&arr));
&arr的是数组的地址,数组的地址也是地址,是地址大小就是4/8字节
//printf("%d\n", sizeof(&arr+1));
&arr+1是跳过整个,指向数组后边空间的地址,4/8
//printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1是数组第二个元素的地址,是地址4/8字节
//printf("%d\n", strlen(arr));
随机值 因为strlen得找/0,又这个没有/0,不知道在哪停止
//printf("%d\n", strlen(arr+0));
随机值,+0还是从a的地址,但是他求的不是sizeof,同上
//printf("%d\n", strlen(*arr));
第三种情况,首位元素,解引用后,变成首位元素,是strlen(a)->strlen('98'),非法访问-err
//printf("%d\n", strlen(arr[1]));
跟上面类似
//printf("%d\n", strlen(&arr));
&arr虽然是数组的地址,但是也是从数组起始位置开始的,计算的还是随机值
//printf("%d\n", strlen(&arr+1));
&arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度 也是随机值
//printf("%d\n", strlen(&arr[0]+1));
&arr[0]+1是数组第二个元素的地址,是地址4/8字节,从 b开始数
//int a[3][4] = {0};
//printf("%d\n",sizeof(a));
结果 大小:48 =3*4*4
//printf("%d\n",sizeof(a[0][0]));
第一行第一个元素结果为4
//printf("%d\n",sizeof(a[0]));
第一行,有4个元素:结果4*4=16
//printf("%d\n",sizeof(a[0]+1));
a[0]作为第一行的数组名,数组名没有单独放在sizeof内部,不属于第一种情况,
也没有取地址,也不属于第二种,
表示的是数组首元素的地址,那就是a[0][0]的地址,
a[0]+1就是第一行第二个元素的地址,是地址就是4/8字节
//printf("%d\n",sizeof(*(a[0]+1)));
第一行第二个元素,计算的是元素的大小-4字节
//printf("%d\n",sizeof(a+1));
a是二维数组的数组名,数组名表示首元素的地址,,a+1就是第二行的地址,就是地址4/8字节
//printf("%d\n",sizeof(*(a+1)));
结果16
//printf("%d\n",sizeof(&a[0]+1));
&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8
//printf("%d\n",sizeof(*(&a[0]+1)));
结果16
//printf("%d\n",sizeof(*a));
a表示首元素的地址,就是第一行的地址,,*a就是第一行,计算的是第一行的大小,结果16
//printf("%d\n",sizeof(a[3]));
如果a存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小
不会造成非法访问的
最后的最后,
又来到我们每次激励鸡汤:
分享高中到至今很喜欢的一句:
我与我,周旋久,宁做我。
希望我们都能够坚持下去自己为了规划的路线,不被周围人的情绪影响了自己的行动。宁做我,活出属于我们每一个人的篇章。
标签:arr,地址,数组,printf,sizeof,解析,strlen From: https://blog.csdn.net/go_bai/article/details/143749837