无法理解数组的行为

时间:2014-11-22 07:14:22

标签: 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] = 17;
  }

问题:
我期望printf语句打印8但是它的打印17 我不明白为什么?

谢谢

3 个答案:

答案 0 :(得分:7)

++b中注意func(),在此之后b(最初指向a[0][0]),现在指向a[1][0],所以以下

b[1][1] = 17;

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

答案 1 :(得分:5)

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

     #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]);
     }       

它会显示在您进行转换后,b[1][1]地址将指向a[2][1]单元格,因为b是指向数组行和b++转换的指针下降一行。

您也可以通过指针传递值,因此函数func可以访问a所在的相同内存。

如果我建议,只需在学习的同时打印所有内容,并查看这个精彩的演示文稿:http://www.slideshare.net/olvemaudal/deep-c?qid=1fcb7c99-e916-4bcd-baa2-1a1f974d1c68

答案 2 :(得分:4)

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

b当前指向第一个数组{1,2,3}。 ++ b执行指针运算,因此b递增以指向下一个数组{4,5,6}。所以b [1] [1]将更新主要的[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;
}