每一次看到++和–运算符都很迷,一直以为自己已经懂了,但当看到下面这道题时,我人傻了…
int a = 1;
int i = ++a + ++a + ++a;
这道题的答案是多少呐?
你可能会说:3,可能会说:9,还可能会说:6…
那么,到底哪个正确呐,是不是很迷,那么我要告诉你,这都可能正确,原因是什么,咱们待会说,现在,先来介绍一下++和–运算符,稍后我们来对这个问题做出回答。
介绍
++和–操作符,可以说是C语言中最常见的操作符之一了,但要说哪种操作符最能捕捉到C语言的感觉,毫无疑问就是这两个操作符,而这两种操作符都有两种形式:前缀和后缀。
- 前缀:即操作符位于变量的前面,如 int a = 1; int b = ++a,操作数的值被增加,而表达式的值就是操作数增加后的值,更简明的来说,b = 2, a = 2;
- 后缀:即操作符位于变量的后面, 如 int a = 1; int b = a++,操作数的值仍然被增加,而表达式的值却是操作数增加前的值,更简明的来说,b = 1, a = 2;
听很多人说过 a++ 操作符是自身先实现一次拷贝,但这里要纠正的是,其实无论是++还是–都是变量自身实现一次拷贝 , 即操作的结果是变量的一份拷贝,而不是变量本身, 所以就无法实现这类操作:
++a = 10;
在了解了这两个运算符最基本的操作后,你有没有想过这样的问题呐?
#include<stdio.h>
int main(void)
{
int arr[6] = {1, 2, 3, 4, 5, 6};
int * p = arr;
printf("*++p = %d, *p++ = %d", *++p, *p++);
}
想一想打印出的结果是多少呐?
其中*++p打印出来的结果是2, *p++打印出来的结果是1。
经常在看书时看到这样一个词:副作用,其实,副作用就是通过操作符会对原来的变量造成影响,即++a就会改变a的值,而有副作用的操作符:++, --, =;
解答
现在,了解了++和–操作符后,我们来回答以下最开始问题:
我们知道的是,表达式的优先级并非完全由操作符的优先级决定,还要有操作符的结合性决定, 如(),但你有没有想过如果是这样一个表达式 int a = b + ++c, 我们并没有办法得知左操作符是在右值操作符之前还是之后执行的,这就是问题产生的原因。
标准说明类似这类表达式的值是未定义的。尽管每个编译器都会为这种表达式产生某个值,但到底式是哪个值正确·并无标准答案,因此,像这样的表达式不可移植,应尽量避免
int a = 1;
int i = ++a + ++a + ++a;
在VS2019上, i 的值为12, 在Codeblocks 上, i 的值为10.