下面简单了解下二维数组的组成(引用的是《c语言入门经典》的图):
从图中可以看出,board作为二维数组是由两层构成的,第一层为纵向数组,第二层为横向数组。
也就是说board是纵向数组的首地址,也就是纵向数组的第一个元素board[0]的地址。这就解释了board的值为什么等于&board[0]的值。而(board+i)就是对数组的第i的元素进行访问,所以*board就是*(board+0),就是board[0]。
第二层每个子数组里面由包含了各自的横向的一维数组,所以从这个角度上来说,board[0]这时候就成了数组名了,它包含了board[0][0]、board[0][1]、board[0][2]这三个元素。所以数组名board[0]就是数组的第一个元素board[0][0]的地址,即&board[0][0]。即board[0]与&board[0][0]的值是一样的。
又因为上面第一层的解释中我们已经知道了board[0]的值与board、*board、&board[0]相等。所以说上面程序中的五条输出语句的结果是一样的。
好了,说了那么多。不知道听晕了没有。总之,二维数组是由两层构成的。
其本质是因为二维数组在内存里面是连续存储的,即board[0][0]
一直到board[2][2]这九个数都是一个个紧挨着的。牢记这句话,这与一维指针数组是不一样的。
一维指针数组
先定义一个一维字符指针数组,
char *a[3]={"monday","tuesday","wednesday"};
printf("&a[][]:%d\n",&a[0][0]);
printf("a[0][0]:%c\n",a[0][0]);
printf("&a[0]:%d\n",&a[0]);
printf("a:%d\n",a);
printf("&a:%d\n",&a);
printf("a[0]:%d\n",a[0]);1234567
下面是输出
可以看出a和&a、&a[0]结果一样,但是&a[0][0]与其他不一样。这与二维数组是不同的。正如我们之前所见的,二维数组的输出都是一样的。
首先我们要理解char a[3]的含义,这是定义了一个一维数组,数组名为a, 共有三个元素,且元素的类型是char *型。那么我们很清楚了,a是一维数组的名字,也是数组的首地址,所以与&a相等,也与数组的第一个元素的地址&a[0]一样。而a[0]是一个char型的指针变量,指针变量里面存放的是地址。而我们知道的通常情况下指针如int *p=&a,p和&p的内容是不一样的,p放的是要访问的变量a的地址,而&p是指针p的自己的内存地址,两者不一样。所以类似的,&a[0]与a[0]不是同一个东西。a[0]放的是“monday”这个字符串的地址,也就是’m’的地址,所以&a[0][0]即m的地址与a[0]是一样的,都为4216712。