我可以像这样投射指针吗?

时间:2016-12-15 03:35:48

标签: c pointers microcontroller 8-bit

代码:

unsigned char array_add[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

...

if ((*((uint32_t*)array_add)!=0)||(*((uint32_t*)array_add+1)!=0))
{
 ...
}

我想检查数组是否全为零。所以我自然而然地想要将一个数组的地址(也恰好是第一个成员的地址)转换为unsigned int 32类型,因此我只需要执行两次,因为它是64位,8字节阵列。问题是,它已成功编译,但程序每次都在这里崩溃。

我在8位微控制器cortex-M0上运行我的程序。

我有多难?

3 个答案:

答案 0 :(得分:2)

从理论上说这可行,但在实践中有一件事你不考虑:对齐内存访问。

如果uint32_t需要对齐的内存访问(例如,4个字节),则将unsigned char的数组转换为uint32_t*,该数组具有1个字节的对齐要求,会生成指向未对齐的指针数组uint32_t

根据documentation

  

不支持Cortex-M0处理器上的未对齐访问。任何尝试执行未对齐的内存访问操作都会导致HardFault异常。

在实践中,这只是危险且脆弱的代码,在某些情况下会调用未定义的行为,正如Olaf所指出的那样,并且更好地解释了here

答案 1 :(得分:1)

要测试多个字节,因为一次代码可以使用memcmp()

这有多快取决于编译器,因为优化编译器可以简单地发出快速8字节(或2 4字节)比较的代码。在{8}处理器上,即使memcmp()也可能不会太慢​​。分析代码有帮助。

注意微观优化,因为它们往往无法有效地使用编码器时间进行重大优化。

unsigned char array_add[8] = ...
const unsigned char array_zero[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
if (memcmp(array_zero, array_add, 8) == 0) ... 

另一种方法使用union。小心不要假设add.arr8[0]是最重要或最不重要的字节。

union {
  uint8_t array8[8];
  uint64_t array64;
} add; 

// below code will check all 8 of the add.array8[] is they are zero.
if (add.array64 == 0)

一般而言,专注于编写清晰的代码并为非常选择案例保留这些小优化。

答案 2 :(得分:-3)

我不确定但是如果你的数组有8个字节,那么只需将基地址分配给long long变量并将其与0进行比较。这应该可以解决检查数组是否全为0的问题。

编辑1:在奥拉夫的评论之后,我会说用long long替换int64_t。但是,为什么不是一个简单的循环来迭代数组和检查。你需要比较8个字符。

编辑2:另一种方法可能是对所有数组元素进行OR运算,然后与0进行比较。如果全部为0,则OR将为零。我不知道CMP是快还是OR。有关精确的CPU周期要求,请参考Cortex-M0文档,但是,我希望CMP更慢。