2.4.8 赋值运算

    由赋值运算符组成的表达式为赋值表达式,赋值运算符的结合性是由右至左的,因此,C++程序中允许出现连赋值的情况。


    int A,B,C,D,E; A=B=C=D=E=9;

    上述语句是合法的,整型变量A、B、C、D和E都被赋值为9。

    讨论到赋值运算,有必要提及程序实体和左值这两个概念,程序实体是内存中的一块可标识的区域,左值是左值表达式的简称,是指一个程序实体的表达式。判断一个表达式是否左值的方法是看其能否放在等号的左边。

    如“float a;”声明了一个浮点型变量a,则a是左值,因为其指明了一个程序实体,可放在赋值号的左边,但表达式“a+3”和“a=1”就不能放在赋值号的左边,不是左值。

    能放在赋值号左边的表达式都是左值,它指明了一块内存区域,而赋值运算实质上是改变了这一区域内容的操作。

    关于赋值运算需要注意以下3个问题。

    (1)赋值号两边的数据类型不一致时,编译器会在赋值前将右操作数转换成左操作数的类型。


    int numA; numA=1.25;

    上述语句声明了一个整型变量numA,并对其赋值1.25,1.25是个浮点型常量,因此,在赋值时,编译器会对0.25进行转换后再对numA赋值,赋值后numA的实际值为1。

    (2)声明语句使用的“=”符号,称为“初始化符”,与赋值运算符不同。


    int numA; numA=3;与 int numA=3;

    虽然效果相同,但本质不同,前者是声明一个变量numA,并对其进行赋值操作,而后者则是声明一个变量numA,并对其初始化为3。

    下面这个同时声明两个变量并初始化的语句是非法的。


    int numA=numB=9;但这并不是说不能用一个变量对另一个变量进行初始化。 int numB=1; int numA=numB=9;

    使用一个已经定义的变量对另一个变量初始化是没有问题的。

    (3)前面我们讲过符号常量,事实上,const也可以修饰变量,用const修饰的变量是左值,但不能放在赋值号的左边,只有能被修改的左值才可以放在赋值号的左边,换言之,只有当表达式指定的内存区域的值可以被程序修改时,表达式才可放在赋值号的左边。

    赋值运算符除了"="之外还有10个复合赋值运算符,这是赋值和运算相结合的运算符。举例来说,语句“x=x+y;”代表的意义是将x和y相加,结果放入变量x中,这可以简洁地表示为“x+=y;”,运算符“+=”既有加的功能,也有赋值的功能,其他一些类似的复合赋值运算符如表2.8所示。

    2.4.8 赋值运算 - 图1

    复合赋值运算符的结合性都是从右向左的,它们的优先级和简单的赋值运算符一样,同时,复合运算符是把右边的表达式作为一个整体来进行运算的,见代码2.13。

    代码2.13 复合赋值运算符的用法CompoundAssign


    <——————————文件名:example213.cpp————————————————-> 01 #include<iostream> 02 int main() 03 { 04 using namespace std; 05 int x=2,y=7;//声明两个int型变量x和y 06 x=y+3;//x=x(y+3) 07 cout<<"x*=y+3:"<<x<<endl;//输出 08 x=2,y=7;//恢复原始值 09 x=xy+3;//注意与"x=y+3;"对比 10 cout<<"x=x*y+3:"<<x<<endl;//输出 11 x=2,y=7; 12 x=x*(y+3); 13 cout<<"x=x*(y+3):"<<x<<endl; 14 return 0; 15 }

    【代码解析】代码6行使用了复合运算符,其相当于x=x*(y+3)。

    输出结果如下所示。


    x*=y+3:20 x=x*y+3:17 x=x*(y+3):20

    可见,“x=y+3”等价于“x=x(y+3)”,复合运算符右边的部分会当成一个整体来计算,这是因为复合赋值运算符的优先级比算术运算符低。