我遇到了一行用 C++ 编写的代码:
long *lbuf = (long*)spiReadBuffer;
事实证明,“spiReadBuffer”是一个包含 12 个元素的字节数组。但我有点困惑。我想我对指针的定义很熟悉,我可以看到“lbuf”是一种“long”指针。我还认为对于类型转换我们可以做这样的事情:
y = (int) x;
但是如果我像我的第一个例子一样在“int”后面加上一个“*”,在“long”后面有一个怎么办? 如果这是一个非常微不足道的问题,我深表歉意,但是当我浏览类型转换和指针主题时,我没有遇到我的案例,我也没有真正理解它。 如果您能指导我或向我介绍任何相关 Material 或资源,我将不胜感激。
最佳答案
这称为类型双关。它欺骗编译器读取对象占用的内存,就好像它是另一种类型一样。
在您的例子中,数组 spiReadBuffer
衰减为指向其第一个元素的指针,然后指针被转换并存储。当您取消引用此指针时,您将访问数组的开头,就好像它是一个 long
。
这种方法的问题在于它会触发未定义的行为(参见严格别名)。因此,即使它在很多情况下都能正常工作,它也可能会在没有通知的情况下中断。
有两种方法(据我所知)可以安全地输入双关语。第一个是符合标准的:std::memcpy
。
char spiReadBuffer[12];
long rbAsLong;
std::memcpy(&rbAsLong, &spiReadBuffer, sizeof rbAsLong);
// rbAsLong contains the first four bytes of spiReadBuffer, reinterpreted as a long.
第二个涉及编译器通常提供的扩展(但您应该检查),它扩展了 union 的行为。
union {
char buf[12];
long asLong;
} spiReadBuffer;
标准声明写入 union 成员然后从另一个成员读取是未定义的行为。这些编译器扩展选择将其定义为安全的重新解释。
关于c++ - 这是类型转换还是某种指针算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29966930/