关于C语言中的复合赋值操作符
2011-12-01 22:14
232 查看
复合赋值操作符有 +=, -=, *=, /=,%=, <<=, >>=, &=, ^=, |=。
下面以+=为例
a += expression (1)
等价于:
a = a + expression (2)
但是,这里是有区别的,(1)式中的a(如数组下标访问的元素)只求值一次,(2)式中的a求值两次,当然编译器也许会优化,可能会使得(2)式效果和(1)式一样,但是有例外的情况,编译器是无法优化的。如:
以上两个表达式机器代码是完全不同的,对于(2)式,由于是调用函数,编译器并不能确定每次函数都返回相同的值(即是否有副作用),所以编译器对此无能为力,不能对此优化,因此也就会去乖乖地调用两次函数,而(1)式只调用一次函数,参见VS2010下的汇编代码:
因此,如果我们能确定表达式中不含有副作用的元素(如上面的函数f),那么我们应尽量使用复合赋值操作符,不失效率同时书写方便。
下面以+=为例
a += expression (1)
等价于:
a = a + expression (2)
但是,这里是有区别的,(1)式中的a(如数组下标访问的元素)只求值一次,(2)式中的a求值两次,当然编译器也许会优化,可能会使得(2)式效果和(1)式一样,但是有例外的情况,编译器是无法优化的。如:
int f(int x){return x;} int a[10] = {0}; int x = 2; a[f(x) + 1] += 1; // (1) a[f(x) + 1] = a[f(x) +1] +1; // (2)
以上两个表达式机器代码是完全不同的,对于(2)式,由于是调用函数,编译器并不能确定每次函数都返回相同的值(即是否有副作用),所以编译器对此无能为力,不能对此优化,因此也就会去乖乖地调用两次函数,而(1)式只调用一次函数,参见VS2010下的汇编代码:
a[f(x) + 1] = a[f(x) +1] +2; 013B1413 mov eax,dword ptr [ebp-3Ch] 013B1416 push eax 013B1417 call @ILT+110(_f) (13B1073h) 013B141C add esp,4 013B141F mov esi,dword ptr [ebp+eax*4-2Ch] 013B1423 add esi,2 013B1426 mov ecx,dword ptr [ebp-3Ch] 013B1429 push ecx 013B142A call @ILT+110(_f) (13B1073h) 013B142F add esp,4 013B1432 mov dword ptr [ebp+eax*4-2Ch],esi a[f(x) + 1] += 2; 013B1436 mov eax,dword ptr [ebp-3Ch] 013B1439 push eax 013B143A call @ILT+110(_f) (13B1073h) 013B143F add esp,4 013B1442 lea ecx,[ebp+eax*4-2Ch] 013B1446 mov dword ptr [ebp-104h],ecx 013B144C mov edx,dword ptr [ebp-104h] 013B1452 mov eax,dword ptr [edx] 013B1454 add eax,2 013B1457 mov ecx,dword ptr [ebp-104h] 013B145D mov dword ptr [ecx],eax
因此,如果我们能确定表达式中不含有副作用的元素(如上面的函数f),那么我们应尽量使用复合赋值操作符,不失效率同时书写方便。
相关文章推荐
- C语言之赋值操作符和表达式
- 关于C语言结构体的赋值(复制)问题
- 关于给Size point Location 这些复合属性 赋值
- 关于我们C语言的操作符。。
- 关于基本类型的简单赋值和复合赋值运算
- 关于"&"操作符在变量赋值时的使用
- 关于为什么要为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
- Effective c++(笔记) 中关于构造函数、析构函数以及赋值操作符的知识
- C语言关于结构体赋值的问题
- 关于c语言中变量赋值问题
- 警惕复合赋值操作符
- C++前置式后置式递增和复合赋值操作符对程序性能
- 关于c语言中变量赋值问题
- 小小的C语言问题指针数组赋值----关于指针和数组。
- 关于C语言相关操作符的个人剖析
- 关于c语言的赋值和memcpy的问题
- [C语言]流程控制, 复合赋值, 优先级, 循环控制
- VC#2005快速入门之复合赋值操作符
- 关于C语言的操作符
- 关于拷贝构造函数和重载赋值操作符