关于二维数组和一维指针数组的区别

来源:互联网 发布:远洋数据招聘 编辑:程序博客网 时间:2024/05/18 00:31

二维数组

下面的代码先定义了一个整数二维数组,board[3][3]

    int board[3][3]={                    {'1','2','3'},                    {'4','5','6'},                    {'7','8','9'}            };    printf("*board:%9d\n",*board);//相当于board[0]    printf("board:%9d\n",board);//二维数组名也就是二维数组的首地址    printf("&board[0][0]:%9d\n",&board[0][0]);//第一个元素的地址    printf("board[0]:%9d\n",board[0]);//二维数组board的第一个子数组的名称/地址    printf("&board[0]:%9d\n",&board[0]);//相当于board

下面是运行的结果:

这里写图片描述

从运行结果和程序的注释可以看出,输出的值是一样的,但是表示的意思不大一样。在解释之前,我们先回顾下一维数组的知识,int a[3]={1,2,3};其中a是数组名,也是第一个元素a[0]的地址,即a、&a、&a[0]三个的值一样的。(但是&a和a分别自加所移动的长度是不一样的)。 另外,*(a+1)就是a[1]就是数值2。这应该是没有疑问的。好的,那进行下一步了。

下面简单了解下二维数组的组成(引用的是《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]);

下面是输出
这里写图片描述

可以看出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。

至此,该解释的也说的差不多了。这就是两者的区别之处,希望大家多多注意。不对的地方欢迎提出来哈。

0 0
原创粉丝点击