一维数组
int a[ ] = { 1,2,3,4 };
printf("%d\n", sizeof(a)); //16
//数组名单独放在sizeof内部,数组名表示整个数组。 sizeof(数组名)计算的是整个数组的大小,单位是字节。
printf("%d\n", sizeof(a + 0)); //4 不是单独放在sizeof内部,它表示首元素地址
printf("%d\n", sizeof(*a)); //4 首元素
// *a == *(a + 0) == a[0];
// arr[i] ==> *(arr + i)
printf("%d\n", sizeof(a + 1)); //4 第二个元素地址
printf("%d\n", sizeof(a[1])); //4 第二个元素
printf("%d\n", sizeof(&a)); //4 &a取的是数组的地址,无论取谁的地址,都是4个字节(32位)
拓展:
我们来看看下面这些
printf("%p\n", &a[0]); printf("%p\n", a); printf("%p\n", &a);
它们的结果是
那改成下面这样呢,再来看
printf("%p\n", &a[0] ); printf("%p\n", &a[0]+1); printf("%p\n", a); printf("%p\n", a + 1); printf("%p\n", &a); printf("%p\n", &a + 1);
结果如下
我们发现,&a[0] + 1和a + 1都跳了4个字节,即跳到第二个元素,而&a+1它跳过了16个字节,也就是跳过了整个数组
printf("%d\n", sizeof(*&a)); //16 指针访问整个数组
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 整个数组
printf("%d\n", sizeof(arr+0)); //4 首元素地址(不要以为是char类型就以为是1,它就是个地址)
printf("%d\n", sizeof(*arr)); //1 首元素
printf("%d\n", sizeof(arr[1])); //1 第二个元素
printf("%d\n", sizeof(&arr)); //4 首元素地址
printf("%d\n", sizeof(&arr+1)); //4 跳过这个数组后的地址
printf("%d\n", sizeof(&arr[0]+1)); //4 第二个首元素地址
//strlen 求字符串长度
printf("%d\n", strlen(arr)); // 随机值 strlen求字符串长度需要字符串以\0结束,而这个数组中没有\n
printf("%d\n", strlen(arr + 0)); // 随机值 原因同上
printf("%d\n", strlen(*arr)); // 程序错误 *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)); // 随机值
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); // 7 arr[]={{a},{b},{c},{d},{e},{f},{\0}};
printf("%d\n", sizeof(arr + 0)); // 4
printf("%d\n", sizeof(*arr)); // 1
printf("%d\n", sizeof(arr[1])); // 1
printf("%d\n", sizeof(&arr)); // 4
printf("%d\n", sizeof(&arr + 1)); // 4
printf("%d\n", sizeof(&arr[0] + 1)); // 4
printf("%d\n", strlen(arr)); // 6 虽然字符串最后有‘\0’,strlen求长度不算'\0'
printf("%d\n", strlen(arr + 0)); // 6
printf("%d\n", strlen(*arr)); // 程序错误
printf("%d\n", strlen(arr[1])); // 程序错误
printf("%d\n", strlen(&arr)); // 6
printf("%d\n", strlen(&arr + 1)); // 随机值 跳过这个数组开始计算,不知道什么时候会碰到‘\0’
printf("%d\n", strlen(&arr[0] + 1)); // 5 从第二个元素地址开始( 6 - 1 = 5 )
char *p = "abcdef";
printf("%d\n", sizeof(p)); // 4 p是个指针变量,4个字节
printf("%d\n", sizeof(p + 1)); // 4 p+1存的第二个元素的地址,4个字节
printf("%d\n", sizeof(*p)); // 1 首元素
printf("%d\n", sizeof(p[0])); // 1
printf("%d\n", sizeof(&p)); // 4 指针变量地址
printf("%d\n", sizeof(&p + 1)); // 4 p的地址的下一个地址,与数组无关了
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)); // 程序错误
printf("%d\n", strlen(p[0])); // 程序错误
printf("%d\n", strlen(&p)); // 随机值 从p的地址开始数,不知道后面的情况
printf("%d\n", strlen(&p + 1)); // 随机值
printf("%d\n", strlen(&p[0] + 1)); // 5
二维数组
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 相当于第一行的数组名
printf("%d\n", sizeof(a[0] + 1)); // 4 a[0]相当于第一行的数组名,它不单独在sizeof() 内,所以a[0]降级为第一行第一个元素,a[0]+1则表示为第一行第二个元素地址
printf("%d\n", sizeof(a + 1)); // 4 a不单独在sizeof() 内,二维数组 a 降级为一维数组 ,即第一行地址,+1就是第二行的地址(不是第二行第一个元素的地址)
printf("%d\n", sizeof(&a[0] + 1)); // 4 第二行的地址
printf("%d\n", sizeof(*a)); // 16 a不单独在sizeof() 内,二维数组 a 降级为一维数组 ,即第一行地址
printf("%d\n", sizeof(a[3])); // 16 sizeof内部不参与运算,我们可以根据a[3]这个表达式推测出它和a[0]的类型是一样的,所以无论a[ ]中是多少,它的大小都是16 (sizeof(int)是4,int是个类型)