前言
先提前把总结内容放在前面:
①sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
②&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
③除此之外的所有数组名表示的都是首元素的地址。
一、一维数组
//一维数组
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//这里是整个数组的字节大小
printf("%d\n", sizeof(a+0));//进行运算,这里是数组的首元素地址的字节大小
printf("%d\n", sizeof(*a));//*a为int类型,其字节大小还是指针的字节大小(4/8)
printf("%d\n", sizeof(a[1]));//等价*(a+1),为int类型,四个字节
printf("%d\n", sizeof(&a));//取出的数组地址,为int(ptr*)[4],是一个数组指针,大小还是4/8字节
printf("%d\n", sizeof(&a+1));//数组指针加一还是指针,只是跳过类型决定的字节数,其字节大小还是4/8
printf("%d\n", sizeof(&a[0]+1));//取出首元素地址加一,与a[1]等价
运行结果:

二、字符数组
//一维数组
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//这里是整个数组的字节大小
printf("%d\n", sizeof(a+0));//进行运算,这里是数组的首元素地址的字节大小
printf("%d\n", sizeof(*a));//*a为int类型,其字节大小还是指针的字节大小(4/8)
printf("%d\n", sizeof(a[1]));//等价*(a+1),为int类型,四个字节
printf("%d\n", sizeof(&a));//取出的数组地址,为int(ptr*)[4],是一个数组指针,大小还是4/8字节
printf("%d\n", sizeof(&a+1));//数组指针加一还是指针,只是跳过类型决定的字节数,其字节大小还是4/8
printf("%d\n", sizeof(&a[0]+1));//取出首元素地址加一,与a[1]等价
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//计算整个数组大小,1*6个字节
printf("%d\n", sizeof(arr+0));//等价&(arr[0]),为首元素地址
printf("%d\n", sizeof(*arr));//等价arr[0],char类型,大小为一个字节
printf("%d\n", sizeof(&arr));//为数组指针,char (ptr*)[6],为4/8个字节
//字符串
char str[] = "abcdef";
printf("%d\n", sizeof(str));//整个数组的大小,7*1=7个字节(末尾有'\0')
printf("%d\n", sizeof(str+0));//首元素地址
printf("%d\n", strlen(str));//计算字符串长度,为6
printf("%d\n", strlen(str + 1));//str表示首元素地址,即从b开始计数,为5
printf("%d\n", strlen(*str));//视a的ASCILL值97为地址,开始访问,最终结果为随机值(要注意的是,这里属于非法访问,运行时会报错)
printf("%d\n", strlen(&str));//与str等价(strlen只需要一个起始地址,不论类型)
printf("%d\n", strlen(&str + 1));//起始地址跳过一个char(ptr*)[6],结果是随机值
printf("%d\n", strlen(&str[0] + 1));//起始地址为str[1]
三、二维数组
//二维数组
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//计算整个数组的大小,3*4*4=48
printf("%d\n", sizeof(a[0][0]));//计算第一个元素类型字节大小,int型为4个字节
printf("%d\n", sizeof(a[0]));//a[0]相当于第一行数组名,等价于*(a+0),计算第一行数组大小
printf("%d\n", sizeof(a[0] + 1));//数组名加1,等价于第一行第二个元素地址
printf("%d\n", sizeof(*(a[0] + 1)));//等价a[0][1]
printf("%d\n", sizeof(a + 1));//a进行运算,等价于&a[1],即第二行数组地址
printf("%d\n", sizeof(*(a + 1)));//与a[1]等价,即第二行首元素地址
printf("%d\n", sizeof(&a[0] + 1));//第二行数组地址,等价与&a[1]
printf("%d\n", sizeof(*(&a[0] + 1)));//计算第二行数组大小,等价a[1]
printf("%d\n", sizeof(*a));//计算第一行数组大小,等价a[0]
printf("%d\n", sizeof(&a[3]));//取出的是第三行数组的地址,所以还是指针的字节大小(sizeof不管越界,自动推测类型)
二维数组总结:
①对二维数组数组名解引用等价arr<==>(arr+0)<>arr[0]
②二维数组首元素加数字,等价arr+1<>&arr[1],即第二行数组地址,是一个数组指针
③*(arr+1)<==>*&arr[1],即为arr[1],第二行首元素地址(也可看做是第二行数组名)
四、经典例题
笔试题1.
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
//程序的结果是什么?`

即答案为2,5

1036

被折叠的 条评论
为什么被折叠?



