您的位置:首页 > 编程语言 > C语言/C++

关于C语言中的复合赋值操作符

2011-12-01 22:14 232 查看
复合赋值操作符有 +=, -=, *=, /=,%=, <<=, >>=, &=, ^=, |=。

下面以+=为例

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 赋值操作符