sizeof针对不同输入的区别
转载于:https://blog.****.net/prokgtfy9n18/article/details/68962512
在数组运算前,先了解一下数组的解引用到底是怎么回事。
-
#include <windows.h>
-
#include <stdio.h>
-
int main()
-
{
-
int arr[] = {1,2,3,4,5,6,7,8,9,0};
-
printf("%d\n", *arr);
-
system("pause");
-
return 0;
-
}
由此可见,数组的数组名其实是数组首元素的地址。
那么,如果要访问一个数组中其他元素呢?
-
#include <stdio.h>
-
int main()
-
{
-
int arr[10] = {0};
-
int i = 0;
-
for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
-
{
-
printf("&arr[%d] = %p\n", i, &arr[i]);
-
printf("%p\n", arr+i);
-
}
-
return 0;
-
}
这里输出的是&arr[i]的地址,那么从arr[0]到arr[9]的地址能不能通过arr+i的方式打印出来呢?我们来看
观察结果我们发现,通过对数组名+整数的运算,其实可以获取到数组每个人元素的地址。这样我们就可以用指针访问我们的数组了。
看完一维数组的表示方式,下列关于数组的一些运算我们必须掌握。
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); //16 数组的大小(4个元素,一个占4个字节)
printf("%d\n",sizeof(a+0)); //4 第一个元素的大小
printf("%d\n",sizeof(*a)); //4 数组的解引用,数组首元素的大小(int型)
printf("%d\n",sizeof(a+1)); //4 第二个元素的大小
printf("%d\n",sizeof(a[1]));
//4 第二个元素的大小
printf("%d\n",sizeof(&a));
//4 数组的地址大小都是4
printf("%d\n",sizeof(&a+1)); //4 这个数组的下一个数组的地址
printf("%d\n",sizeof(&a[0]));
//4 首元素的地址
printf("%d\n",sizeof(&a[0]+1));
//4 第二个元素的地址
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr)); //6 数组的大小(6个元素,一个占1个字节)
printf("%d\n", sizeof(arr+0));//4 首元素的地址
printf("%d\n", sizeof(*arr)); //1
数组的解引用,首元素的大(char型)
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));
//随机
printf("%d\n", strlen(arr+0));//随机
/*
printf("%d\n", strlen(*arr));//error
*/
/*printf("%d\n", strlen(arr[1]));*/
//error
printf("%d\n", strlen(&arr));//随机
printf("%d\n", strlen(&arr+1));//随机
printf("%d\n", strlen(&arr[0]+1));//随机
为什么在运算strlen 时会出现这么多随机数呢?不妨先来看看strlen的用法
它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止
而对于strlen(*arr),在对arr解引用求长度时,会自动将首元素的地址先用ASCII码值表示出了,然后向后查找,系统会一直查找下去(a的ASCII为97)
strlen(&arr)是对arr的地址求长度,而arr的地址里没'\n',所以他会一直找到'\n'才能停下了,会产生一个随机值
char *p = "abcdef";
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 指针的地址为4
printf("%d\n", sizeof(&p+1));//4
下个指针的地址
printf("%d\n", sizeof(&p[0]+1));//4 第二个元素的地址
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
printf("%d\n", strlen(&p));//x
从首元素地址开始找'\n',随机值
printf("%d\n", strlen(&p+1));//x
同上
printf("%d\n", strlen(&p[0]+1));//5第二个元素开始的长度
这里产生的错误和上面的strlen 一样会从首元素对应的ASCII值出查找,所以一样会出错。
//二维数组
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
第一行元素的大小(int型)
printf("%d\n",sizeof(a[0]+1));//4
第一行的第二个元素的大小
printf("%d\n",sizeof(a+1));//4
第二个元素的地址
printf("%d\n",sizeof(&a[0]+1));//4
第一行第二个元素的地址
printf("%d\n",sizeof(*a));//16
数组首元素(相当于第一行的大小)
printf("%d\n",sizeof(a[3]));//16
下个数组的首个元素(第一行)大小
接下来总结一下sizeof和strlen的区别:
sizeof:
1、sizeof的单位是字节
2、sizeof(数组名)表示整个数组的大小(和类型有关)
3、sizeof(&数组名)表示整个数组的地址(和类型无关)
4、sizeof(*数组名)表示数组首元素的大小
strlen:
1、strlen(数组名)表示数组的长度(如果是非字符串则会产生一个随机值)
2、strlen(*数组名)表示从首元素对应的ASCII开始找'\n',会出错
3、strlen(&数组名)表示从首元素的地址开始找'\n',直到找到'\n',会产生一个随机值
结果和你想的一样吗?