一亩三分地论坛

 找回密码
 获取更多干货,去instant注册!

扫码关注一亩三分地公众号
查看: 937|回复: 14
收起左侧

Bloomberg 今日店面一道诡异的C++基础题,求解答!

[复制链接] |试试Instant~ |关注本帖
zhenggao1986 发表于 2014-9-4 12:37:03 | 显示全部楼层 |阅读模式

2014(10-12月) 码农类 博士 全职@Bloomberg - 猎头 - 技术电面 |Other

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看,没有帐号?获取更多干货,去instant注册!

x
void foo(int a, int b) {
        cout << a << " " << b << endl;
}

int main() {. From 1point 3acres bbs
        int i = 0;
        foo(++i, i++);
        return 0;. 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴
}. visit 1point3acres.com for more.

求程序输出结果?

我觉得输出是 1 和 0. 1point 3acres 璁哄潧
估计面试官也没实际跑过这个,她竟然没觉得不对。
但是我心虚啊,事后我回来在机器上跑了一下,linux和windows的编译结果都是 2 和 0
谁来解释一下这个2是怎么冒出来的?

另外我试验了下面的程序,前两个输出符合预期。
void bar(int a) {
        cout << a << endl;
}. 1point 3acres 璁哄潧
void foo(int a, int b) {. visit 1point3acres.com for more.
        cout << a << " " << b << endl;
}. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
int main() {. more info on 1point3acres.com
        int i = 0 , j = 0, k = 0;
        bar(++i);                            //   1
        bar(j++);                           //    0
        foo(++k, k++);                 //    2  0
        return 0;
}.鏈枃鍘熷垱鑷1point3acres璁哄潧



补充内容 (2014-9-4 12:50):

Java 上结果不同
public class test {
    public static void foo(int a, int b) {
        System.out.println(a + " " + b);
. from: 1point3acres.com/bbs     }
    public static void main(String[] args) {
        int i = 0;
      ...

补充内容 (2014-9-4 12:51): 鏉ユ簮涓浜.涓夊垎鍦拌鍧.
        foo(++i, i++);     // 1 1
    }
}
temperlancer 发表于 2014-9-6 05:21:30 | 显示全部楼层
C++的函数是从右向左push argument, 当然, 当argument是表达式的时候, C++会先evaluate表达式. 所以,
--1. i++被执行, 0被push到stack, i变成1
--2. ++i被执行, i变成2, 然后被push到stack上
--3. 执行foo
所以输出时2, 0
回复 支持 1 反对 0

使用道具 举报

ototsuyume 发表于 2014-9-4 14:40:31 | 显示全部楼层
假如面试官是期望答题者能答出2 0的话那面试官得多没水平。这个代码运行的结果跟编译器的实现有关,有些编译器把参数从右到左压栈,有些编译器会直接用寄存器传参,得出的值都会不一样。比如我在自己的机器上跑,clang得出的结果就是1 1,而gcc是2 0

所以正确的答案是输出的结果依赖于编译器的实现,这种行为是在标准里没有定义的行为,实际开发中不应该使用
. 1point3acres.com/bbs
补充内容 (2014-9-4 14:43):
谭浩强那本书就有道题是问printf("%d %d %d\n",i++,++i,i++)之类的,都已经被人喷了不知道多少年了

评分

1

查看全部评分

回复 支持 1 反对 0

使用道具 举报

Linzertorte 发表于 2014-9-4 14:26:18 | 显示全部楼层
Even though the evaluation order is termed 'unspecified' in C99 and also in C++ documentation as evident from other comments, but, from a a practical point of view, both the gcc compiler for C programs and g++ compiler for C++ programs seems to evaluate it from right to left order.. 鍥磋鎴戜滑@1point 3 acres

The following code in C gave output 3 3 1:

int i=1;
printf("%d %d %d", i, ++i, i++);
while the C++ code also gave the same output 331.1point3acres缃
. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
int i=1; 鏉ユ簮涓浜.涓夊垎鍦拌鍧.
cout<<i<<++i<<i++;
鏉ユ簮涓浜.涓夊垎鍦拌鍧. So i think it's evident that most compilers follow right-to-left evaluation order. 鏉ユ簮涓浜.涓夊垎鍦拌鍧.

