2016-02-19 88 views
1
char xtime(char m) 
{ 
    //calculates the m value by checking m,if m is less than 0x80 hexadecimal 
    // then it is left shifted else it is left shifted and xor'ed with 0x1b. 
    if(m<0x80) 
    { 
     m<<=1; 
    } else { 
     m=(((m)<<1)^0x1b); 
    } 

    printf("%#01x ",m&0xff); 
    return m; 
} 

如果m = 0x80(這是0x1b),此代碼不顯示預期的輸出,它以十六進制的形式給出輸出0。具有相同邏輯的兩段代碼。一個給出預期的輸出,另一個不給出

#define xtime(a) (((a)<0x80)?(a)<<1:(((a)<<1)^0x1b)) 

此代碼的工作原理,並給出了預期的結果。

請問功能代碼出了什麼問題,以及第二個代碼是如何解決的。

+4

'char'可能會根據環境進行簽名,如果'char'是8位長並且被簽名,則'0x80'可能不適合它。如果int類型的值被傳遞,第二個代碼應該可以工作,因爲int可以保存至少32767的整數。 – MikeCAT

+3

對於字符只使用'char'是個好主意。如果您需要一個小整數類型,請使用'signed char'或'unsigned char'。就你而言,後者似乎是你需要的。 –

+0

對於C++,您應該考慮'inline'而不是宏。 – crashmstr

回答

2

假設您的環境中

  • char簽訂
  • char是8位長
  • 二進制補碼是用來表達負整數
  • 如果有符號整數轉換爲不能存儲原始值,高位被簡單扔掉

0x80太大而無法存儲到char變量中,並且它將被解釋爲-128-128小於0x80,所以執行m <<= 1;。 該轉變的結果是-256,其二進制表示是0xffffff00,而m將得到最後8位,即0。這就是你得到的。

如果0x80傳遞給a,因爲計算將使用int完成宏將工作,int可容納高達整數至少32767

+0

Plus有符號整型溢出是未定義的行爲。 – YSC

+0

@YSC我認爲'm'作爲操作數將通過整數升級轉換爲'int',因爲另一個操作數'1'是'int',並且轉換爲小型有符號整數是由實現定義的(N1256 6.3.1.3)。我錯了嗎? – MikeCAT

+0

這更糟糕:事實上'因爲'm'是'signed char',所以'if(m <0x80)'總是爲真。 – YSC