学前服用
动画版的这个听完再去看书上的实例真的很不错!www.bilibili.com/video/BV1MJ…
一、指针和多维数组的关系
书上写的也很详细
b站有个视频写的也挺好,分享出来
下面这个是我做的笔记(下次一定把字写好)
此时,C和C[0]的值都是二维数组的首地址
实例
#include <stdio.h> int main(void) { int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}}; //zippon 拉链 printf("zippo = %p,zippo + 1 = %p\n", zippo, zippo + 1); //zippo和zippo[0]都是二维数组的首地址 printf("zippo[0] = %p, zippo[0]+1 = %p\n", zippo[0], zippo[0] + 1); //zippo+1是指向第二个一维数组,zippo[0]+1是第一个一维数组的第二个元素 printf("*zippo = %p,*zippo+1 = %p\n", *zippo, *zippo + 1); printf("zippo[0][0] = %d\n", zippo[0][0]); printf("*zippo[0] = %d\n", *zippo[0]); printf("**zippo = %d \n", **zippo); printf("zippon[2][1] = %d\n", zippo[2][1]); printf("*(*(zippo+2)+1) = %d\n", *(*(zippo + 2) + 1)); return 0; } 输出的结果: PS D:\Code\C\指针> cd "d:\Code\C\指针\" ; if ($?) { gcc 指针Demo06.c -o 指针Demo06 } ; if ($?) { .\指针Demo06 } zippo = 000000000061FE00,zippo + 1 = 000000000061FE08 zippo[0] = 000000000061FE00, zippo[0]+1 = 000000000061FE04 *zippo = 000000000061FE00,*zippo+1 = 000000000061FE04 zippo[0][0] = 2 *zippo[0] = 2 **zippo = 2 zippon[2][1] = 3 *(*(zippo+2)+1) = 3
解析
其他系统显示的地址值和地址形式可能不同,但是地址之间的关系与以上输出相同。该输出显示了二维数组zippo的地址和一维数组zippo[0]的地址相同。它们的地址都是各自数组首元素的地址,因而与&zippo [0] [0]的值也相同。 尽管如此,它们也有差别。在我们的系统中, int是4字节。前面讨论过,zippo[0]指向一个4字节的数据对象。zippo[0]加1,其值加4。
数组名zippo 是一个内含2个int类型值的数组的地址,所以zippo指向一个8字节的数据对象。因此,zippo 加1,它所指向的地址加8字节。
该程序演示了zippo[0]和zippo完全相同,实际上确实如此。然后,对二维数组名解引用两次,得到储存在数组中的值。使用两个间接运算符(*)或者使用两对方括号([])都能获得该值(还可以使用一个和一对[ ],但是我们暂不讨论这么多情况)。
要特别注意,与 zippo[2] [1]等价的指针表示法是 ((zippo+2) + 1)。看上去比较复杂,应最好能理解。下面列出了理解该表达式的思路:
zippo 二维数组首元素的地址(每个元素都是内含两个int类型元素的一维数组)
zippo + 2 二维数组的第三个一维数组的地址
*(zippo + 2)二维数组的第三个一维数组的地址首元素(一个int类型的值)地址
*(zippo + 2)+ 1 二维数组的第3个元素(即一维数组)的第2个元素(也是一个int类型的值)地址
*(*(zippo + 2)+ 1) 二维数组的第3个元素(即一维数组)的第2个元素的值,即zippo[2][1]
以上分析并不是为了说明用指针表示法(* (*(zippo+2) + 1))代替数组表示法(zippo[2][1]),而是提示读者,如果程序恰巧使用一个指向二维数组的指针,而且要通过该指针获取值时,最好用简单的数组表示法,而不是指针表示法。