在我的机器上:
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个不同的编译器和操作系统上运行此代码。所有人都给了我同样的答案,如问题所述。除非有人提出编译器,这是真正未定义的行为,我会说答案是正确的。如果在99.99%的情况下这是稳定的,那么标准变更的机会比编译器停止支持它的机会多。
这是未定义的行为。
$ 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
我只是在一个文本文件中编写代码,编译它,然后 的 是 强> ,答案是对的。
从技术上讲,左移一个负整数会调用Undefined Behavior。这意味着 -1<<4 是UB。我不知道为什么他们问你这个问题。可能他们想测试您对C和C ++标准的深度了解。
-1<<4
C99 [ 6.5.7/4 ]说
6.5.7/4
E1&lt;&lt;&lt;&lt; E2是E1左移E2位位置;空位是铿乴以零为首。如果E1具有无符号类型,则结果的值为E1脳2 E2 ,减少模数 比结果类型中可表示的最大值多一个。如果E1有签名 类型和非负值,E1脳2 E2 在结果类型中是可表示的,那就是 结果价值; 的 否则,行为是不正确的 强> 。
C ++ 03使其成为未定义的行为 省略相关文字 。
左移一个负数是未定义的 一般 但是我们必须理解为什么这个未定义的行为(UB)?请记住,最高有效位(MSb)是符号位。如果该位为1,则该数字为负。如果它为零,则数字为正。这是第一次左移时丢失的关键信息。例如
-32768<<4
是一样的
0x8000<<4
(假设16位机器简单)
结果当然是0,这实际上没有任何意义,因此是UB。
在OP的访谈问题的具体情况中,我们只关注一个具体的价值...... 不 一般情况。 -1(在32位机器上的0xffffffff)向左移动4次将产生0xfffffff0,正如OP最初想的那样。
Binary of 1 : 0000 0000 0000 0000 0000 0000 0000 00001
将1的出现替换为1,因为您要计算负数的二进制数
如何计算负数的二进制数
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
你的答案是正确的。
不,你不对。这是坏消息。好消息是,面试官可能不知道这一点,并且会认为你是因为这是他们在编译和运行时得到的结果。
真正的答案是它是实现定义的。由于超载,我并不是100%有信心说它是未定义的行为,但我认为可能是。至少虽然结果取决于负数如何表示等等......你声称这两种语言都没有定义输出的内容。