使用指针将 char* 转换为 unsigned char*
Using a pointer for casting char* to unsigned char*
我正在编写一些使用 fstream read() 函数的代码,该函数需要一个 char* 作为缓冲区。稍后,我想将此缓冲区中的字节作为无符号字符使用,因此我要么必须: 1. 将缓冲区声明为 char* 然后稍后为每个元素执行 static_casts,2 . 将缓冲区声明为 unsigned 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 可以,原因有两个:
(有符号)char
和 unsigned char
类型需要具有相同的 "representation and alignment"。这意味着数据不会有差异(精确到位),或者缓冲区被解释为多长时间。
文件读取函数通常使用 char*
作为通用数据访问类型。他们不能使用 void*
因为类型 void
有一个特别未定义的长度和表示。 char
,但是,确实如此。所以他们可以用它来 read/write 一系列字节。
实际上,文件函数通常用于重新解释数据 as/from 其他内容。它允许你有一个像
这样的结构
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));
并以类似的方式阅读。
我正在编写一些使用 fstream read() 函数的代码,该函数需要一个 char* 作为缓冲区。稍后,我想将此缓冲区中的字节作为无符号字符使用,因此我要么必须: 1. 将缓冲区声明为 char* 然后稍后为每个元素执行 static_casts,2 . 将缓冲区声明为 unsigned 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 可以,原因有两个:
(有符号)
char
和unsigned char
类型需要具有相同的 "representation and alignment"。这意味着数据不会有差异(精确到位),或者缓冲区被解释为多长时间。文件读取函数通常使用
char*
作为通用数据访问类型。他们不能使用void*
因为类型void
有一个特别未定义的长度和表示。char
,但是,确实如此。所以他们可以用它来 read/write 一系列字节。
实际上,文件函数通常用于重新解释数据 as/from 其他内容。它允许你有一个像
这样的结构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));
并以类似的方式阅读。