中级C ++开发人员的棘手面试问题 [英] Tricky interview question for mid-level C++ developer
问题描述
面试中有人问我这个问题,我真的不明白这里发生了什么。问题是控制台中将显示什么?
I was asked this question on the interview, and I can't really understand what is going on here. The question is "What would be displayed in the console?"
#include <iostream>
int main()
{
unsigned long long n = 0;
((char*)&n)[sizeof(unsigned long long)-1] = 0xFF;
n >>= 7*8;
std::cout << n;
}
这里正在逐步发生什么事情?
What is happening here, step by step?
推荐答案
让我们一次获得这一步骤:
Let's get this one step at a time:
((char*)&n)
这会强制转换变量<$ c $的地址c> n 从 unsigned long long *
到 char *
。这是合法的,实际上通过char指针访问不同类型的对象是该语言接受的少数类型调整情况之一。实际上,这允许您以字节数组(在C ++中为 char
)访问对象 n
的内存。
This casts the address of the variable n
from unsigned long long*
to char*
. This is legal and actually accessing objects of different types via pointer of char is one of the very few "type punning" cases accepted by the language. This in effect allows you to access the memory of the object n
as an array of bytes (aka char
in C++)
((char*)&n)[sizeof(unsigned long long)-1]
您访问对象 n
的最后一个字节。请记住, sizeof
返回数据类型的维数(以字节为单位)(在C ++中, char
具有字节的更改自我)
You access the last byte of the object n
. Remember sizeof
returns the dimension of a data type in bytes (in C++ char
has an alter ego of byte)
((char*)&n)[sizeof(unsigned long long)-1] = 0xFF;
您将 n
的最后一个字节设置为值 0xFF
。
You set the last byte of n
to the value 0xFF
.
由于 n
为 0
最初的 n
布局内存现在为:
Since n
was 0
initially the layout memory of n
is now:
00 .. 00 FF
现在请注意 ...
我放在中间。那不是因为我懒于将 n
的值复制粘贴到字节中,而是因为 unsigned long long $ c $的大小标准未将c>设置为固定尺寸。有一些限制,但具体实现因实施而异。因此,这是第一个未知。但是,在大多数现代体系结构中,
sizeof(无符号长长整数)
为8,因此我们将继续使用它,但是在认真的采访中,您应该提到这一点。
Now notice the ...
I put in the middle. That's not because I am lazy to copy paste the values the amount of bytes n
has, it's because the size of unsigned long long
is not set by the standard to a fixed dimension. There are some restrictions, but it can vary from implementation to implementation. So this is the first "unknown". However on most modern architectures sizeof (unsigned long long)
is 8, so we are going to go with this, but in a serious interview you are expected to mention this.
另一个未知是这些字节的解释方式。无符号整数只是用二进制编码。但这可以是小尾数或大尾数。 x86的字节序不大,因此我们以它为例进行说明。
The other "unknown" is how these bytes are interpreted. Unsigned integers are simply encoded in binary. But it can be little endian or big endian. x86 is little endian so we are going with it for the exemplification. And again, in a serious interview you are expected to mention this.
n >>= 7*8;
此右移 n
的值56次。请注意,现在我们谈论的是 n
的值,而不是内存中的字节。根据我们的假设(大小8,小端),在内存中编码的值为 0xFF000000 00000000
,因此将其移位为 7 * 8
时间将导致值 0xFF
为 255
。
This right shifts the value of n
56 times. Pay attention, now we are talking about the value of n
, not the bytes in memory. With our assumptions (size 8, little endian) the value encoded in memory is 0xFF000000 00000000
so shifting it 7*8
times will result in the value 0xFF
which is 255
.
因此,假设 sizeof(unsigned long long)
为 8
,并且对程序进行了小端编码,则输出 255
到控制台。
So, assuming sizeof(unsigned long long)
is 8
and a little endian encoding the program prints 255
to the console.
如果我们在谈论大型字节序系统,将最后一个字节设置为 0xff
后的内存布局仍然相同: 00 ... 00 FF
,但是现在编码的值为 0xFF
。因此, n>> = 7 * 8;
的结果将是 0
。在大型字节序系统中,程序将在控制台上打印 0
。
If we are talking about a big endian system, the memory layout after setting the last byte to 0xff
is still the same: 00 ... 00 FF
, but now the value encoded is 0xFF
. So the result of n >>= 7*8;
would be 0
. In a big endian system the program would print 0
to the console.
如评论中所指出的,还有其他假设:
As pointed out in the comments, there are other assumptions:
-
char
是8位。尽管保证sizeof(char)
为1
,但它不必具有8位。我所知道的所有现代系统都将位分组为8位字节。
char
being 8 bits. Althoughsizeof(char)
is guaranteed to be1
, it doesn't have to have 8 bits. All modern systems I know of have bits grouped in 8-bit bytes.
整型不必是大端数字的。可能还有其他排列方式,例如中间字节序。如今,除了大尾数以外,其他东西都被认为是深奥的。
integers don't have to be little or big endian. There can be other arrangement patterns like middle endian. Being something other than little or big endian is considered esoteric nowadays.
这篇关于中级C ++开发人员的棘手面试问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!