为什么在使用矩阵作为函数的参数时,我们必须指定列数,但是我们不必指示行数?
答案 0 :(得分:1)
我假设你在谈论像
这样的函数定义void foo( int matrix[][COLS] ) { ... }
这需要一点背景......
除非它是sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,表达式为类型“{元素数组T
”将被转换(“衰减”)为“指向T
的指针”类型的表达式,表达式的值将是第一个元素的地址数组。所以,鉴于声明
int arr[10];
表达式 arr
将具有类型“10-element array of int
”;除非此表达式是sizeof
或一元&
运算符的操作数,否则它将被转换(“衰减”)为“指向int
的指针”类型的表达式。所以如果我们将该数组传递给函数,比如
blurga( arr );
blurga
收到的是指向int
的指针,而不是int
的数组。因此,我们可以将blurga
定义为
void blurga( int *ap )
{
// do something with ap[i]
}
形式参数ap
的类型为“指向int
的指针”。请注意,您可以在指针表达式和数组表达式 1 上使用[]
运算符。
现在,在正式参数声明的上下文中,T a[N]
和T a[]
被解释为T *a
;所有这三个都将a
声明为T
的指针,而不是T
的数组。所以我们可以将该函数定义重写为
void blurga( int ap[] )
{
// do something with ap[i]
}
同样,int ap[]
的解释与int *ap
完全相同。
现在让我们看一下二维数组:
int blah[10][10];
表达式blah
的类型为“10元素数组int
的10元素数组”。按照上面的转换规则,表达式blah
将衰减为“指向10个元素数组int
”或int (*)[10]
的类型的表达式。因此,如果我们将blah
传递给函数,函数接收的是指向数组的指针,而不是数组数组:
void bletch( int (*barr)[10] );
之前T a[]
被解释为T *a
,因此我们可以将该声明写为
void blech( int barr[][10] ); // barr[] == (*bar)
请记住barr
是指针类型,而不是数组类型。
<小时/> 1。事实上,
a[i]
被定义为*(a + i)
的结果;给定指针值a
,我们从该地址偏移i
元素并取消引用结果。所以基本上,转换规则仍然适用;数组表达式a
正在转换为指针表达式,该指针表达式是[]
正在应用的表达式。