目录
一维数组
sizeof在计算的时候,只看操作数的类型,并不会访问空间。
二维数组
一维数组
sizeof在计算的时候,只看操作数的类型,并不会访问空间。
数组名:
一、sizeof(数组名)——数组名表示整个数组,计算的是整个数组的大小
二、&数组名——数组名表示整个数组,取出的是整个数组的地址
除此之外,所有的数组名都是数组首元素的地址
#include <stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a)); //1
printf("%d\n", sizeof(a + 0)); //2
printf("%d\n", sizeof(*a)); //3
printf("%d\n", sizeof(a + 1)); //4
printf("%d\n", sizeof(a[1])); //5
printf("%d\n", sizeof(&a)); //6
printf("%d\n", sizeof(*&a)); //7
printf("%d\n", sizeof(&a + 1)); //8
printf("%d\n", sizeof(&a[0])); //9
printf("%d\n", sizeof(&a[0] + 1)); //10
return 0;
}
1、数组名单独放在sizeof内,表示的是整个数组,计算的是整个数组的大小,单位是字节。
2、数组名a没有单独放在sizeof内,数组名a前面也没有&,所以这个的数组名a表示的是数组首元 素的地址。所以sizeof(a+0) = 4/8;x86是32位系统,sizeof(a+0) = 4;x64是64位系 统, sizeof(a+0) = 8;
3、数组名a没有单独放在sizeof内,数组名a前面也没有&,所以这个的数组名a表示的是数组首元 素的地址。*a就是首元素==>a[0],大小是4。
*a<==>*(a+0)<==>a[0]
4、和2同理。
5、a[1]就是第二个元素
6、&a——数组的地址,sizeof(&a) = 4/8;类型是int (*)[4]
7、 &a是数组的地址,对数组的地址解引用拿到的是数组,所以大小是16。
这里可以理解为*和&这两个符号抵消了。
8、&a是数组的地址,&a+1是数组的地址+1,跳过整个数组,虽然跳过了数组,但还是地址
9、a[0]表示首元素,&a[0]是首元素的地址
10、&a[0]是首元素的地址,所以&a[0] + 1表示第二个元素的地址
输出结果:
我们接下来再看一个例子。
#include <stdio.h>
#include <string.h>
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p)); //1
printf("%d\n", sizeof(p + 1)); //2
printf("%d\n", sizeof(*p)); //3
printf("%d\n", sizeof(p[0])); //4
printf("%d\n", sizeof(&p)); //5
printf("%d\n", sizeof(&p + 1)); //6
printf("%d\n", sizeof(&p[0] + 1)); //7
return 0;
}
1、p是一个指针变量,存放的是,指向字符串的首元素a。
2、p + 1表示的就是第二个元素的地址,也就是b的地址。
3、由1可知,p是字符串首元素的地址,所以*p = 'a';
4、*a<==>*(a+0)<==>a[0],所以p[0] = 'a';
5、p存放的是字符串首元素的地址,&p表示的是一个二级指针,存放的是p的地址。但依然是一 个指针,所以sizeof(&p) = 4/8;
6、
7、p[0]表示首元素,&p[0]是首元素的地址,所以&p[0] + 1是指向字符串第二个元素的地址。
二维数组
二维数组也是数组
1、sizeof(数组名)
2、&数组名
除此之外,所有数组名都是数组首元素的地址。
a[0]是第一行的数组名, a[1]是第二行的数组名, a[2]是第三行的数组名。
#include <stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a)); //1
printf("%d\n", sizeof(a[0][0])); //2
printf("%d\n", sizeof(a[0])); //3
printf("%d\n", sizeof(a[0] + 1)); //4
printf("%d\n", sizeof(*(a[0] + 1))); //5
printf("%d\n", sizeof(a + 1)); //6
printf("%d\n", sizeof(*(a + 1))); //7
printf("%d\n", sizeof(&a[0] + 1)); //8
printf("%d\n", sizeof(*(&a[0] + 1)));//9
printf("%d\n", sizeof(*a)); //10
printf("%d\n", sizeof(a[3])); //11
return 0;
}
1、数组名单独放在sizeof内部,计算的是整个数组的大小。
2、a[0][0]是第一行第一列的元素。
3、a[0]是二维数组a第一行的数组名,数组名单独放在sizeof内部,则计算的是第一行的大小。
4、a[0]并没有单独放在sizeof内部,也没有&。所以a[0]表示的是第一行第一个元素的地址。故a[0] + 1表示的是,第一行第二个元素的地址。
5、由上面的结论就可以知道,*(a[0] + 1)是第一行第二个元素。
6、二维数组名a没有单独放在sizeof内部,也没有&。所以a表示的是二维数组的首元素的地址, 而二维数组的首元素是二维数组的第一行。所以这里的a是第一行的地址,则a + 1是第二行的 地址。(a + 1)==>&a[1]
7、*(a+1)是对第二行的地址解引用,得到的是,二维数组的第二行。相当于就是*(a+1)==>a[1]。
这个有点类似于:假设一维数组a = {1,2,3,4};&a表示的是数组的地址,而对数组的地址解引 用,得到的是整个数组。所以,sizeof(*(a+1))计算的是第二行的大小。
8、a[0]是第一行的数组名,&a[0]表示的是第一行数组的地址,所以&a[0] + 1就是第二行的地址 了。&a[0] + 1的类型是int (*)[4]。
9、同理,对第二行的地址进行解引用,得到的是第二行数组。sizeof(*(&a[0] + 1))计算的是第二行的大小。*(&a[0] + 1)的类型是int [4]。
10、*a<==>*(a+0)<==>a[0],得到的是第一行数组。
11、a[3]假设存在,就是第四行的数组名,sizeof(a[3]),就相当于把第四行的数组名单独放在 sizeof内部。