C++ 面试问题

C++ 面试问题,c++,c,C++,C,在昨天的采访中,我被问及以下代码的输出 #include <stdio.h> int main(void){ printf ("%x" ,-1<<4); } #包括 内部主(空){ printf(“%x”,-1从技术上讲,将负整数左移会调用未定义的行为。这意味着-1不。你不正确。这是个坏消息。好消息是面试官可能不知道这一点,并且会假设你知道,因为这是他们编译和运行它时得到的结果 真正的答案是它是实现定义的。我不能100%肯定地说它是由于过载而未定义的行为

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

#include <stdio.h>
int main(void){
       printf ("%x" ,-1<<4); 
}
#包括
内部主(空){

printf(“%x”,-1从技术上讲,将负整数左移会调用未定义的行为。这意味着
-1不。你不正确。这是个坏消息。好消息是面试官可能不知道这一点,并且会假设你知道,因为这是他们编译和运行它时得到的结果

真正的答案是它是实现定义的。我不能100%肯定地说它是由于过载而未定义的行为,但我认为它可能是。至少,尽管结果取决于负数的表示方式,等等。您声称的这两种语言都不是定义输出的语言。

ine:

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

chris@zack:~$ gcc -o test test.c && ./test
fffffff0
chris@zack:~$cat>test.c
#包括
内部主(空){

printf(“%x”,-1我刚刚在一个文本文件中编写了代码,并对其进行了编译,是的,答案是正确的。

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

-32768<<4

-32768我在3个不同的编译器和操作系统上运行了这段代码。所有人都给了我与问题中提到的相同的答案。除非有人提出了编译器,而这实际上是未定义的行为,否则我会说答案是正确的。如果这在99.99%的情况下是稳定的,那么就有更多的机会获得标准ged,则编译器停止支持它

Binary of 1  : 0000 0000 0000 0000 0000 0000 0000 00001
将0替换为1,因为您要计算负no的二进制数

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

因此,计算的输出将是:

FFFFFFF0

你的回答是对的。

这是未定义的行为

$ 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
$cat undef.c
#包括
内部主(空){


printf(“%x”,-1这不取决于有符号整数的表示吗?好吧,有一种方法可以找到。编译并运行代码,傻瓜!@cdhowie-如果你是开玩笑的话,这很有趣,但可能对OP来说并不完全清楚。如果你不是,那你就可耻了。除了-1@Tony:
main
不需要返回语句。请参阅不相关的,但在测试。尽管如此,我的答案并没有什么不正确的地方。我不会抱怨分数(反正我被封顶了,我不在乎)但是当有人投反对票时,我通常希望他们留下反馈,说明原因,这样我就有机会改进我的答案。我不认为编译器的输出与此无关。我认为这比引用标准更相关。特别是当每个人关心的编译器都有相同的输出时。所以我给了你f反馈。停止抱怨。@PigBen编译器的输出是不相关的,因为它是未定义的行为,结果可能会在下一版本的
中更改……我说我认为是的。“因为过载”?你是说“过载”吗用
c
c++
标记问题?如果是这样的话:你可能选择了一个更模糊的术语吗?:-PEither他们想测试知识的深度,或者他们只是不知道。我参加过几次采访,他们实际上不知道一个技术问题的正确答案。通常情况下,特别是在早期阶段,面试官是人力资源部或管理部。据我所知,有些困难的是,在技术方面高度熟练对成为管理层毫无帮助……甚至会损害你的机会。而人力资源部……根本就不是他们的领域。在我的经验中,知识最少的人经常会问这样的问题是的,我记得当我被问及
无符号字符
和普通的
字符
之间的区别时,有人告诉我说有一种
有符号字符
类型是错误的。但这是由技术负责人说的,不是人力资源或管理层说的。我需要检查一下,但我的理解是正确的C标准的定义是,负值的移位确实是未定义的,但负值的移位是“实现定义的”,即,它不必在所有平台上都相同,但需要定义。在任何情况下,在任何最近的平台上-1@Jean-Marc:Prasoons的回答直接引用了C99标准。左移负值是未定义的行为。但是,如果右移负值,结果是实现定义的。Prasoon:litb的命令关于你“省略相关文本”的评论link让我觉得有足够的空间来解释这个片段,因为它意味着左移负整数是实现定义的,而不是UB。我只是说。我通常向上投票来反对匿名向下投票,但在这种情况下,答案不仅是错误的,而且是积极的误导。检查使用特定的编译器和在特定系统上运行的编译器不会告诉您标准要求是什么(更不用说编译器可能有bug)。几乎是例外:Comeau是一个非常符合标准的编译器,您通常可以信任它,使用Comeau在线(免费)测试小代码段是一个好主意,但即使是科莫也有一些错误…@Akf:我明白。谢谢你的建议。我很久没有使用编译语言工作了,忘记了所有这些。我应该得到否决票。不管怎样,从u_+1中学到的教训是:-)。还是把答案删掉吧…?同样的观点也被cdhowie详尽地阐述了,他仅仅因为剪切和粘贴了他的代码,就获得了3票!@Alf:UsiveInsight re Comeau’s to share-谢谢(不过这里有一个有趣的反例-如你所知,即使Comeau在某些特定的CPU上编译/测试运行,所以它也很有用
1111 : F 

0000 : 0
FFFFFFF0
$ 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