是否有理由不键入演员指针(C)?

时间:2015-03-30 22:08:38

标签: c pointers casting microcontroller

我对C很新,随时教育......

我正在使用一个函数,它期望一个指向char数组的指针作为输入。在调用之前单独设置数组的每个元素是非常麻烦的。我发现了一些似乎有效的替代方案,但我担心自己会陷入陷阱。以下是几个选项。

选项1:

 unsigned char DataToPass[8];
 uint64_t *IntPtr = (uint64_t *)DataToPass;
   ...
 *IntPtr = 0x1122334455667788;
 FunctionCall(DataToPass);

选项2:

unsigned char DataToPass[8];
uint64_t IntData;
...
iDataToPass = 0x1122334455667788;
memcpy(DataToPass, &IntData, sizeof(IntData);
FunctionCall(DataToPass);

3 个答案:

答案 0 :(得分:3)

示例1可能由于对齐违规而导致未定义的行为。此外,它还会违反严格的别名规则而导致UB。

示例2不会导致UB,但它具有实现定义的结果。常见系统上DataToPass[0]0x88,但0x110x55也存在,事实上一切皆有可能。

我的建议是编写清楚表达你意图的代码:

unsigned char DataToPass[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };

它会带你,什么,10秒钟输入,但会节省很多痛苦。

答案 1 :(得分:2)

这有点脏,但你可以使用联盟。

union Data
{
   char c [8];
   uint64_t i;
};

void Func (char *data);

void test ()
{
  Data d;
  d.i = 0x1122334455667788;
  Func (d.c);
}

我觉得那很有用。但是不会解决endian问题。

(我觉得我现在需要彻底清洗)

答案 2 :(得分:1)

你的两个例子都很好 - 有一点需要注意。您需要确保DataToPass已正确对齐系统,以便选项1正常工作。选项2原样罚款。如果你真的想减少打字,为什么不呢:

uint64_t IntData = 0x1122334455667788;
FunctionCall((unsigned char *)&IntData);

正如@Barmar在评论中提到的那样,你的系统的字节序也将在这里发挥作用。