L作为增量运算符所需的值 - C.

时间:2016-08-16 15:26:09

标签: c lvalue

我刚从朋友那里得到了一个问题。

#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行的情况,情况并没有发生。

任何人都能明白这个疑问吗?

3 个答案:

答案 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值,可以递增。

这被称为“衰减到指针的数组”(正如评论中所指出的),是的,它可能令人困惑。