我需要将char pcm[]中的2字节转换为1字节的short pcm_[]。This post使用了C风格的强制转换,最初我在C++程序中试用了它(使用Qt):
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
char pcm[2] = {0xA1, 0x12};
qDebug()<<pcm[0]<<pcm[1];
short pcm_ = ( pcm[1] << 8 )| pcm[0];
qDebug()<<pcm_;
short pcm_2 = ((unsigned char)(pcm[1])) << 8| (unsigned char) pcm[0];
qDebug()<<pcm_2;
return a.exec();
}我发现只有当我在位移位中使用unsigned char时,它才能工作,但是不明白,为什么输入是一个char,所以这是必要的。
此外,我想使用C++风格的转换,并提出了这个:
short pcm_3 = (static_cast<unsigned char>(pcm[1])) << 8|
static_cast<unsigned char>(pcm[0]);
qDebug()<<pcm_3;同样,我需要使用unsigned char而不是char。
所以我有两个问题:
static_cast是正确的演员吗?在我看来,这是一个使用reinterpret_cast的地方的例子。然而,重新解释强制转换不起作用。unsigned char发布于 2015-07-19 11:59:40
根据C标准(6.5.11位排他性或运算符)
3 The usual arithmetic conversions are performed on the operands在C++标准中也是这样写的(5.13位包含或运算符)
1执行通常的算法转换;
通常的算术转换包括整数提升。这意味着在这个表达式中
( pcm[1] << 8 )| pcm[0];操作数pcm[0]被提升为int类型。如果根据编译器类型的设置,char行为类似于signed char类型,那么您得到的值0xA1被提升为有符号的int 0xFFFFFFA1 (条件是like of ( int )等于4)。那就是符号位将是合适的。
因此,您将得到一个不正确的结果。为了避免这种情况,您应该将char类型转换为unsigned char类型,在本例中,提升的值将类似于0x000000A1。在C++中,它可以编写如下
static_cast<unsigned char>( pcm[0] ) 发布于 2015-07-19 11:59:58
您必须使用unsigned char,因为有了operator |升级到int
假设int为32位:
0xA1变为int 0xFFFFFFA1 (以保持相同的值)0xA1变为0x000000A1。发布于 2015-07-19 12:00:53
您需要将char转换为unsigned char的原因是允许char是一个有符号的数据类型。在本例中,在执行|之前将对其进行符号扩展,这意味着对于char的下半部分将变为负值,其中最重要的位设置为1。
char c = 200;
int a = c | 0; // returns -56 on systems where char is signed 在本例中,使用static_cast或C强制转换是一个风格问题。许多C++商店远离C转换,因为它们很难在源代码中找到,而static_cast的则更容易识别。
https://stackoverflow.com/questions/31500787
复制相似问题