关于C语言中的复合赋值操作符
来源:互联网 发布:晨曦软件 编辑:程序博客网 时间:2024/04/30 11:38
复合赋值操作符有 +=, -=, *=, /=,%=, <<=, >>=, &=, ^=, |=。
下面以+=为例
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语言中的复合数据类型
- 第七节swift 复合赋值操作符
- 关于C语言中的移位操作
- 关于C语言中的文件操作
- 复合赋值操作符(操作符重载)
- 关于C语言操作符
- 关于c语言操作符
- c语言中的操作符
- C语言中的操作符
- C语言中的操作符
- C语言中的操作符
- 复合赋值运算符
- 《C语言解惑》之 谜题1.2 赋值操作符
- C语言之赋值操作符和表达式
- 复合赋值操作符和简单赋值操作符的区别。
- C语言赋值语句是不是原子操作?
- javascript继承相关的函数
- access中sql语句执行错误 “标准表达式中数据类型不匹配”
- U-Boot启动过程完全分析
- aix日常使用问题总汇
- vim scope 用法
- 关于C语言中的复合赋值操作符
- Linux内核简介
- C++虚析构函数
- Nginx源码分析--master进程
- uva 113 Power of Cryptography
- utf gb 等区别
- 说不尽的string字符串
- static 类成员
- Oracle:启动 Database Control 时出错