【问题标题】:(gcc) Multi-Dim Array or Double Pointer for Warning-free Compile(gcc) 用于无警告编译的多维数组或双指针
【发布时间】:2010-03-26 01:01:37
【问题描述】:

我有一个函数,有时用常规数组调用,有时用动态数组调用。

如果我将函数定义为

function_name(int[10][10] a)

并发送 int** 作为参数,我收到警告。相反,如果我声明

function_name(int** a)

并发送 int[][] 作为参数(转换后)我无法访问函数内的数组元素。

什么是最正确的方法?

【问题讨论】:

    标签: c arrays pointers


    【解决方案1】:

    当一个数组被传递给一个函数时,它“衰减”为指向其第一个元素的指针。所以,给定:

    T a[10];
    f(a);
    

    f(a)调用中,a实际上是&a[0],即指针,类型为T *&a[0]的类型)。

    当你有一个数组时,同样的规则适用:

    T a[10][5];
    f(a);
    

    a 再次衰减为指针,等于&a[0]a[0] 的类型为“T 的数组 [5]”。所以,&a[0] 的类型是“指向T 的数组 [5] 的指针”,也就是说,如果你要声明一个指针 p 以设置为等于 &a[0],你会这样做:

    T (*p)[5]; /* parentheses because [] binds tighter than * */
    p = &a[0];
    

    鉴于上述情况,假设您的数组在调用代码中声明为int a[10][10];,您应该将您的函数声明为:

    function_name(int (*a)[10]);
    

    欲了解更多信息,请参阅this

    function_name(int[10][10] a) 中存在语法错误——您需要在“变量”名称后指定数组大小:function_name(int a[10][10])。其实上面等价于function_name(int (*a)[10]),因为上面提到了“腐烂”。

    编辑:啊,我想我现在明白了。由于上述原因,您不能声明一个同时采用“二维”数组和指向指针的函数(指针的“衰减”只发生一次)。指向指针的指针可能不指向连续数据,并且每个“行”中可能有不同数量的元素。数组数组不能具有这些属性。它们是根本不同的。

    【讨论】:

      【解决方案2】:

      int **int [][] 不一样。 前者是pointer to pointer to int,而第二个是int 的二维数组。

      int[][] decays to int (*)[] when you pass it as argument to function.

      void func(int arr[][10]) { //decays to `int (*arr)[10]` 
        printf("%d correct", arr[1][9]); //10th element of 2nd row
        //printf("%d correct", (*(arr + 1))[9]); //same as above
      }
      
      int main() {
        int (*arr)[10]; //pointer to array of ints
        arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast.
      
        arr[1][9] = 19;
        func(arr);
      
        return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-09
        • 2022-06-27
        • 2013-04-08
        相关资源
        最近更新 更多