关于C语言二维数组数组名与指针的问题

如下代码所示:

int arr[3][4] = {0};//定义一个二维数组
int (*p)[6] = arr;//定义一个数组指针指向二维数组的首地址arr
printf("--*arr= %x--\n",*arr);
printf("--arr= %x--\n",arr);
printf("--&arr= %x--\n",&arr);
---------------------------------------
输出结果都是
--*arr= 2686640--
--arr= 28feb0--
--&arr= 28feb0--
由此可以看出输出结果相同
第一个问题:如果说数组名就是数组首地址,那么,为什么*arr取出来的还是首地址呢,*和指针结合取得不是指针指向的内容嘛,如果把printf("--*arr= %x--\n",*arr);换成printf("--*arr= %d--\n",*arr);那么输出的结果应该是0才对,但是我试了,结果不是,这个为什么??
第二个问题:arr是首地址,那么&arr输出结果跟首地址一样,作何解释??

第1个回答  2015-08-14
int (*p)[6] = arr;//定义一个数组指针指向二维数组的首地址arr
这行奇葩的代码就不做点评了,在如果在C++的编译器里编译器绝对打脸。

数组名代表的指针其实是降了一级的指针,比如你写int p[10],数组名p并不是指向十个int元素,而是指向第一个int元素,如果希望得到int [10]的指针应该使用&p;int arr[3][4]也是如此,arr并不是指向arr[3][4],而是指向第一个int [4]数组,要指向整个int [3][4]使用&arr。

他们的地址都是一样的,都是指向第一个元素的地址,但是他们的指针指向的对象长度是不一样的。追问

那数组指针应该如何指,他既然是指针应该有指向啊,还有,我重点想知道*p为什么此时不是内容而还是地址,还有数组名代表的指针是降了一级的指针是啥意思?

追答

基础不行就会有很多疑问,C语言里指针是个比较难的内容,很多书讲解的不够,而且大部分C初学者学习深度不够,达不到入门的水平。我觉得如果学习C语言的人能够把C语言的入门书籍真的学懂是不存在这些基础问题的,这种问题完全是基础不行的表现

追问

你说的很对,肯定是基础不行才问的

本回答被网友采纳
第2个回答  推荐于2016-11-25
先说些这个2维数组:int arr[3][4]
可以理解为一个3行四列的矩阵,那么第一维arr[0],arr[1],arr[2]中存的分别是对应行的地址,也就是说arr[0]存的是一个“大小为4的整形数组地址”
这样的话就好理解了,arr存的地址值其实与arr[0]本质上是相同的。都是这个连续空间的开始地址。
第一个问题,arr是个地址变量,因此它本身是个地址,而它存的其实也是个地址。
第二个问题,&arr也是首地址,不过叫“2维数组的首地址”,却别的话就是它有个宽度,举个例子:“&arr+1”其实相当于“&arr[sizeof(a)+1]”这里arr大小为7,那么&arr+1就是从二维数组首地址开始后的第8个整形变量空间的地址。当然从地址值的角度看它们是没有什么却别的,区别在于“指针宽度”
不知道你明白没?追问

arr应该是不是地址变量吧,应该是指针常量吧,只是个符号吧,那为什么取二维数组的第一个值还要用*(*arr)呢?
第二个问题已明白

追答

是变量就有存储空间,指针变量指的是存储地址的变量。arr是这个变量的名称(或者你所说的符号),它存储的是一个指向二维数组空间的地址。你这样理解:arr这个符号是12345,12345是个内存地址。在12345地址处的里面存的是数字0。那么*arr也就是*(12345)表示的就是0;如果12345地址处存放的还是个地址为67890,那么*(*(12345))就是内存地址为67890处的数据。
arr存的是首地址,arr[0]存的也是地址,&(arr[0][0]);你可以把以上三个地址输出下看看。

本回答被提问者采纳
相似回答