P.S. The above codes were run on a Linux terminal. Please notify if the output comes different on a Windows or Mac machine.
回复 支持 1 反对 0

使用道具 举报

lzd1127 发表于 2014-9-4 12:53:19 | 显示全部楼层
不知道。。我还试了3个argument的, 还输出3呢
回复 支持 反对

使用道具 举报

 楼主| zhenggao1986 发表于 2014-9-4 13:10:37 | 显示全部楼层
lzd1127 发表于 2014-9-4 12:53
不知道。。我还试了3个argument的, 还输出3呢

难道是跟编译器有关,但貌似C++编译器结果是一致的,至少g++ 和 visual studio 的编译结果一致。
但是Java的编译结果不同。
回复 支持 反对

使用道具 举报

wangxy 发表于 2014-9-4 13:46:38 | 显示全部楼层
传参顺序问题吧,从右往左和从左往右
猜的。。
回复 支持 反对

使用道具 举报

Linzertorte 发表于 2014-9-4 14:22:26 | 显示全部楼层
输出的确实是2,0其实函数的调用,parameter的evalute顺序是从右向左。。这样编译的时候,生成汇编,参数压栈,就是左边的在上面了。
回复 支持 反对

使用道具 举报

Linzertorte 发表于 2014-9-4 14:25:20 | 显示全部楼层
有空可以看看coursera上的compiler课程。http://stackoverflow.com/questio ... er-evaluation-order
回复 支持 反对

使用道具 举报

lzd1127 发表于 2014-9-5 05:20:51 | 显示全部楼层
哈哈,今天OS还讲了call convention, 貌似argument是从最后一个开始往stack上Push的。
回复 支持 反对

使用道具 举报

guoshuheng 发表于 2014-9-5 08:00:17 | 显示全部楼层
同楼上,从最后一个argument开始push, 楼上是大神,应该没错。
回复 支持 反对

使用道具 举报

 楼主| zhenggao1986 发表于 2014-9-5 14:51:01 | 显示全部楼层
lzd1127 发表于 2014-9-5 05:20. 1point 3acres 璁哄潧
哈哈,今天OS还讲了call convention, 貌似argument是从最后一个开始往stack上Push的。

参数压栈的顺序,每个编译器不一样吧,java run 同样的东西出来的结果是 1 1.
也许有的从左往右,有的从右往左
回复 支持 反对

使用道具 举报

IamForrest 发表于 2014-9-6 01:10:32 | 显示全部楼层
对于C++来说,不会保证参数的evaluation 顺序。各个平台顺序是不一样的。参见标准:. 1point 3acres 璁哄潧
5.2.2 Function call
8 The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
回复 支持 反对

使用道具 举报

rialmat 发表于 2014-9-6 03:12:09 | 显示全部楼层
zhenggao1986 发表于 2014-9-5 14:51.1point3acres缃
参数压栈的顺序,每个编译器不一样吧,java run 同样的东西出来的结果是 1 1.
也许有的从左往右,有的从 ...

如果我没记错的话,Java在语言标准中规定函数参数必须从左到右,而C/C++并没有在语言标准中硬性规定,所以各编译器会有所不同。
回复 支持 反对

使用道具 举报

nintendo_dskay 发表于 2014-9-20 06:10:36 | 显示全部楼层
个人感觉这种是无固定答案的题目,主要考察对函数压参的了解程度。
回复 支持 反对

使用道具 举报

本版积分规则

请点这里访问我们的新网站:一亩三分地Instant.

Instant搜索更强大,不扣积分,内容组织的更好更整洁!目前仍在beta版本,努力完善中!反馈请点这里

关闭

一亩三分地推荐上一条 /5 下一条

手机版|小黑屋|一亩三分地论坛声明 ( 沪ICP备11015994号 )

custom counter

GMT+8, 2016-12-5 04:53

Powered by Discuz! X3

© 2001-2013 Comsenz Inc. Design By HUXTeam

快速回复 返回顶部 返回列表