簡體   English   中英

*(int*)&data[18] 在這段代碼中實際上做了什么?

[英]What is *(int*)&data[18] actually doing in this code?

我遇到了這種在 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 *int的簡單轉換, int width = (int)data[18]; , 工作?

筆記

正如@user4581301在評論中指出的那樣,這取決於實現,並且在許多情況下會失敗。 正如@NathanOliver- Reinstate Monica@ChrisMM指出的那樣,這是未定義的行為,無法保證結果。

根據位圖頭格式位圖的寬度以像素為單位存儲為一個有符號的 32 位整數,從字節偏移量 18 開始。語法

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

讀取字節 19 到 22,包括(假設為 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 ) 但是sizeof(&data[18])4如果系統是 32 位,如果是8如果是 64 位,這可以是更大(對於 16 位系統甚至更小),但除 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM