0

我在 C 函数的形式参数中阅读了这两种不同类型的多维数组声明。

int c[][10];

int (*c)[10];

这两个怎么一样?我没有感觉到它。谁能用一些例子来解释第二个试图做什么?抱歉,如果以前有人问过这个问题。如果有的话,请将我重定向到副本。

4

3 回答 3

8

作为函数参数,int* cint c[]甚至int c[7]是相同的。请参阅C 常见问题解答

[10]部分仅告诉编译器如何进行算术以访问数组中的元素 - 例如c[3][5]。这两个声明都针对一个多维数组,其第二维(就编译器而言,在此函数内部)大小为 10。

例子:

#include <stdio.h>

int sum_all(int c[][2], int len) {
    int res = 0, i ,j;
    for (i=0; i < len; i++)
        for (j=0; j < 2; j++)
            res += c[i][j];
    return res;
}

int main() {
    int a[3][2] = { { 1, 2}, {3, 4}, {5, 6} };
    printf("sum is %d\n", sum_all(a, 3));
    return 0;
}

请注意,在此示例中,未检查数组的大小为 2。我们可以传递一个一维数组。编译器不在乎;我们只告诉他如何访问这个数组中的元素。

于 2013-06-27T10:22:40.207 回答
4

N1570:

6.7.6.3 函数声明符(包括原型)
......
7 将参数声明为“类型数组”应调整为“ 类型限定符”,其中类型限定符(如果有)是指定的在数组类型派生的[and中。]如果关键字static也出现在数组类型派生的[and]中,那么对于函数的每次调用,对应的实际参数的值应提供对数组的第一个元素的访问,该数组的元素至少与大小指定的一样多表达。

因此,在函数参数声明的上下文中,T a[N]T a[]都等价于T *a; 这三个都声明a为指向T. 在这种特殊情况下,T是“10 元素数组int”。

这与以下内容密切相关:

6.3.2.1 左值、数组和函数指示符
...
3 除非它是运算sizeof符、运算符_Alignof或一元&运算符的操作数,或者是用于初始化数组的字符串字面量,否则为 '' 类型的表达式'' 类型的数组被转换为类型为 ''类型的指针的表达式,该指针指向数组对象的初始元素,而不是左值。如果数组对象具有寄存器存储类,则行为未定义。

假设您有一个声明为的数组

int arr[5][10];

当您将数组表达式arr传递给函数时,例如

foo( arr );

数组表达式arr从类型“10 元素数组的 5 元素数组int”类型转换为“指向 10 元素数组的指针”类型int,并且该指针值是传递给函数的值。所以你的函数原型foo将读作

void foo( int (*c)[10] )

或者

 void foo( int c[][10] )

甚至

 void foo( int c[5][10] )

但在所有三种情况下,c都是指向数组的指针,而不是二维数组。

于 2013-06-27T11:13:38.530 回答
0

考虑当您定义int c[5][10]然后传递c给例程时会发生什么。该数组c将自动转换为指向其第一个元素的指针,该元素是 10 的数组int

因此语言设计者对其进行了安排,以便当您使用 声明参数时c[][10],它会自动调整以匹配将要发生的转换。编译器将数组类型的参数更改为int指向数组的指针类型的参数int

于 2013-06-27T10:58:05.620 回答