表达式(六)
4、后缀自增运算符和后缀自减运算符
后缀自增表达式的语法格式如下所示:
postfix-expression ++
其中postfix-expression是后缀表达式,其类型为原子的、限定的或者非限定的实数类型或者指针类型,并且应为可修改左值(modifiable lvalue);++是自增运算符。后缀自增运算符的运算结果是操作数(后缀表达式)的原先值。作为副作用,操作数的值会增加1。
int i = 3; printf("%d\n", i++); //输出3。 printf("%d\n", i); //输出4。
上面的例子也说明了后缀自增运算符运算结果的值计算在更新操作数存储值的副作用之前。
对于不确定顺序的函数调用,后缀自增运算符的操作是一次独立评估;因此函数调用不干预左值到右值的转换(lvalue-to-rvalue conversion)以及任何与后缀自增运算符相关的副作用。
int func(int i) { return i; } ... int i = 3; int j = 1; int sum = 0; sum = func(i++) + func(i++); //合法,两次i++的评估是独立的。 printf("sum = %d\n", sum); //输出sum = 7。 printf("i = %d\n", i); //输出i = 5。 sum = j++ + j++; //非法,未定义行为。
上述两次函数调用中,每次i++的评估都是独立的,这样确保了逻辑的完整性。
原子类型对象的后缀自增操作是读-修改-写操作(read-modify-write operation),具有顺序一致(memory_order_seq_cst)的内存顺序语义。
atomic_int aNumber = 0;
aNumber++;
上述代码等价于
atomic_int aNumber = 0; int before = aNumber; int after = 0; do { after = before + 1; }while(!atomic_compare_exchange_strong(&aNumber, &before, after));
后缀自减表达式的语法格式如下所示:
postfix-expression --
后缀自减运算符与后缀自增运算符相似;区别在于后缀自减运算符的副作用是操作数值减少1。