C 语言,碰到个很让人疑惑的问题

2018-12-04 17:15:04 +08:00
 xjr1022

//声明函数
void test(int a, int b);

int main() {
	int a = 2;
	test(a, a++);
	return 0;
}

void test(int x, int y) {

	printf("x=%d,y=%d", x, y);

}

//运行结果 
x=3,y=2

想请教一下这个是为什么呢,明明给形参 y 传递的是自增的量,怎么就 x 变成 3,而 y 还是 2,

3415 次点击
所在节点    C
45 条回复
kokutou
2018-12-04 17:46:20 +08:00
@xjr1022
那就只能看卷子上或考试说明上说的用啥编译器。
然后自己试试记下来就完事了。
xjr1022
2018-12-04 17:51:15 +08:00
@kokutou 没答案,而且卷子连操作系统,编译器版本 c 标准都没指定,估计默认就是谭浩强的那个编译环境了
misaka19000
2018-12-04 17:56:33 +08:00
用 gcc 取了下汇编,lea 指令那里看不太懂什么意思,有大佬能解释下吗

pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $2, -4(%rbp)
movl -4(%rbp), %eax
leal 1(%rax), %edx
movl %edx, -4(%rbp)
movl -4(%rbp), %edx
movl %eax, %esi
movl %edx, %edi
call test
movl $0, %eax
freedomSky
2018-12-04 17:57:51 +08:00
我想知道这是哪儿的考研题
kljsandjb
2018-12-04 17:58:18 +08:00
@misaka19000 #23 lea 实现运算功能,自增 1
misaka19000
2018-12-04 17:59:09 +08:00
eax 存的应该是 2,但是不知道 edx 是咋算出来的。。。
kljsandjb
2018-12-04 17:59:17 +08:00
@misaka19000 #23 然后 edi 相当于第一个参数为 3,esi 为第二个参数为 2,结果就是楼主的结果
kljsandjb
2018-12-04 18:00:12 +08:00
@misaka19000 #26 这个代码没优化,讲的啰嗦、其实 edx 就是 lea1(%rax)算的
misaka19000
2018-12-04 18:00:23 +08:00
@kljsandjb #25 但是不清楚 rax 的值是多少额,lea 能知道是针对哪一个值进行自增吗
kljsandjb
2018-12-04 18:01:31 +08:00
@misaka19000 #29 rax 不是赋值了吗,先从栈取出来给它的
kljsandjb
2018-12-04 18:02:02 +08:00
@misaka19000 #29 lea 可以做最基本的运算,其实跟地址什么的没什么关系
XIVN1987
2018-12-04 18:02:29 +08:00
TDMGCC:x=3,y=2
kljsandjb
2018-12-04 18:03:47 +08:00
@misaka19000 #29 https://i.loli.net/2018/12/04/5c0650f7e4dae.png 这三行我觉得说得很清楚了呀~
misaka19000
2018-12-04 18:10:49 +08:00
@kljsandjb #30 大佬能解释下这行做了什么操作吗

leal 1(%rax), %edx

从上下文看这个时候 rax 还没有值吧?
kljsandjb
2018-12-04 18:11:33 +08:00
@misaka19000 #34 eax 是 rax 的低 32 位
kljsandjb
2018-12-04 18:11:48 +08:00
@misaka19000 #34 movl 操作会把高位清零
misaka19000
2018-12-04 18:14:51 +08:00
@kljsandjb #36 原来是这样啊,蟹蟹大佬(^ᗜ^)
Kaiv2
2018-12-04 18:22:09 +08:00
看看汇编,就很清晰了
GAMEKON
2018-12-04 18:25:27 +08:00
多写一行能死啊
sbw
2018-12-04 18:32:48 +08:00
ub,取决于编译器实现。

lea 用于寄存器的时候可以实现简单的 乘 2,乘 4,乘 5,加 1 这种计算,比 add 快(不需要进入 ALU )。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/514267

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX