C 无法理解数组的行为

C 无法理解数组的行为,c,arrays,C,Arrays,我有以下代码: #include<stdio.h> void func(int [][3]); int main(){ int a[][3] = {{1,2,3}, {4,5,6}, {7,8,9}}; func(a); printf("%d", a[2][1]); } void func(int b[][3]){ ++b; b[1][1

我有以下代码:

 #include<stdio.h>
   void func(int [][3]);

   int main(){
           int a[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
           func(a);
           printf("%d", a[2][1]);
   }       

  void func(int b[][3]){
          ++b;
          b[1][1] = 17;
  }
#包括
void func(int[][3]);
int main(){
int a[][3]={{1,2,3},{4,5,6},{7,8,9};
func(a);
printf(“%d”,a[2][1]);
}       
void func(int b[][3]){
++b;
b[1][1]=17;
}
问题:
我希望printf语句打印8,但打印17。
我不明白为什么


感谢注意
++b
func()
之后,
b
(最初指向
a[0][0]
),现在指向
a[1][0]
,因此

b[1][1] = 17;

在外部修改
a[2][1]

在C中,int b[][3]等数组参数只是指向数组所在内存的指针。因此,func()中对数组的更新将持续存在,因为您正在访问main和func()中的相同内存

b当前指向第一个数组{1,2,3}++b执行指针算术,因此b递增以指向下一个数组{4,5,6}。所以b[1][1]将更新main的a[2][1],这就是您打印的内容。请尝试以下代码,以查看您是否确实正在更新相同的内存地址

#include<stdio.h>
void func(int [][3]);

int main(){
    int a[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
    printf("%p\n", a+1);
    func(a);
    printf("%d\n", a[2][1]);
}

void func(int b[][3]){
    ++b;
    printf("%p\n", b);
    b[1][1] = 17;
}
#包括
void func(int[][3]);
int main(){
int a[][3]={{1,2,3},{4,5,6},{7,8,9};
printf(“%p\n”,a+1);
func(a);
printf(“%d\n”,a[2][1]);
}
void func(int b[][3]){
++b;
printf(“%p\n”,b);
b[1][1]=17;
}

您可以使用扩展代码查看代码的内存布局:

     #include <stdio.h>

     void print_addr(int b[][3])
     {
        for (int i = 0 ; i < 3 ; i++) {
           for (int j = 0 ; j < 3 ; j++)
              printf("%p ", &b[i][j]);
           printf("\n");
        }

     }

     void func(int b[][3]){
        print_addr(b);
        printf("sizeof(b): %d   sizeof(b[0][0]) %d\n", sizeof(b), sizeof(b[0][0]));
        ++b;
        print_addr(b);
        b[1][1] = 17;
     }

     int main()
     {
        int a[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
        func(a);
        printf("%d\n", a[2][1]);
     }       
#包括
无效打印地址(int b[][3])
{
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++)
printf(“%p”、&b[i][j]);
printf(“\n”);
}
}
void func(int b[][3]){
打印地址(b);
printf(“sizeof(b):%d sizeof(b[0][0])%d\n”、sizeof(b)、sizeof(b[0][0]);
++b;
打印地址(b);
b[1][1]=17;
}
int main()
{
int a[][3]={{1,2,3},{4,5,6},{7,8,9};
func(a);
printf(“%d\n”,a[2][1]);
}       
它将显示在您进行移位之后,
b[1][1]
地址将指向
a[2][1]
单元格,因为
b
是指向数组行的指针,
b++
向下移位一行

您还可以通过指针传递值,这样函数
func
就可以访问
a
所在的相同内存


如果我可以建议的话,在学习的同时把所有内容都打印出来,并看看这个漂亮的演示文稿:

为什么你有“++b”-这是否会让代码有点难以理解-因此发布了一个问题。为什么不把它取下来,在指示灯上做算术呢内存布局清楚地解释了图片。谢谢