将2d数组重新解释为指针

Reinterpret 2d array as pointer

本文关键字:解释 指针 2d 数组 新解释      更新时间:2023-10-16

假设我有一个这样的数组:

unsigned char a[10][10];

和我想使用读取字节到这个数组(行为主顺序):

FILE *f = fopen("xxx.bin", "rb");
fread((unsigned char *)a, 1, 10 * 10, f);
fclose(f);

由于fread的第一个参数类型为void *,是否有标准的方法将unsigned char a[10][10]转换为void * ?我应该用static_cast还是reinterpret_cast ?由于c++中的2d数组是连续分配的,我认为将其重新解释为指针是合理的。

为了获得指向avoid*,只需获取其地址(&a)并让编译器隐式转换为void*:

fread(&a, sizeof a, 1, f);

有一些注意事项:

  • 首先,你痛苦地关闭文件,但你没有检查读取错误。
  • 无论何时使用reinterpret_cast,使用结果的唯一方法是将其reinterpret_cast转换回原来的类型。一般来说,你不会因此使用reinterpret_cast,除非你需要将指针存储在一个整数中。正如其他人提到的,static_cast是可行的方法。
  • 永远不要使用c风格的强制转换。他们是危险的,他们根本不记录正在发生的事情。最后,你可以用const修饰你的数组,你的代码会在运行时愉快地编译和中断,因为你覆盖了编译器的安全开关。
  • 我不会指望在矩阵的行之间没有填充,即它的大小不会只是100。您只能对每行使用单独的读操作来解决这个问题。我不确定这一点,虽然,它很可能是它的大小保证不包括任何填充。

以下工作在gcc 4.8.2中:

FILE *f = fopen("xxx.bin", "rb");
fread(a, sizeof(unsigned char), 10 * 10, f);
fclose(f);

如果您喜欢显式强制转换,那么标准的方法是使用static_cast。应该使用它,因为它在强制转换为void*时保留了地址。

FILE *f = fopen("xxx.bin", "rb");
fread(static_cast<void*>(a), sizeof(unsigned char), 10 * 10, f);
fclose(f);

reinterpret_cast只保证如果您将某些内容强制转换为void*,然后再强制转换回您的类型,那么您将得到相同的值。