monkerman 发表于 2013-4-15 16:20:19

腾讯的一道笔试题, 觉得还是比较考验基础的.

本帖最后由 monkerman 于 2013-4-15 16:35 编辑

#include <stdio.h>

int main(void)
{
      long long a = 1;
      long long b = 2;
      long long c = 3;

      printf("%d %d %d\n", a, b, c);

      return 0;
}32位环境, CPU为小端模式, 所有的参数都是通过栈传递的, 问: 输出结果是什么? 并解释一下.
// 注: VC6++ 不支持 long long 类型. 测试时注意.推荐 GCC, 要是用 MDK / IAR 什么的应该也可以. 不过结果可能和腾讯的答案差距较大. 人家又不是搞嵌入式的.

monkerman 发表于 2013-4-15 16:23:34

好吧. 帖子发在 ARM 板块, 是想引出一些题目漏洞.

skylly3 发表于 2013-4-15 16:40:29

貌似我也做过, 当时答的是随机值,后来发现不对, 是固定值。

monkerman 发表于 2013-4-15 16:48:36

skylly3 发表于 2013-4-15 16:40 static/image/common/back.gif
貌似我也做过, 当时答的是随机值,后来发现不对, 是固定值。

不是随机值. 是固定的. 而且有迹可循. 我也是运行后, 回味了题目, 看了反汇编才明白过来的.

censtar 发表于 2013-4-15 16:51:34

1 0 2
栈传递,是个提示

电源模块 发表于 2013-4-15 16:54:27

难道long long 这种古怪的类型压不到栈里去?那也要看编译器吧,不见得谁都压不进去。静等大神讲解

Wxy8030 发表于 2013-4-15 17:31:27

腾讯 —— 笔试考这个? 不是考“你认为现在哪个东西值得抄?”么?

tragedy 发表于 2013-4-15 18:14:42

csdn看过,一共三道题。

fantaq 发表于 2013-4-15 18:16:09

这题敢情是专考半熟的人的?初学的大概还不会答错。

实际试了一下,和事先想的一样,无聊。
贴个warning信息,很明了。
test.c: In function ‘main’:
test.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long int’
test.c:9: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long long int’
test.c:9: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘long long int’

monkerman 发表于 2013-4-15 18:40:29

tragedy 发表于 2013-4-15 18:14 static/image/common/back.gif
csdn看过,一共三道题。

就是从那里弄来的........{:lol:}

monkerman 发表于 2013-4-15 18:41:19

fantaq 发表于 2013-4-15 18:16 static/image/common/back.gif
这题敢情是专考半熟的人的?初学的大概还不会答错。

实际试了一下,和事先想的一样,无聊。


无聊?? 能解释下结果为啥么? {:dizzy:}

sniper.q 发表于 2013-4-15 19:03:16

本帖最后由 sniper.q 于 2013-4-15 19:32 编辑

用builder模拟了下 结果:1 0 2

想明白了

long long是8个字节的,printf按4字节取,栈的数据换成4字节是10,20,30,所以实际输出是a的低位:1,a的高位:0;b的低位:2

derive3000 发表于 2013-4-15 19:33:33

是因为long long无法压栈吗??

fantaq 发表于 2013-4-15 20:39:10

monkerman 发表于 2013-4-15 18:41 static/image/common/back.gif
无聊?? 能解释下结果为啥么?


呵呵,较真一下,再补充说明下,之前这个是我拿GCC试的,64位ubuntu,看warning的意思的printf默认的参数是按32位处理的。
刚才拿VC2010试了下, 还真是1 0 2
VC2010已经能认long long了。

本来变参压栈好像是应该是什么就压什么,long long 应该压8byte
但是GCC好像是做的比较聪明,它会判断printf的串,%d就是4byte, 见到%PRId64才会8byte.

既然不同编译器不一样,这问题就没意思了,跟研究回字4种写法差不多了。知道就行了,一个printf搞这么透没意思,我这人向来不求甚解,哈哈。

monkerman 发表于 2013-4-16 09:05:02

fantaq 发表于 2013-4-15 20:39 static/image/common/back.gif
呵呵,较真一下,再补充说明下,之前这个是我拿GCC试的,64位ubuntu,看warning的意思的printf默认的参 ...

嗯. 个人觉得 printf 还是很有用的. 有时候需要自己实现的, 有机会求甚解那就解解.{:lol:}
这题其实就是 long long 64位, printf 参数入栈顺序从右到左(貌似是标准规定. 如果分三次 printf, 结果就又不一样了.), 栈的增长方向从高到低地址. %d 只取 4字节(标准), 大小端模式.
题目里没提到的就是栈的增长方向, 这个在 ARM 平台下就有问题了. 因为 ARM 的堆栈有四种模式. 不过常用的几乎都是满递减. 人家企鹅又不是搞这个的.
另外 %lld/%I64d 就可以打出 64 位数值.

llwllwllw 发表于 2013-4-17 07:54:11

学习学习!

sleet1986 发表于 2013-4-17 08:10:20

这个帖子可以了解printf,栈,还不错

xiefy21 发表于 2013-8-14 08:50:45

mark……
顶一个…
页: [1]
查看完整版本: 腾讯的一道笔试题, 觉得还是比较考验基础的.