windows下C中数据的字节表示。大端和小端

Byte presentation of data in C under windows. Big-endian & little endian

我有一些C代码,"fread"读了一些,但结果不是我所期望的。这是我的代码:

 void main()
{
    unsigned int *data =(unsigned int*)malloc(4);
    static unsigned int ImageData[256][256];
    char *filename= "C:\Users\Frank\Documents\Visual Studio 2012\Projects\UI\UI\bin\Debug\bin\result.txt";
    FILE *pfile=fopen(filename,"rb");
    for (int i = 0; i < 256; i++)
        for (int j = 0; j < 256; j++)
        {
           fread(data, 4, 1, pfile);              
           ImageData[i][j] =(*data);
        }
          fclose(pfile);        
          printf("\nsize=%d",sizeof(unsigned int));
    for (int i = 0; i < 9; i++)     
        for (int j = 0; j < 9; j++)
        {
           printf("\npixel[%d,%d]=%d",i,j,ImageData[i][j]);
        }           
}

我期望的十六进制是:

38 FC 0D 13 38 A7 D4 92 38 1F 32 B3 38 blabla...

两大问题:

  1. 始终检查相关系统调用的结果,如果您依赖它们的结果,通常就是这种情况。

    FILE *pfile=fopen(filename,"rb");
    

    应该是

    FILE *pfile=fopen(filename,"rb");
    if (NULL == pfile)
    {
       fprintf(stderr, "%s failed to open.\n", filename);
    }
    
  2. 打印 unsigned int 时使用 %u 转换说明符。

    所以这个

    printf("\npixel[%d,%d]=%d", i, j,ImageData[i][j]);
    

    应该是

    printf("\npixel[%d,%d]=%u", i, j, ImageData[i][j]);
    

一些小问题:

  1. C 标准将 main() 定义为 return int.

    所以这个

    void main()
    

    应该是

    int main()
    

    甚至更好

    int main(void)
    
  2. 不需要在C中强制转换malloc/calloc/realloc的结果,也不推荐以任何方式。

  3. 另外 malloc() 可能会失败。

    所以通过

    测试它的结果
    data = malloc(4);
    if (NULL == data)
    {
      /* Log error and probably exit ... */
    }
    
  4. fread() 也可能失败。

    if (1 != fread(..., 4, 1, pfile))
    {
       /* read less then expected */
    }
    
  5. 测量内存和索引数组的首选数据类型是 size_t 而不是 int。在这种情况下不需要负值。

一些最后的提示:

  1. 如果您知道需要读取 32 位值(4 字节),请确保正确定义变量。

    #include <inttypes.h> /* for u/int32_t */
    
    uint32_t ImageData[256][256];
    
  2. 无需动态分配临时读取缓冲区

    只需定义

    uint32_t data;
    

    并像这样使用它

    if (1 != fread(&data, 4, 1, pfile))
    {
       ...
    
    ImageData[i][j] = data;
    

    或者直接读入数组

    if (1 != fread(&ImageData[i][j], 4, 1, pfile))
    {
       ...
    

反正就是大小端问题。已解决。

ImageData[i][j] =_byteswap_ulong(ImageData[i][j]);

谢谢大家。