C语言:执行 i++ 和 ++i 时CPU在做什么? int a = i++ 违反操作符优先级了吗?【视频解析】

!!!喜欢看视频的朋友请直接点这里!!!

一、执行i++++i时CPU在做什么

1.1 i++C代码示例

#include <stdio.h>
int main() {
    int i = 0;
    i++;
    printf("%d\n", i);
    return 0;
}

第4行i++对应的汇编代码如下:

add    DWORD PTR [rbp-0x4],0x1   // 把内存单元[rbp-0x4]里面的值加1

1.2 i++C代码示例

++iC代码示例:

#include <stdio.h>
int main() {
    int i = 0;
    ++i;
    printf("%d\n", i);
    return 0;
}

第4行++i对应的汇编代码如下:

add    DWORD PTR [rbp-0x4],0x1   // 把内存单元[rbp-0x4]里面的值加1

1.3 结论

是的,你没有看错,i++++i对应的汇编代码是一模一样的。
也就是说,对于单独的一行C代码i++;++i;对CPU来说没有任何区别。


二、int a = i++违反操作符优先级了吗?

C代码如下:

#include <stdio.h>
int main() {
    int i = 0;
    int a = i++;
    printf("%d %d\n", a, i);
    return 0;
}

这是初学者必学的知识点,打印的结果是0 1
这里的问题是:操作符++的优先级高于=int a = i++;就等于int a = (i++);,因此会先计算(i++)的值,i变成了1,再执行=运算,所以理论上a的值也应该是1才对,那为什么实际结果却是0呢?

《C程序设计语言》中是这么描述的:

表达式 ++n 先将 n 的值递增1,然后再使用变量 n 的值,而表达式 n++ 则是先使用变量 n 的值,然后再将 n 的值递增1。

注意了,这本书是C语言发明人合作编写的,上面这句话就是真理。
所以int a = i++违反操作符优先级了吗?没有。因为C语言语法的优先级高于操作符优先级
即,从语法上已经规定了int a = i++;从C语言的角度等价于以下两行代码(从汇编角度不是这样的):

int a = i;
i++;

int a = ++i;从C语言的角度等价于以下两行代码(从汇编角度也是这样的):

i++;
int a = i;

三、执行int a = i++int a = ++i时CPU在做什么?

3.1 执行int a = i++时CPU在做什么

执行int a = i++时的汇编代码如下(看注释):

mov eax,DWORD PTR [rbp-0x8]  // 把[rbp-0x8]内存单元中的值(即0)存入eax寄存器
							 // 注:eax是rax寄存器的低32位
							 // 执行完这行指令之后,eax和rax的值都是0
lea edx,[rax+0x1]            // edx = 1
mov DWORD PTR [rbp-0x8],edx  // [rbp-0x8] = 1,即 i = 1
mov DWORD PTR [rbp-0x4],eax  // [rbp-0x4] = 0,即 a = 0

可以看出,从汇编的角度来说,C语言int a = i++;等价于以下三行代码:

int temp = i; // 先把 0 存起来(汇编代码第1行)
i++;          // 再执行自增 (汇编代码第4和第5行)
a = temp;     // 再给a赋值 (汇编代码第6行)

3.2 执行int a = ++i时CPU在做什么

执行int a = ++i时的汇编代码如下(看注释):
TODO

add DWORD PTR [rbp-0x8],0x1  // 把[rbp-0x8]内存单元中的值(即0)加1(从0变成1)
mov eax,DWORD PTR [rbp-0x8]  // 把[rbp-0x8]内存单元中的值(即1)存入eax寄存器
mov DWORD PTR [rbp-0x4],eax  // [rbp-0x4] = 1,即 a = 1

第1行执行了i++,第2和第3行执行了a = 1


3.3 结论

int a = i++int a = ++i多了一条汇编指令。

在执行int a = i++时,出现了三个值:变量a的值、变量i的值、表达式i++的值。变量i的值从0变成了1,但是表达式i++的值还是0,所以最终a的值是0

在执行int a = ++i时,出现了三个值:变量a的值、变量i的值、表达式++i的值。变量i的值从0变成了1,表达式++i的值也从0变成了1,所以最终a的值是1


全文完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值