gpt4 book ai didi

c++ - *(int*)&data[18] 在此代码中实际做了什么?

转载 作者:行者123 更新时间:2023-12-02 02:36:51 25 4
gpt4 key购买 nike

我遇到了用 C++ 读取 BMP 文件的语法

#include <fstream>
int main() {
std::ifstream in('filename.bmp', std::ifstream::binary);
in.seekg(0, in.end);
size = in.tellg();
in.seekg(0);
unsigned char * data = new unsigned char[size];
in.read((unsigned char *)data, size);

int width = *(int*)&data[18];
// omitted remainder for minimal example
}

我不明白这句话是什么

int width = *(int*)&data[18];

实际上是在做。为什么从 unsigned char *intint width = (int)data[18]; 的简单转换不起作用?

最佳答案

Note

As @user4581301 indicated in the comments, this depends on the implementation and will fail in many instances. And as @NathanOliver- Reinstate Monica and @ChrisMM pointed out this is Undefined Behavior and the result is not guaranteed.

根据bitmap header format ,位图的宽度(以像素为单位)存储为从字节偏移量 18 开始的有符号 32 位整数。语法

int width = *(int*)&data[18];

读取字节 19 到 22(含)(假设为 32 位 int)并将结果解释为整数。

怎么样?

  • &data[18] 获取索引 18 处 unsigned char 的地址
  • (int*) 将地址从 unsigned char* 转换为 int* 以避免 loss of precision on 64 bit architectures
  • *(int*) 取消引用地址以获取引用的 int

基本上,它获取data[18]的地址并读取该地址处的字节,就好像它们是整数一样。

为什么简单地转换为 `int` 不起作用?

sizeof(data[18])1,因为 unsigned char 是一个字节 (0- 255) 但如果系统是 32 位,则 sizeof(&data[18])4,如果系统为 8它是 64 位的,这可以是 larger (or even smaller for 16-bit systems)但除 16 位系统外,它至少应为 4 字节。显然,在这种情况下,不需要读取超过 4 字节,并且转换为 (int*) 并随后取消引用 int 会产生 4 字节,实际上是偏移量 18 和 21 之间的 4 个字节(含)。从 unsigned charint 的简单转换也将产生 4 个字节,但仅产生 data 信息的一个字节。以下示例对此进行了说明:

#include <iostream>
#include <bitset>

int main() {
// Populate 18-21 with a recognizable pattern for demonstration
std::bitset<8> _bits(std::string("10011010"));
unsigned long bits = _bits.to_ulong();
for (int ii = 18; ii < 22; ii ++) {
data[ii] = static_cast<unsigned char>(bits);
}

std::cout << "data[18] -> 1 byte "
<< std::bitset<32>(data[18]) << std::endl;
std::cout << "*(unsigned short*)&data[18] -> 2 bytes "
<< std::bitset<32>(*(unsigned short*)&data[18]) << std::endl;
std::cout << "*(int*)&data[18] -> 4 bytes "
<< std::bitset<32>(*(int*)&data[18]) << std::endl;
}
data[18]                    -> 1 byte  00000000000000000000000010011010
*(unsigned short*)&data[18] -> 2 bytes 00000000000000001001101010011010
*(int*)&data[18] -> 4 bytes 10011010100110101001101010011010

关于c++ - *(int*)&data[18] 在此代码中实际做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59186280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com