目录
1. 数组名、sizeof(数组名)、&数组名
arr[ ]
数组名是首元素的地址;例如:arr当参数传递时,arr表示首元素的地址,sizeof(arr)=4,即指针的大小
但是在以下这两种情况表示的不是首元素地址。
(1)sizeof(arr):在sizeof()中,单独数组名出现,表示数组的整个大小,不是首元素地址大小。
(2)&arr :对于取地址数组名,表示的是整个数组的地址。
sizeof():求的是在括号()里面表达式或者类型的大小,以字节为单位;
strlen():是一个字符串函数,括号里接收是地址,求得该地址往后,碰到\0结束为止的字符个数。
2. 一维数组的sizeof()
前提:32位操作系统下
2.1 整型数组的sizeof()
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
数组名a表示整个数组的大小,元素类型 int ,有4个元素,所以大小为 4×4 = 16
printf("%d\n",sizeof(a+0));
数组名a表示首元素地址,a+0 表示 首元素地址跳过了0个元素的地址;即首元素的地址,地址的大小为:4
printf("%d\n",sizeof(*a));
数组名a表示首元素地址,*a对首元素地址解引用表示a[0]的元素,1为int型,大小为:4
printf("%d\n",sizeof(*(a+1)));
数组名a表示首元素地址,a+1就是a[1]的地址,*(a+1)对a[1]地址解引用表示a[1]的元素2,为int型,大小为:4
printf("%d\n",sizeof(a+1));
数组名a表示首元素地址,a+1表示跳过一个元素的地址,即a[1]的地址,地址的大小为4个字节。结果为:4
printf("%d\n",sizeof(a[1]));
a[1]表示下标为 1的元素,该元素类型为int,结果为:4
printf("%d\n",sizeof(&a));
&a表示整个数组的地址,并不是数组首元素地址的地址;整个数组的地址还是地址;
结果为:4
printf("%d\n",sizeof(*&a));
&a表示整个数组的地址,对整个数组地址解引用 *&a,访问的是整个数组;结果为:16
printf("%d\n",sizeof(&a+1));
&a表示整个数组的地址,&a + 1;表示跳过 1个 数组大小的地址,由于还是地址,结果:4
printf("%d\n",sizeof(&a[0]));
&a[0],表示的是下标为0元素的地址,结果: 4
printf("%d\n",sizeof(&a[0]+1));
&a[0] + 1 表示下标为0的地址,跳过一个元素的地址,即为下标为 1 的地址,和 &a[1]等价;结果为:4
2.2 字符数组的sizeof()
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr)); 6,整个数组的大小
printf("%d\n", sizeof(arr+0)); 4,arr[0]的地址
printf("%d\n", sizeof(*arr)); 1,arr[0]的元素
printf("%d\n", sizeof(arr[1])); 1,arr[1]的元素
printf("%d\n", sizeof(&arr)); 4,整个数组地址,本质还是地址
printf("%d\n", sizeof(&arr+1)); 4,整个数组+1的地址
printf("%d\n", sizeof(&arr[0]+1)); 4,arr[1]的地址
2.3 字符串赋值给字符数组的sizeof()
char arr[] = "abcdef";
相当于 char arr[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};
printf("%d\n", sizeof(arr));
字符串其实是隐藏了\0,即,在这里数组的大小不是 6 ,而是 7,多了一个\0; 结果:7
printf("%d\n", sizeof(arr+0));
arr+0表示&a[0],地址的大小都是4个字节; 结果:4
printf("%d\n", sizeof(*arr));
*arr表示a[0],为字符'a',大小为: 1
printf("%d\n", sizeof(arr[1]));
arr[1]表示‘b’; 最终结果:1
printf("%d\n", sizeof(&arr));
&arr表示整个数组的地址,地址的大小还是:4
printf("%d\n", sizeof(&arr+1));
&arr + 1表示跳过一个数组的地址,该地址最终还是地址,虽然是不合法的地址; 结果:4
printf("%d\n", sizeof(&arr[0]+1));
&arr[0]+1 表示&arr[1], 结果:4
2.4 字符串赋值给指针的sizeof()
char *p = "abcdef";
看清楚p这是一个字符指针,指向字符串“abcdef”
printf("%d\n", sizeof(p));
p是字符指针,表示字符串首地址,指针大小为4个字节; 结果:4
printf("%d\n", sizeof(p+1));
p+1表示 字符串第二个元素的地址; 结果:4
printf("%d\n", sizeof(*p));
*p表示 字符'a',类型为 char; 结果为;1
printf("%d\n", sizeof(p[0]));
p[0]表示第一个元素,字符'a',类型为 char; 结果:1
printf("%d\n", sizeof(&p));
&p是字符指针p的地址,类型为 char**, 结果:4
printf("%d\n", sizeof(&p+1));
&p + 1 表示地址, 最终结果:4
printf("%d\n", sizeof(&p[0]+1));
&p[0] + 1表示第二个元素 p[1]的地址; 结果: 4
3. 二维数组的sizeof()
数组名是首元素地址,对于二维数组来说也不例外;
记: sizeof(*a) == sizeof(a[0])
除两个例外
sizeof(arr) 表示整个数组的大小,
&arr,表示整个数组的地址。
把二维数组 arr[n][m],看成 n 个一维数组,每个一维数组有m个元素。
对于二维数组来说:
第 0 行的首元素地址为 arr[0], arr[0],表示二维数组的第 0 行一维数组的数组名
第 1 行的首元素地址为arr[1],arr[1],表示二维数组的第 1 行 一维数组的数组名
…
第 n行的首元素地址为 arr[n]
arr == arr[0] 二维数组名是首元素的地址,即 第 0 行 一维数组首元素的地址,
arr + 1 ==arr[1],二维数组首元素地址 + 1,表示移动了 1 行,即 第 1 行 一维数组首元素的地址。
…
arr + n ==arr[n],二维数组首元素地址 + n,表示移动了 n 行,即 第 n 行 一维数组首元素的地址。
int a[3][4] = {0};
二维数组的数组名也是首元素的地址;除两个例外
sizeof(arr) 表示整个数组的大小,
&arr,表示整个数组的地址。
printf("%d\n",sizeof(a));
sizeof(a) 表示整个数组的大小,该数组有3×4 = 12 个元素,每个元素类型为 int; 结果: 48
printf("%d\n",sizeof(a[0][0]));
arr[0][0]表示第 0 行 第 0 个元素,类型为 int; 结果:4
printf("%d\n",sizeof(a[0]));
a[0]表示二维数组第 0 行的一维数组,求一维数组的总大小,该一维数组有4个元素,结果:16
printf("%d\n",sizeof(a[0]+1));
a[0] + 1表示二维数组第 0 行的一维数组的数组名,一维数组名+ 1,表示跳过一个元素的地址,即 a[0] + 1,表示 &a[0][1]; 结果:4
区分 a+1 与 a[0]+1 与 &a[0]+1
printf("%d\n",sizeof(*(a[0]+1)));
*(a[0] + 1),表示a[0][1],类型为 int; 结果:4
printf("%d\n",sizeof(a+1));
数组名a是首元素的地址,数组名 + 1 ,在二维数组表示 跳过一行,即第 1行的一维数组的地址; 结果:4
printf("%d\n",sizeof(*(a+1)));
*(a+1) 表示第 1 行 的一维数组的地址解引用,即a[1]; 结果:16
printf("%d\n",sizeof(&a[0]+1));
&a[0]表示第 0 行一维数组的整个数组的地址,&a[0] + 1,表示跳过了一个一维数组的地址,到达 第 1 行的一位数组的地址,由于第一行一位数组的地址还是地址; 结果:4
printf("%d\n",sizeof(*(&a[0]+1)));
*(&a[0]+1)),表示第一行的数组地址解引用; 结果:16
printf("%d\n",sizeof(*a));
a == &a[0],即第 0 行的地址,解引用为第 0 行数组的整个大小; 结果:16
printf("%d\n",sizeof(a[3]));
a[3]表示第3行的一维数组的数组名,这里越界了,但是sizeof()括号内不参与计算的; 结果:16