前置和后置运算符

这是迅雷一问一答的题目:

#include <stdio.h>

int main(void) {
  int a, b;

  a = 5;
  a = a + a++;
  printf("a = %d\n", a);

  a = 5;
  b = a + a++;
  printf("b = %d\n", b);
  return 0;
}

输出的结果是:


反汇编过程:

PUBLIC	_main
EXTRN	_printf:NEAR
_DATA	SEGMENT
$SG529	DB	'a = %d', 0aH, 00H
$SG530	DB	'b = %d', 0aH, 00H
_DATA	ENDS
_TEXT	SEGMENT
_a$ = -4
_b$ = -8
_main	PROC NEAR

; 3    : int main(void) {

	push	ebp
	mov	ebp, esp
	sub	esp, 8

; 4    :   int a, b;
; 5    : 
; 6    :   a = 5;

	mov	DWORD PTR _a$[ebp], 5	              ; 赋值,a = 5

; 7    :   a = a + (a++);

	mov	eax, DWORD PTR _a$[ebp]
	add	eax, DWORD PTR _a$[ebp]	              ; a += a(a = 10)
	mov	DWORD PTR _a$[ebp], eax
	mov	ecx, DWORD PTR _a$[ebp]
	add	ecx, 1			              ; a++,a = 11
	mov	DWORD PTR _a$[ebp], ecx  

; 8    :   printf("a = %d\n", a);

	mov	edx, DWORD PTR _a$[ebp]
	push	edx
	push	OFFSET FLAT:$SG529
	call	_printf
	add	esp, 8

; 9    : 
; 10   :   a = 5;

	mov	DWORD PTR _a$[ebp], 5

; 11   :   b = a + (a++);

	mov	eax, DWORD PTR _a$[ebp]
	add	eax, DWORD PTR _a$[ebp]	               ; a += a(a = 10,b = 10)
	mov	DWORD PTR _b$[ebp], eax
	mov	ecx, DWORD PTR _a$[ebp]
	add	ecx, 1			               ; a++,a = 11,b不变
	mov	DWORD PTR _a$[ebp], ecx

; 12   :   printf("b = %d\n", b);

	mov	edx, DWORD PTR _b$[ebp]
	push	edx
	push	OFFSET FLAT:$SG530
	call	_printf
	add	esp, 8

; 13   :   return 0;

	xor	eax, eax

; 14   : }

	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END

首先有一点必须要明确的是:表达式的运算顺序是从左到右的

1. 对于 a = a + a++; 运算过程是:a = 5 + 5 = 10,然后 a 再自加

2. 对于 b = a + a++; 运算过程是:b = 5 + 5 = 10,然后 a 再自加


再看一个稍微复杂点的程序:

#include <stdio.h>

int main(void) {
  int a, b;

  a = 5;
  a = a++ + a++;
  printf("a = %d\n", a);

  a = 5;
  b = (++a) + (a++) + (a++) + (++a) + (++a) + (a--);
  printf("a = %d\n", a);
  printf("b = %d\n", b);
  return 0;
}

运算结果是:


不贴ASM代码了

-----------------------------------

首先有一点必须要明确的是:表达式的运算顺序是从左到右的

语句 a = a++ + a++; 的执行过程是:

1. 第一个 a++ 的结果是5,第二个 a++ 的结果也是5

2. 此时表达式的结果是 a = 5 + 5 = 10,然后 a 再执行 2 个自加


语句 b = (++a) + (a++) + (a++) + (++a) + (++a) + (a--); 的执行过程是:

1. 第一个 ++a 的结果是6

2. 两个 a++ 的结果都是6

3. 前一个 ++a 的结果是7,后一个 ++a 的结果是8

4. a-- 的结果是8


最后表达式的结果是 b = 6+6+6+7+8+8 = 41,接下来就是更新 a 的值了,a一共有2次后置自加,1次后置自减,所以a = a + 2 -1 = 9(因为前置运算在表达式运算时已经运算过,而到表达式运算结束时a的值是8)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值