赋值运算符(Assignment Operators) o Simple assignment:store a value into a variable o Compound assignment:update a value already stored in a variable o The effect of the assignment v e is to evaluate the expression e and copy its value into v.e can be a constant,a variable,or a more complicated expres- sion oi=5;//iis now 5 ●j=i;j is now5 ok=10*i+j:∥k is now55 1口140,1于,1至20Q0 16/67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 赋值运算符 (Assignment Operators) Simple assignment: store a value into a variable Compound assignment: update a value already stored in a variable The effect of the assignment v = e is to evaluate the expression e and copy its value into v. e can be a constant, a variable, or a more complicated expression i = 5; // i is now 5 j = i; // j is now 5 k = 10 ∗ i + j; // k is now 55 16 / 67
赋值运算符示例 ●在赋值语句V=e中,如果V和e的数据类型不同,则在 赋值操作发生时e的类型被转换为V的数据类型 int i; float f; i=72.99f; /i is now 72 f=136; /f is now 136.0 。在其它许多语言中,赋值都视为statement,在C中,赋 值是个运算符,就像+一样 ●赋值操作v=e作为一个整体,其本身的值(value)是v赋 值后的值,比如上面ⅰ=72.99f的值是72而不是72.99 17/67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 赋值运算符示例 在赋值语句 v = e 中,如果 v 和 e 的数据类型不同,则在 赋值操作发生时 e 的类型被转换为 v 的数据类型 in t i ; fl o a t f ; i = 72.99 f ; / / i i s now 72 f = 136; / / f i s now 136.0 在其它许多语言中,赋值都视为 statement,在 C 中,赋 值是个运算符,就像 + 一样 赋值操作 v = e 作为一个整体,其本身的值 (value) 是 v 赋 值后的值,比如上面 i = 72.99f 的值是 72 而不是 72.99 17 / 67
运算符的副作用(Side Effects) ●如果一个运算符会修改它的某个操作数,就称其为有副作用 ●赋值运算符=的副作用是修改左操作数的值 ·对表达式ⅰ=0求值产生一个结果0,同时副作用将0赋值 给i 由于赋值是一个操作符,多个赋值操作可以串联起来: i=j=k=0; =具有右结合性,所以上述赋值等价于: i=0=(k=0): 18/67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 运算符的副作用 (Side Effects) 如果一个运算符会修改它的某个操作数,就称其为有副作用 赋值运算符 = 的副作用是修改左操作数的值 对表达式 i = 0 求值产生一个结果 0,同时副作用将 0 赋值 给 i 由于赋值是一个操作符,多个赋值操作可以串联起来: i = j = k = 0; = 具有右结合性,所以上述赋值等价于: i = (j = (k = 0)); 18 / 67
运算符的副作用示例 ●串联赋值操作可能由于类型转化的原因产生非预期的结果,比如在下 列操作中,ⅰ首先被赋值为33,接着f被赋值为33.0而不是33.3 int i; float f; f=i=33.3f; ●赋值操作V=e可以出现在任何与V同类型值允许出现的地方 i=1; k=1+(j=i); /prints "11 2" printf("%d %d %dIn",i,j,k) ●类似于第二行程序的嵌入式赋值操作会使得程序很难理解,也是某些 诡异bug的重要来源 19/67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 运算符的副作用示例 串联赋值操作可能由于类型转化的原因产生非预期的结果,比如在下 列操作中,i 首先被赋值为 33,接着 f 被赋值为 33.0 而不是 33.3 in t i ; fl o a t f ; f = i = 33.3 f ; 赋值操作 v = e 可以出现在任何与 v 同类型值允许出现的地方 i = 1; k = 1 + ( j = i ) ; / / p rin t s "1 1 2" p ri n t f ( "%d %d %d\n" , i , j , k ) ; 类似于第二行程序的嵌入式赋值操作会使得程序很难理解,也是某些 诡异 bug 的重要来源 19 / 67
左值(Lvalues) ●赋值操作需要其左操作数是一个左值(Ivalue) 。一个左值表示存储在计算机内存中的一个具体可改写的对 象,而不是一个常数或某个计算的临时结果 。变量是左值,表达式比如10或者2*i则不是 由于赋值操作要求左操作数是左值,因此任何其它类型作为左操 作数都是不合法的,比如: 12=i;/**NRONG**/ i+j=0;/**WRONG ** -i j;/***WRONG *** 编译器会产生类似"invalid Ivalue in assignment.."之类的错 误信息 20/67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 左值 (Lvalues) 赋值操作需要其左操作数是一个左值 (lvalue) 一个左值表示存储在计算机内存中的一个具体可改写的对 象,而不是一个常数或某个计算的临时结果 变量是左值,表达式比如 10 或者 2 ∗ 则不是 由于赋值操作要求左操作数是左值,因此任何其它类型作为左操 作数都是不合法的,比如: 12 = i; /*** WRONG ***/ i + j = 0; /*** WRONG ***/ -i = j; /*** WRONG ***/ 编译器会产生类似 “invalid lvalue in assignment." 之类的错 误信息 20 / 67