今天看书见到如下代码:
int a=2;
++a++;
根据操作符的优先级和结合性知,操作符++的优先级为3,结合性为右结合,即++a++;可以理解为++(a++);
但我把代码放在vs2015上,结果报错,如图:
意思就是所a++不能作为左值,那a++为什么不能作为左值呢?我们先来看左值的定义:
左值(lvalue) 是B语言/C语言/C++语言等类C语言中的一类表达式。“左”(left)的原意是指可以放在赋值符号“=”的左边,但其实也表示能作为&和++等操作符的操作数(B语言中已经如此)。左值不但具有空间实体,还具有读写访问权。
现在我们来看a++的实现:
int temp;
temp=a;
a=a+1;
return temp;
因为a++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通过地址对它进行操作.(换句话说就是不能作为左值)。
而++a的实现为:
a=a+1;
return a;
因为++a返回的是a,它是程序中定义的可寻址变量的引用,所以它可以作为左值。
附加:++与--是连体操作符,中间不能有空格。如果有多于两个的+或-连写,则编译器按“贪吃法则”理解。所谓贪吃,是指只要能理解(能成为操作符),就尽量多读入字符。例如:
(1)int a=1, b=5, c;
(2)c = a + b; //ok
(3)c = a ++ b; //错:a++和b两个表达式,缺乏相运算的操作符
(4)c = a +++ b; //ok:a++ +b;
(5)c = a ++++ b; //错:a++和++b两个表达式,缺乏相运算的操作符
(6)c = a +++++ b; //错:a++ ++ +b,a++非左值,不能++
根据“贪吃法则”,上面第3行,编译器不会理解成a + +b;同样第5行也不会理解成a++ + +b;以及第6行也不会理解成a++ + ++b;编译器对表达式的理解是没有二义性的。如果要使上面的非法代码可行,只能通过书写格式人为控制表达式的意义,如下代码:
using namespace std;
int a = 1, b = 5, c;
c = a + +b;
cout << c << endl;
c = a++ +b;
cout << c << endl;
c = a++ + +b;
cout << c << endl;
c = a+ ++++b;
cout << c << endl;
}