这是类型转换还是某种指针算法
Is this type casting or some kind of pointer arithmetics?
我看到了一行用C++编写的代码:
long *lbuf = (long*)spiReadBuffer;
事实证明,"spiReadBuffer"是一个包含12个元素的字节数组。但我有点困惑。我想我熟悉定义指针,我可以看到"lbuf"是一个类型为"长"的指针。我还认为,对于选角,我们可以做这样的事情:
y = (int) x;
但是,如果我在"int"后面加一个"*",就像我的第一个例子一样,在"long"后面有一个呢?如果这真的是一个微不足道的问题,我很抱歉,但当我讨论打字和指点的话题时,我没有遇到我的情况,我也没有真正理解它。如果你能指导我或向我介绍任何相关的材料或资源,我将不胜感激。
这被称为类型punning。它欺骗编译器读取对象占用的内存,就好像它是另一种类型一样。
在您的情况下,数组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 {
char buf[12];
long asLong;
} spiReadBuffer;
该标准规定,给工会成员写信,然后从另一个成员那里阅读是未定义的行为。这些编译器扩展选择将其定义为安全的重新解释。
在C/C++中,编译器以相同的方式处理数组:
char spiReadBuffer[12];
char* pBuffer;
编译器将把spiReadBuffer和pBuffer都当作指针。
代码片段
long *lbuf = (long*)spiReadBuffer;
是类型转换的一个示例,仅适用于指针类型。字符*转换为长*;您可以说这是一种指针算术,因为现在,您可以使用long*(而不是一次一个字节)从spiReadBuffer
读取sizeof(long)字节。
您展示的第二个片段:y = (int) x;
也是一个强制转换,但不适用于指针;
考虑一下这个片段:
char spiReadBuffer[] = {1,2,3,4,5,6,7,8};
long *lbuf = (long*)spiReadBuffer;
printf ("%08xn", lbuf[0]);
它将在小端架构上打印04030201
,或在小端体系结构上打印01020304
。
在long *lbuf = (long*)spiReadBuffer
语句lBuf
指向spiReadBuffer
的开头之后,lbuf[0]
(或*lBuf
)允许您将spiReadBuffer
的前4个字节读取为长。
- 使用指针算法修改函数中的 2D 数组
- 通过指针算法计算数组长度
- 由于指针算法错误,代码在 memcpy 中崩溃
- 在 c++ 中使用指针算法
- 通过指针算法访问结构数据成员
- 使用字符** argv 时如何避免指针算法
- 通过指针算法调用结构的结构属性
- 是什么让这种易失性打破了结构的指针算法?
- 使用指针算法调用结构内的结构数组
- 指针算法:*p++ 和 (*p)++ 等等
- 指针算法是否适用于迭代器?
- 你不能在 void 指针上使用指针算法,那么 void 指针数组是如何工作的呢?
- 使用指针算法搜索 2D 数组
- 未检测到越界指针算法?
- 具有两个不同缓冲区的指针算法
- 指针算法符号
- 指针算法传播的"laundry"是吗?
- 这是类型转换还是某种指针算法
- 指针算法在 C++ 中不起作用
- C++11:模板 (TMP) 中的(递归)指针算法