首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言指標類型轉換實戰:浮點數陣列強制轉整數生成圖像

     編輯:關於C

嚴格別名規則下的合法類型雙關:memcpy 與聯合體

利用 memcpy 或聯合體進行類型雙關,將浮點數位模式重新解讀為整數/RGB 像素,生成具有分形特徵的 PPM 圖像。回應「指標強制轉換有限制」的質疑。

核心程式碼 (C99 標準合規)

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

#define DIM 1000

void write_pixel(FILE *fp, int x, int y) {
    float t = y + x * 0.001f;           // 計算浮點值
    uint8_t rgb[3];
    memcpy(rgb, &t, 3);                 // 合法類型雙關:複製位模式
    fwrite(rgb, 1, 3, fp);              // 寫入 RGB 三通道
}

int main() {
    FILE *fp = fopen("image.ppm", "wb");
    if (!fp) return 1;
    
    // PPM 標頭:P6 = 二進位 RGB, 寬 高, 最大色值
    fprintf(fp, "P6\n%d %d\n255\n", DIM, DIM);
    
    for (int y = 0; y < DIM; y++) {
        for (int x = 0; x < DIM; x++) {
            write_pixel(fp, x, y);
        }
    }
    fclose(fp);
    return 0;
}

為什麼這是合法的?

生成圖像分析

  • t = y + x * 0.001f:x 變化 0.001,y 變化 1.0
  • IEEE 754 float 位模式:sign(1) | exponent(8) | mantissa(23)
  • 取前 3 bytes (24 bits) 作為 RGB:捕獲指數位 + 尾數高位
  • 結果呈現分形條紋圖樣,反映浮點數編碼的幂級結構

PPM 格式說明

P6              # 二進位 RGB 模式 (P3 為 ASCII)
1000 1000       # 寬 高
255             # 最大色值
[RGB 三元組連續資料...]

可用 ImageMagick convert image.ppm image.png 或線上檢視器開啟。

C++ 版本 (更型別安全)

// C++17 std::bit_cast (編譯期位模式轉換)
#include <bit>
#include <cstdint>

uint32_t float_to_rgb(float f) {
    uint32_t bits = std::bit_cast(f);
    return bits | 0xFF000000; // 加上 Alpha = 255
}

// 或使用聯合體 (C++20 起標準化)
union FloatInt { float f; uint32_t i; };
uint32_t bits = FloatInt{f}.i;

Why 數學圖像生成工具

作者開發的 Why 工具內建此演算法:

class CPixelFloatConvertInt : public IPixelEquation {
    unsigned int CalculatePixel(unsigned int x, unsigned int y) {
        float t = y + x * 0.001f;
        unsigned int rst = *(unsigned int*)&t; // 內部實作用聯合體
        rst |= 0xFF000000;
        return rst;
    }
};

教訓總結

  1. 指標強制轉換 *(T*)&v 違反嚴格別名規則,編譯器可假設不別名而誤優化
  2. memcpy 與聯合體是標準合規的類型雙關方式
  3. char* 可別名任何類型,但僅限字節級存取
  4. 現代 C/C++ 提供 std::bit_cast/__builtin_bit_cast 零開銷安全轉換
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法合法性標準依據
*(int*)&float_var❌ 未定義行為C11 6.5/7 嚴格別名規則
union { float f; int i; } u;✅ 合法 (C99+)C11 6.5.2.3/3 聯合體類型雙關
memcpy(&dst, &src, sizeof(dst))✅ 合法C11 7.24.2.1 位模式複製
char* 別名✅ 合法字符類型可別名任何類型