使用指针将字符* 转换为无符号字符*

Using a pointer for casting char* to unsigned char*

本文关键字:字符 无符号 转换 指针      更新时间:2023-10-16

我正在编写一些使用 fstream read() 函数的代码,这个函数需要一个 char* 作为缓冲区。稍后,我想将此缓冲区中的字节用作无符号字符,因此我必须:1.将缓冲区声明为char*,然后稍后为每个元素执行static_casts,2.将缓冲区声明为无符号char*,然后在将其传递给读取函数时执行reinterpret_cast, 或 3.将缓冲区声明为 char*,并创建一个强制转换指针,用于将缓冲区作为无符号字符访问。

下面是一个片段:

char* buf = new char[512];
unsigned char* ubuf = reinterpret_cast<unsigned char*>(buf);
    fstream myfile;
    myfile.open("foo.img");
    myfile.seekg(446);
    myfile.read(buf, 16);
    //myfile.read(reinterpret_cast<char*>(buf), 16);
int bytes_per_sector = ubuf[1] << 8 | ubuf[0];
...

我喜欢这种方式,因为我只需要强制转换一次,并且我可以以任一类型访问缓冲区,而无需每次都进行转换。但是,这是一种好的做法吗?这里有什么可能出错的地方吗?使用reinterpret_cast让我有点紧张,因为我通常不使用它,而且我被告知要小心很多次。

在这种情况下,reinterpret_cast很好,原因有两个:

  1. (带符号的)charunsigned char类型需要具有相同的"表示和对齐方式"。这意味着数据不会有差异(它将是每比特精确),或者缓冲区被解释为多长时间。

  2. 文件读取函数通常将char*用作通用数据访问类型。他们不能使用 void*因为类型 void 具有特定的未定义的长度和表示形式。 然而,char确实如此。因此,他们可以使用它来读取/写入一系列字节。

实际上,文件函数通常旨在将数据重新解释为/来自其他内容。它允许您拥有这样的结构

typedef struct structSomeStruct
{
    char name[8]; // a basic, fixed length, string
    unsigned long i; // a 32 bit value
    float x, y, z, w;
} SomeStruct;

class SomeStruct
{
    public:
        char name[8];
        unsigned long i;
        float x, y, z, w;
        
        SomeStruct()
        {
            // ...
        }
};

并使用以下内容将其存储到文件中:

SomeStruct st;
// populate the st data structure
// file.write(char* start_of_data, size_t number_of_bytes);
file.write(reinterpret_cast<char*>(&st), sizeof(SomeStruct));

并类似地阅读它。