我刚从朋友那里得到了一个问题。
#include<stdio.h>
void fun(int[][3]);
int main(void){
int a[3][3]={1,2,3,4,5,6,7,8,9};
fun(a);
printf("\n%u",a);
a++;//Ques 1
printf("\n%u",a);
printf("%d",a[2][1]-a[1][2]);
return 0;
}
void fun(int a[][3]){
++a;//Ques 2
a[1][1]++;
}
“问题1”行会抛出L值的错误,因为&#39; a&#39;是二维数组的名称。但是,对于第2行的情况,情况并没有发生。
任何人都能明白这个疑问吗?
答案 0 :(得分:7)
在Ques 1中,a
是一个数组,当用作++
运算符的操作数并发出编译错误时,它将被转换为非左值指针。
在问题2中,参数int a[][3]
等同于int (*a)[3]
,++a
是指针变量的增量,这是可以接受的。
引自N1570 6.7.6.3函数声明符(包括原型),第7段:
参数声明为''数组类型''应调整为''限定指针 type'',其中类型限定符(如果有)是在[和]中指定的类型 数组类型推导。
答案 1 :(得分:2)
当一个数组作为函数参数传递时,它会衰减成指向数组第一个元素的指针。
任务1
a
是一个数组,是一个不可修改的左值。所以它不能递增。
任务2
传递的参数int a[][3]
。这会衰减成指向第一个元素的指针,即int (*)[3]
(和不 int *
,这与普遍看法相反)。指针可以递增,因此可行。
此外,您应该使用%p
作为printf
中的指针,而不是%u
。
答案 2 :(得分:0)
好的,首先,“L值”表示您可以分配的内容。 a
是数组的名称。那么该行尝试做的就像你在数组本身上做a = a + 1
一样,这是没有意义的。
现在,你在这里遇到的是C有一种处理数组的方式有点令人困惑:它们实际上只是无法区分的内存块,它们的名称是数组开头地址的有限别名。当你传递一个数组时,C实际传递的是数组的地址(或者在这种情况下,是数组内存中特定点的地址。)所以在Ques 2中,那实际上是一个指针,是一个L值,可以递增。
这被称为“衰减到指针的数组”(正如评论中所指出的),是的,它可能令人困惑。