我在C中的函数的形式参数中读取了这两种不同类型的多维数组声明。
int c[][10];
int (*c)[10];
这两者是如何相同的?我感觉不到它。任何人都可以用一些例子解释这个,第二个人试图做什么? 对不起,如果以前曾经问过这个问题。请将我重定向到副本(如果有的话)。
答案 0 :(得分:8)
作为函数参数,int* c
和int c[]
或甚至int c[7]
是相同的。请参阅C FAQ。
[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。我们本可以通过一维数组。编译器不关心;我们只告诉他如何访问这个数组中的元素。
答案 1 :(得分:4)
N1570:
6.7.6.3函数声明符(包括原型)
...
7参数声明为'' type ''数组'应调整为''限定指针 type '',其中类型限定符(如果有)是在[
和]
内指定的类型限定符。 数组类型推导。如果关键字static
也出现在[
和]
内 数组类型派生,然后对每个函数调用,对应的值 实际参数应提供对至少具有至少数量的数组的第一个元素的访问 size表达式指定的元素。
因此,在函数参数声明的上下文中,T a[N]
和T a[]
都等同于T *a
;所有这三个都将a
声明为指向T
的指针。在这种特殊情况下,T
是“int
的10个元素数组”。
这与以下内容密切相关:
6.3.2.1左值,数组和函数指示符
...
3除非它是sizeof
运算符,_Alignof
运算符或运算符的操作数 一元&
运算符,或者是用于初始化数组的字符串文字,一个包含的表达式 类型'' type ''的数组被转换为类型为''指向 type ''指针的表达式 到数组对象的初始元素,而不是左值。如果数组对象有 注册存储类,行为未定义。
假设您有一个声明为
的数组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] )
是指向数组的指针,而不是2D数组。
答案 2 :(得分:0)
考虑定义int c[5][10]
然后将c
传递给例程时会发生什么。数组c
将自动转换为指向其第一个元素的指针,该元素是10 int
的数组。
因此,语言设计人员对其进行了排列,以便在您使用c[][10]
声明参数时,会自动调整该参数以匹配将要发生的转换。编译器将数组类型为int
的数组的参数更改为指向int
数组的类型指针的参数。