编程C开发人员

描述C语言中后缀增量(i++)和前缀增量(++i)之间的区别。它们的语义是什么,以及在复杂表达式中使用哪种变体是不安全的?

用 Hintsage AI 助手通过面试

答案

在C语言中,后缀增量(i++)和前缀增量(++i)操作将变量的值增加1,但返回值不同:

  • i++(后缀):首先返回当前值,然后增加它。
  • ++i(前缀):首先增加值,然后返回新值。

示例:

int i = 5; int a = i++; // a == 5, i == 6 int j = 5; int b = ++j; // b == 6, j == 6

在简单表达式中,差异没有多大,但在复杂表达式中(例如,多个增量一起)可能会导致未定义行为。

陷阱问题

执行表达式int a = i++ + ++i;后,若i = 1,变量a的值将是什么?

答案:

计算依赖于操作数计算的顺序,标准不保证这一点,并且导致未定义行为,因为变量i在连续使用值之间被修改了多次。这样写是不可以的!

这种代码的示例:

int i = 1; int a = i++ + ++i; // 未定义行为!请不要这样使用!

因不熟悉该主题而导致的实际错误示例


故事

在一个大型项目中,数组中的索引计算写成arr[i++] = getValue(++i);——开发人员想保留旧值,同时获取新值。在不同的编译器上行为不同:有时候一个值会覆盖另一个值,有时候程序崩溃。原因是在一个表达式中对i的多次修改是不允许的。


故事

在嵌入式项目中,计数器的值作为复杂表达式的一部分递增:if (buffer[i++] == TERMINATOR && ++i < SIZE) ...——在“硬件”上,由于计算顺序的不同,时常会得到错误的索引,导致读取未初始化的数据。


故事

在将代码移植到另一种编译器时,操作数计算顺序的实现差异导致while (arr[i++] && i < MAX && arr[++i])这样的循环表现得不可预测。此bug仅在客户端设备的测试阶段结果中被发现。