c - C 中的数组递增运算符

标签 c pointers post-increment

我不明白以下代码的结果:

#include <stdio.h>
#include <conio.h>
int main()
{
   int a[4]={1, 3, 5, 6};
   //suppose a is stored at location 2010
   printf("%d\n", a + 2);
   printf("%d", a++);
   return 0;
}

为什么第二个 printf 函数会产生以下错误?

错误:需要左值作为递增操作数

最佳答案

第 1 部分:

数组名是常量(不可修改的左值),您可以向数组名添加值但不能修改它。

表达式 a + 2 不会修改 a 本身,但是当您执行 a++ 时,它等同于 a = a + 1 尝试修改数组名——左值错误。第二个 printf 中的表达式 a++ 是错误的 - 语义阶段错误的一个例子。阅读以下语言标准:

6.3.2.1 Lvalues, arrays, and function designators

724 A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

729 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue.

第二部分:

注意大多数表达式中的数组名称在第一个元素的地址中衰减(阅读一些 exceptions where array name not decaying into a pointer to first element? @H2CO3 巧妙地回答)。

当您执行 a + 2 时,其结果是第三个元素的地址(或索引 2 处元素的地址)所以 a + 2&a[2] 相同 它是地址而不是索引处的值。

要打印地址,请使用 %p 而不是 %d 并将地址类型转换为 void*,如下所示:

printf("address (a + 2) = %p , &a[2] = %p", (void*)(a + 2), (void*)(&a[2]));

要打印值,您需要防御运算符 *,如下所示:

printf("address *(a + 2) = %d , a[2] = %d", *(a + 2), a[2]);   

第三部分:

suppose a is stored at location 2010, Is the output of first printf function 2012?

不,指针运算不同于整数运算。正如我们所知,在大多数表达式中,数组名称会衰减为第一个元素的地址。因此,当您执行 a + 2 时,该值是索引 2 处的第三个元素的地址。因此,假设如果系统中的 int 大小为 4 个字节,则根据您对 a 地址值为 2010 的假设,a + 2 stat 指向位置 2018。

要理解阅读10.2 Pointers and Arrays; Pointer ArithmeticPointer Arithmetic .

关于c - C 中的数组递增运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19130236/

相关文章:

c - C 中带有 AVR atmega8 的意外 float 行为

c - 为什么 -(-2147483648) = - 2147483648 在 32 位机器上?

C# 指针 Console.WriteLine 中的 X 表示什么?

c++ - 分配递增变量

java - Math.min() 中后递增运算符的有趣行为

microcontroller - C while 在数字范围之间循环

c - 从 main 之外的函数打印 double

c++ - 内存泄漏问题;删除指针

pointers - 通过 &str 获取指针

c - 结构指针上的前/后增量运算符