面试问题

时间:2010-11-24 17:44:33

标签: c++ c

我昨天在采访中被问到以下代码的输出

#include <stdio.h>
int main(void){
       printf ("%x" ,-1<<4); 
}

我有2分钟时间告诉答案。我回复了fffffff0。采访结果尚未宣布。我想知道我的答案是否正确?

8 个答案:

答案 0 :(得分:58)

技术上左移一个负整数会调用Undefined Behavior。这意味着-1<<4是UB。我不知道为什么他们问你这个问题。可能他们想测试你对C和C ++标准的深度了解。

C99 [6.5.7/4]说

  

E1的结果&lt;&lt; E2是E1左移E2位位置;腾出的位用零填充。如果E1具有无符号类型,则结果的值为E1×2 E2 ,减少模数   比结果类型中可表示的最大值多一个。如果E1有签名   类型和非负值,E1×2 E2 在结果类型中可表示,那么   结果价值; 否则,行为未确定

C ++ 03使omitting the relevant text的行为未定义。

答案 1 :(得分:11)

没有。你不对。这是坏消息。好消息是,面试官可能不知道这一点,并且会认为你是因为这是他们编译运行时得到的结果。

真正的答案是它是实现定义的。由于超载,我并不是100%有信心说它是未定义的行为,但我认为可能是。至少虽然结果取决于负数如何表示等等......你声称这两种语言都没有定义输出的内容。

答案 2 :(得分:9)

在我的机器上:

chris@zack:~$ cat > test.c
#include <stdio.h>
int main(void){
       printf ("%x" ,-1<<4);
}

chris@zack:~$ gcc -o test test.c && ./test
fffffff0

但是,结果将取决于您的体系结构和编译器。所以正确的答案是“它可以输出任何东西。”

答案 3 :(得分:8)

Binary of 1  : 0000 0000 0000 0000 0000 0000 0000 00001

将1的出现替换为1,因为您要计算负数的二进制

How to calculate binary of negative numbers

Binary of -1 : 1111 1111 1111 1111 1111 1111 1111 11111

Left shift 4 : 1111 1111 1111 1111 1111 1111 1111 0000

十六进制结果左移4的表示 将是

1111 : F 

0000 : 0

如此计算的输出将是:

FFFFFFF0

你的答案是对的。

答案 4 :(得分:3)

对于一般情况,

左移一个负数是未定义的,但是我们必须理解为什么这个未定义的行为(UB)?请记住,最高有效位(MSb)是符号位。如果该位为1,则该数字为负。如果它为零,则数字为正。这是第一次左移时丢失的关键信息。例如

-32768<<4

相同
0x8000<<4

(假设一台16位机器为了简单起见)

结果当然是0,这实际上没有任何意义,因此是UB。

在OP的访谈问题的具体情况中,我们只关注一个特定的值... not 一般情况。 -1(32位机器上的0xffffffff)向左移动4次将产生0xfffffff0,就像OP最初想的那样。

答案 5 :(得分:1)

这是未定义的行为。

$ cat undef.c 
#include <stdio.h>
int main(void){
       printf ("%x" ,-1<<4); 
}
$ clang -fsanitize=undefined undef.c
$ ./a.out
undef.c:3:24: runtime error: left shift of negative value -1
fffffff0

答案 6 :(得分:-1)

我在3个不同的编译器和操作系统上运行此代码。所有人都给了我同样的答案,如问题所述。除非有人提出编译器,这是真正未定义的行为,我会说答案是正确的。如果在99.99%的情况下这是稳定的,那么标准变更的机会比编译器停止支持它的机会多。

答案 7 :(得分:-4)

我只是在一个文本文件中编写代码,编译它,然后,答案是正确的。