user-0 提问: C语言二维数组一些问题 问题在注释里

回复:
user: user-0
content: 现在学了指针才知道之前说错了，a=&a[0]，此时a和&a[0]，纯地址也相同，基类型也相同，都是指向行的，指向一维数组a[0]，a[0]=&a[0][0]，纯地址也相同，基类型也相同，都是指向第0行第1列数组的元素，而a和a[0]虽然纯地址相同，但是基类型不同，前者是int(*)[n]型，后者是int *型。而且一个纯地址不可以再取地址，纯地址不可以，所以不可以&&a[0][0]，此时&a[0][0]就是一个纯地址，当然不可以再取地址，如果指针p指向&a[0][0]，再取此指针p的地址就可以了。

user: user-1
content: c语言书上有，基础的

user: user-0
content: 刚刚问了一个人，在二维数组里，a=&a[0]=&a[0][0]，但a不等于a[0]，地址不行，但指针可以，因为数组底层是指针实现的，所以a在二维数组里才等于a[0]。

user: user-2
content: 用指针表达一下数组，就可以理解这个问题了

user: user-2
content: 应该还是因为a[0]和a均不是变量的原因。 只有a[0][0]是变量。 int a[3][4]的含义不是定义了一个3*4的整数数组，而是3*4个整数的集合 也就说这个集合中的每个元素是int ，但是这个集合不是int  还有一个原因，在实际的实现里好像是既没有数组的概念，也没有变量的概念。 实际实现，都是用地址偏移实现的。  假设a是a[0]的首地址，那么a++，a+5... 就很好的操作 同样a[0]++,a[0]+5,就很好操作下一级的元素。  如果让a定义成就是本身的地址，或者最低维的地址，就不好操作。 定义为本身，++就偏移出数组了，定义为最低维，每次只能移动一个元素。  而且，个人认为，不能a=&a[0],这样理解，他们只是数值相等 a[0]本身就是地址，不能对地址取地址

user: user-0
content: 回答了就结贴了

user: user-0
content: 那好的，刚刚说到a=&a[0]，a[0]=&a[0][0]，那么如何推出a=a[0]呢？

user: user-2
content: int a; int b=&a; b=&&a; 这么写是错误，一个地址不再会有地址了。 int a; int b=&a; int c=&b; 实际上二级间址，取的是指针变量的地址。 int a; int * b=&a; int **c=&b; **c=5; printf("%d",a); 个人认为数组名不是变量，更像是数据类型。

user: user-0
content: 嗯，例如二维数组a[3][4]，可以把a看作一个一维数组，它有3个元素:a[0],a[1],a[2],每个元素又是一个包含4个元素的一维数组，例如a[0]包含a[0][0] a[0][1] a[0][2] a[0][3]，所以在定义上来看，a包含的一个数组有三个元素，a就是这三个元素的首地址，也就是a=&a[0]（一式）。 a[0]包含一个数组有四个元素(此时把a[0]看做包含四个元素的这个数组的名字)，所以a[0]=&a[0][0]。（二式）。所以由一式和二式推出a=&a[0]=&&a[0][0]. 但是我有一个疑问，为啥&&a[0][0]打印不出来？    #include<stdio.h>   int main() {     int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};     printf("%d",&(&a[0][0]));     return 0; }

user: user-2
content: 好难，我是这么理解的，不知道对不对。 二维数组其实是这么定义的， 定义了一个数组[3]，这个数组的每个元素是一个数组[4] 所以a是数组[3]的首地址 也就是说a的定义含义是a[0]的地址，而只是在数值上相等于a[0][0]的地址，其含义并不是。 同时，a并不是一个变量，a是数组。a就是a的地址。 也就是说，没有一个地方保存着a的地址，更没有一个变量a a就是数组的地址  那么  a+1，是a[3]这个数组的元素，偏移1，也就是偏移一个[4] &a，导致a的含义发生改变，a不再是a[3]这个数组元素的首地址，而是整个类型的地址（这里假设把数组看成数据类型） &a+1，是整个a+1，也就是偏移了sizeof a  a[0]是a[3]这个数组的首个元素（你可能这里混淆了），其是[4]数组的首个地址，也就是a[0][0]的地址。 所以a[0]+1，是a[0][1]的地址 a[1]是a[3]这个数组的第二个元素，其同样是一个[4]数组的首地址，也就是a[1][0]的地址。 a[1]+1是a[1][1]的地址  a是a[3]这个数组的首个元素的地址，也就是a[0]的地址，每个元素是一个[4]数组 也就是说*a,是一个[4]数组的首地址。 所以*a+1，是a[0]1]的地址。  我已经晕了，这指针也太绕了。

user: user-0
content: https://blog.csdn.net/qq_39589390/article/details/88048973  好的 刚刚找到一篇文章不错

user: user-3
content: 建议楼主考虑类型，比如a和a[0]，已经&a[0][0]的地址都是一样的，但是类型不一定一样哦。

user: user-4
content: a+1, 是a[3][4]数组中的 a[1][4]这一行的首地址。二维数组首地址是行地址 a (也就是a+0)是第一行， a+1是第二行， a+2是第三行，每一行有4个元素，这样可以理解吧

user: user-0
content: #include<stdio.h>   int main() {     int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};     printf("%d\n",a);//a是整个二维数组的首地址，a=&a[0]=&&a[0][0]，      printf("%d\n",a+1);//a+1就是整个二维数组首地址偏移一个数组，那么a+1不应该是a的地址加上整个二维数组元素个数12吗？为什么结果不是？      printf("\n");          printf("%d\n",&a);//&a是指向二维数组的指针存放的地址，结果为什么和&a一样？是巧合吗？      printf("%d\n",&a+1);//&a+1就是指向二维数组的指针向下偏移一个，那么a+1不应该是a的地址加上整个二维数组元素个数12吗？为什么结果不是？     printf("\n");          printf("%d\n",a[0]);//a[0]是二维数组第一行的首地址     printf("%d\n",a[0]+1);//a[0]+1是二维数组第一行的首地址向下偏移一行的地址，也就是二维数组第二行的首地址，结果相差一行4个数字，正确！      printf("%d\n",a[1]);//a[1]是二维数组第二行的首地址，为什么结果和a[0]+1不同？      printf("%d\n",a[1]+1);//a[1]+1和a[1]结果相差4，正确！      printf("\n");          printf("%d\n",*a);//二维数组的第一行地址      printf("%d\n",*a+1);//*a+1是二维数组的第一行地址向下平移一样的地址，正确！      printf("\n");     return 0;      }