【问题标题】:Increment a vector adress and assign it to a pointer增加一个向量地址并将其分配给一个指针
【发布时间】:2013-09-13 15:20:58
【问题描述】:

为什么我不能p=numbers++p=++numbers?编译器显示消息:“需要左值作为增量操作数”但指针 p 不是左值吗?

int main(int argc, char *argv[]){
    int numbers[] = {1,2,3,4,5,6}, *p;
    p=numbers++;
    printf("%d ",*p);
    return 0;
}

【问题讨论】:

标签: c arrays pointers increment


【解决方案1】:

numbers++ 等价于numbers = numbers + 1

但是numbers这里是一个数组,不能修改数组的地址。

左值并不意味着“左值”

【讨论】:

    【解决方案2】:

    numbers不是 指针。它是一个具有此定义int numbers[] = {1,2,3,4,5,6} 和一个右值的数组。所以the compiler shows the message: "lvalue required as increment operand"

    数组和指针的区别。 Pointers - Difference between Array and Pointer

    【讨论】:

      【解决方案3】:

      首先我建议您阅读Arrays and Pointers 上的C FAQ 部分,它是更好的通用参考资料之一。

      为了直接解决您的错误,如果我们查看 C99 标准草案,我们会在 6.5.2.4 部分中看到 后缀递增和递减运算符6.5.3.1 前缀递增和递减运算符第1段中说:

      前缀递增或递减运算符的操作数应有限定或 不合格的实数或指针类型,应为可修改的左值

      6.3.2.1 部分左值、数组和函数指示符第 3 段 说:

      除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是 用于初始化数组的字符串字面量,具有 type ''array of type'' 的表达式将转换为类型为 ''pointer to type'' 的表达式,该表达式指向数组的初始元素对象并且不是左值。 [...]

      第1段说:

      [...] 可修改的左值是没有数组类型的左值,[...]

      因此,即使在许多情况下数组会衰减为指向第一个元素的指针,它也不是lvalue

      【讨论】:

        【解决方案4】:

        当您声明和定义一个数组时,数组的名称是一个表达式,计算结果为数组第一个元素的地址。将名称视为保存第一个元素地址的常量。

        一旦为数组分配了内存,就不能更改数组的地址。因此,数组标识符(名称)的值也不能更改。

        在你的代码中,当你有

        p = numbers++;
        

        您要求 numbers 增加数组第一个元素的地址的常量值并指向第二个元素。这不是合法的操作。递增操作数需要modifiable lvalue,而数组的名称不是modifiable lvalue

        什么是lvalue?它是locator value:标识可以保存另一个值的内存区域的东西。所以当你声明:

        int a = 5;
        

        a 表示一个足以容纳int 的内存区域,而该内存区域中的int5。您可以通过分配更改 int

        a = 7;
        

        但标识符a 仍然表示相同的内存区域。这意味着amodifiable lvalue

        当你声明和定义你的数组时:

        int numbers[] = { 1, 2, 3, 4, 5, 6 };
        

        numbers 是一个lvalue,因为它指定了一个存储指定整数数组的内存区域,但它不是modifiable。您可以更改numbers 中元素的值,但不能更改numbers 本身的值。 numbers 始终计算为 &numbers[0]

        如果您想更改p 指向的位置,使其指向第二个元素而不是第一个元素,请使用:

        p = numbers + 1;
        

        这不会改变numbers 本身的值,只会改变p 的值。 numbers 仍然是 &numbers[0]p 将是 &numbers[1]

        希望这很清楚!

        【讨论】:

          猜你喜欢
          • 2011-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-19
          相关资源
          最近更新 更多