*(int*)&data[18]在这段代码中实际上做了什么?
What is *(int*)&data[18] actually doing in this code?
我遇到了这种语法来读取 BMP 文件C++
#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 *
到int
、int width = (int)data[18];
的简单演员阵容不起作用?
注意
如注释中所述@user4581301,这取决于实现,并且在许多情况下会失败。正如@NathanOliver-恢复莫妮卡和@ChrisMM指出的那样,这是未定义的行为,结果无法保证。
根据位图标头格式,位图的宽度(以像素为单位(存储为从字节偏移量 18 开始的有符号 32 位整数。语法
int width = *(int*)&data[18];
读取字节 19 到 22(包括 32 位((假设 32 位int
(并将结果解释为整数。
如何?
&data[18]
获取索引 18 处unsigned char
的地址(int*)
将地址从unsigned char*
转换为int*
,以避免在 64 位架构上损失精度*(int*)
取消引用地址以获取引用的int
值
所以基本上,它采用data[18]
的地址并读取该地址的字节,就好像它们是整数一样。
为什么简单的"int"投射不起作用?
sizeof(data[18])
是1
,因为unsigned char
是一个字节(0
-255
(,但如果系统是32位sizeof(&data[18])
4
,如果它是64位,则8
,它可以更大(对于16位系统甚至更小(,但除了16位系统之外,它至少应该为4
字节。显然,在这种情况下不需要读取超过4
个字节,并且强制转换为(int*)
并随后取消引用int
会产生4
个字节,实际上是偏移量 18 和 21 之间的 4 个字节(包括 18 和 21(。从unsigned char
到int
的简单转换也将产生 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++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 您好,我实际上想了解以下代码.有人可以详细说明代码它到底在做什么吗?为什么它会在第 31 行崩溃
- *(int*)&data[18]在这段代码中实际上做了什么?
- Cppcheck 静态代码分析器实际上可以检测到不太常见的警告(如 "Relative Path Traversal (CWE-23)" 或"Buffer Under-read(CWE-127)")吗
- 将在C++中的内联函数中返回语句实际上返回并终止代码流
- 代码由于未初始化的变量而崩溃,即使我实际上没有使用它