簡體   English   中英

移位char和unsigned char

[英]Bit shifting `char` vs. `unsigned char`

我需要將char pcm[]中的2個字節轉換為1個字節short pcm_[] 這篇文章使用了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 ++-style-cast,並提出了這一點:

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

根據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提升為signed int 0xFFFFFFA1 (假設sizeof(int)等於4)。 那就是符號位將被傳播。

因此,您將得到錯誤的結果。 為了避免這種情況,您應該將類​​型char強制轉換為unsigned char類型。在這種情況下,提升后的值將看起來像0x000000A1 在C ++中可以這樣寫

static_cast<unsigned char>( pcm[0] ) 

問題從這里開始:

char pcm[2] = {0xA1, 0x12};

在您的系統上, char是帶符號的,范圍為-128127 您嘗試將161分配給char 這超出范圍。

在C和C ++中,超出范圍分配的結果是實現定義的 通常,編譯器決定使用具有相同表示形式的char -95

然后,將其提升為int(通過將其用作|操作數),得到int值-95 ,該值的表示形式以1位開始。

如果您實際上想使用值161 ,則需要使用可以保存該值的數據類型,例如unsigned char 最簡單的方法是使pcm[]具有該類型,而不是使用強制類型轉換。

您必須使用unsigned char因為升級為int with operator |

假設int是32位:

  • 有符號的char 0xA1變為int 0xFFFFFFA1 (保持相同的值)
  • 無符號字符0xA1變為0x000000A1

您需要將charunsigned char是,允許char為有符號數據類型。 在這種情況下,將在執行|之前對它進行符號擴展| ,這意味着對於最高有效位設置為1 char ,下半部分將變為負數:

char c = 200;
int a = c | 0; // returns -56 on systems where char is signed 

在此示例中,使用static_cast或C static_cast是樣式問題。 許多C ++商店都遠離C強制轉換,因為它們很難在源代碼中找到,而static_cast容易發現。

  1. 您應該將數據類型強制轉換為無符號,因為當您“擴展”一個有符號的字符以對短進行簽名時,它的第7位將被復制到該短的第8-15位。 因此,從A110100001可以得到1111111110100001
  2. 根據此問題和答案 ,reinterpret_cast是您應該想到的最后一個演員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM