#解析在备注里#
一、数组
int main()
{
int arr[] = { 3,0,8,17,9,54 };
printf("%d\n", sizeof(arr));
//答案是24,这里的数组名表示整个数组,sizeof(arr)计算的是整个数组的大小,即4×6=24
printf("%d\n", sizeof(arr + 0));
//答案是8,这里的arr没有单独存放在sizeof内部,也没有取地址,则表示数组首元素地址,arr+0表示跳过0个int类型的变量,仍然还是首元素地址,是地址大小就为8个字节
printf("%d\n", sizeof(*arr));
//答案是4,arr表示首元素地址,*arr解引用之后就为首元素,大小是4个字节,*arr->*&arr[0]->arr[0]
printf("%d\n", sizeof(arr + 1));
//答案是8,arr+1跳过一个int类型的变量,表示第二个元素的地址,是地址大小就为8个字节
printf("%d\n", sizeof(arr[1]));
//答案是4,arr[1]表示第二个元素,大小是4个字节
printf("%d\n", sizeof(&arr));
//答案是8,&arr这里的arr表示整个数组,取出的是整个数组的大小,&arr即表示整个数组的地址,是地址大小就为8
printf("%d\n", sizeof(*&arr));
//答案是24,&arr表示整个数组的地址,*对其解引用找到的是整个数组,大小是4×6=24个字节,&arr是数组指针,类型是int(*)[6],数组指针解引用找到的是数组
printf("%d\n", sizeof(&arr + 1));
//答案是8,&arr+1表示跳过整个数组的地址,最终结果还是地址,大小是8个字节,&arr+1是从数组arr的地址向后跳过了一个(6个整型元素)数组的大小
printf("%d\n", sizeof(&arr[0]));
//答案是8,&arr[0]表示第一个元素的地址,是地址大小就是8个字节
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示第二个元素的地址,大小是8
return 0;
}
提示:
1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3、除此之外所有的数组名都表示首元素的地址。
二、字符数组
int main()
{
char arr[] = { 'x','y','z','p','q','r','m','n','k'};
printf("%d\n", sizeof(arr));
//答案是9,这里arr表示整个数组,计算的是整个数组的大小,即1×9=9
printf("%d\n", sizeof(arr + 0));
//答案是8,arr表示数组首元素地址,arr+0表示跳过0个char类型的变量,还是首元素地址,是地址大小就是8
printf("%d\n", sizeof(*arr));
//答案是1,*表示解引用,*arr就表示首元素,大小是1,*arr->*(arr+0)->arr[0]
printf("%d\n", sizeof(arr[1]));
//答案是1,arr[1]表示第二个元素,大小是1
printf("%d\n", sizeof(&arr));
//答案是8,&arr表示整个数组的地址,是地址大小就是8
printf("%d\n", sizeof(&arr + 1));
//答案是8,&arr+1是跳过了一个(9个字符型元素)的数组后的地址,大小是8
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示跳过一个char型变量的地址,即第二个元素的地址,大小是8
return 0;
}
提示:
sizeof是操作符,只关注占用内存空间的大小(类型),不在乎内存中放的是什么
strlen是库函数,只针对字符串,strlen是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符个数
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
//"POINT",注意运行结束此时cpp指向cp[1]
printf("%s\n", *--* ++cpp + 3);
//"ER",++优先级高,先执行*--*++cpp,再执行c[0]+3,此时cpp指向cp[2]
printf("%s\n", *cpp[-2] + 3);
//"ST",等效*(*(cpp-2))+3,cpp-2指向cp[0],两次解引用后c[3]+3,注意此时cpp指向并没有改变
printf("%s\n", cpp[-1][-1] + 1);
//"EW",等效*(*(cpp-1)-1)+1,cpp-1指向cp[1],第一次解引用指向c[1],第二次解引用指向"NEW",+1后指向E
三、二维数组
int main()
{
int arr[5][6] = { 0 };
printf("%d\n", sizeof(arr));
//答案是120,5×6×4=120
printf("%d\n", sizeof(arr[0][0]));
//答案是4
printf("%d\n", sizeof(arr[0]));
//答案是24,arr[0]是第一行这个一维数组的数组名,单独放在sizeof内部,arr[0]表示第一个整个这个一维数组
printf("%d\n", sizeof(arr[0] + 1));
//答案是8,arr[0]并没有单独放在sizeof内部,也没取地址,arr[0]就表示首元素地址,就是第一行这个一维数组的第一个元素的地址,arr[0]+1就是第一行第二个元素的地址
printf("%d\n", sizeof(*(arr[0] + 1)));
//答案是4
printf("%d\n", sizeof(arr + 1));
//答案是8,arr+1表示第二行的地址
printf("%d\n", sizeof(*(arr + 1)));
//答案是24
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示第二行的地址
printf("%d\n", sizeof(*(&arr[0] + 1)));
//答案是24
printf("%d\n", sizeof(*arr));
//答案是24
printf("%d\n", sizeof(arr[3]));
//答案是24
return 0;
}
提示:arr[]是每行的数组名,arr[][]是每个的数组名