c - C中指向不同数据类型的指针

标签 c pointers unsigned-integer unsigned-char

我已经在 C 中编译并运行了以下程序:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char* argv[]){
  uint8_t data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
  uint32_t* pointer32 = &data[0];
  uint64_t* pointer64 = &data[0];

  printf("%" PRIu64 "\n", *pointer64);
  printf("%" PRIu32 "\n", *(pointer32++));
  printf("%" PRIu32 "\n", *pointer32);

  return 0;
}

并收到以下预期输出:

506097522914230528
50462976
117835012

输出是正确的,对应于将数据按位解释为无符号 64 位整数和无符号 32 位整数。 我在运行 Ubuntu 14.04 的 64 位机器上试过这个。它是用标准的 gcc 编译器(4.8.4?)编译的。编译器会抛出“来自不兼容指针类型的赋值”警告(可以安全地忽略它,因为不兼容的赋值是有意的)。

这是一种转换和解释“数据”数组中数据的可靠方法,还是建议手动将每个字节(一次一个)复制和移动到一个临时变量?

最佳答案

你违反了aliasing rules .所以,明确的答案是:

简而言之:你不能让不同类型的指针指向同一个对象。这可能会导致代码损坏,因为编译器实际上会假设这不会发生,并且可能会优化代码。

只是一个非常强烈的提示:不要忽略警告。它们是有充分理由的。

最好的方法是将数组中每个元素的数据正确序列化/反序列化为最终类型。这也将避免与值的字节顺序(字节顺序)和任何(可能的)填充有关的任何问题。

我使用这样的函数:

uint32_t readUInt32(const uint8_t **buffer)
{
    ... // increment buffer accordingly
}

这样,我只需沿行传递缓冲区指针,而不必关心调用者的递增。该技术实际上是一个迭代器。

关于c - C中指向不同数据类型的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31301949/

相关文章:

c - 在 C 中使用 libcurl 通过 HTTPS 上传文件

c - gdb核心转储警告: Can't open file/memfd:magicringbuffer (deleted) during file-backed mapping note processing

PHP处理大字符串

C从函数传递双指针

sql - 为什么 SQL Server 不支持无符号数据类型?

c++ - 将 uint64_t rdtsc 值转换为 uint32_t

c - 在 for 循环之外使用变量。

c++ - 修改指针属性

c - 扩展动态分配的指针数组

byte - 寻址 32 个字节需要多少位?