1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) { int i;
i = 0; printf("i++ = %d\n", i++); printf("i = %d\n", i);
i = 0; printf("++i = %d\n", ++i); printf("i = %d\n", i);
return 0; }
|
输出结果:
1 2 3 4
| i++ = 0 i = 1 ++i = 1 i = 1
|
不管是 i++ 还是 ++i 最终都会让 i 产生副作用,即都会使得 i 在原来的基础上 加 1。二者的区别在于 ++i
的值 代表 i+1,而 i++
的值 代表 i。即 ++i 会立即产生自增的效果,而 i++ 不会立即产生自增的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| i++ 对应的汇编代码
0042186C mov eax,dword ptr [i] ; 将变量 i 的值加载到 eax 寄存器中 0042186F mov dword ptr [ebp-0D0h],eax ; 将 eax 中的值(即 i 的当前值)存储到内存(临时变量) 00421875 mov ecx,dword ptr [i] ; 再次加载 i 的值到 ecx 寄存器 00421878 add ecx,1 ; 对 ecx 中的 i 进行递增操作 0042187B mov dword ptr [i],ecx ; 将递增后的值存储回 i 0042187E mov edx,dword ptr [ebp-0D0h] ; 将最初保存的 i 的值加载到 edx 00421884 push edx ; 将最初的 i 值压入堆栈,用于 printf 输出 00421885 push offset string "%lld\n" ; 压入字符串格式化参数 0042188A call _printf ; 调用 printf 函数 0042188F add esp,8 ; 调整堆栈指针
++i 对应的汇编代码
004218AA mov eax,dword ptr [i] ; 将变量 i 的值加载到 eax 寄存器中 004218AD add eax,1 ; 对 eax 中的 i 进行递增操作 004218B0 mov dword ptr [i],eax ; 将递增后的值存储回 i 004218B3 mov ecx,dword ptr [i] ; 再次加载递增后的 i 到 ecx 寄存器 004218B6 push ecx ; 将递增后的 i 值压入堆栈,用于 printf 输出 004218B7 push offset string "++i = %d\n" ; 压入字符串格式化参数 004218BC call _printf ; 调用 printf 函数 004218C1 add esp,8 ; 调整堆栈指针
|
解读:
从 ++i 的汇编代码可以看出是 先让 i 执行自增操作之后才打印 i 的值,所以打印结果为 1。
i++ 的汇编代码是把 i 最初的值转存到其他临时地址,并读取原始 i 的值进行自加后放到其他寄存器,然后再把之前存储到临时地址的 i 的数据用于输出,所以打印结果为 0。
总结:
i++
先使用 i
的原值,再递增。这就需要在递增之前保存 i
的原值,以便在后续操作中使用。
++i
先递增 i
,然后使用递增后的值。这个过程更简单,不需要保存原值,因为递增操作已经完成。