簡體   English   中英

C左移和分配

[英]C left shift and assignment

請檢查下面的代碼,並讓我知道為什么這不能達到預期的效果。

#include <stdio.h>
int main()
{
  unsigned short y=0;
  unsigned char x=0xe0; //binary - 1110 0000
  unsigned char z=3;

  y = (x<< z);
  printf("\n y value is %x\n",y);
  return 0;
}

我期望y應該打印0x00,但它正在打印0x0700。 您能告訴我這里的左移和分配操作如何工作嗎?

謝謝

通過指定,按位移位運算符的左操作數將進行整數提升。

所以:

 y = (x<< z);

在這里等於:

 y = ((int) x << z);

<<表達式的結果屬於提升后的左操作數的類型,即int並且在賦值期間將其轉換為unsigned short

該操作會將您的字節提升為整數。 所以它在整數上做左移

原因是x整數提升。

C11:6.5.7逐位移位運算符(p3):

對每個操作數執行整數提升。 結果的類型是提升后的左操作數的類型。

你必須寫

y = ( unsigned char )(x<< z);

問題是integer promotion應用於運算符<<的操作數。 也就是說,具有小於int類型的等級的整數數據將隱式轉換為int類型。

所以在這個表達

x<< z

x將具有如下表示形式

00 00 00 E0

手術后的結果將顯示為

00 00 07 00

也就是說,這三個設置位將向左移,並將占據int類型對象的下一個字節。 如果將結果分配給類型為insigned short的y,則將結果的兩個低字節分配給y,並且y等於0x0700

如果使用移位運算符,則對每個操作數執行整數提升。

在您的情況下,x和z轉換為int,結果轉換回short。

請參閱以下規范的相關部分。

6.5.7按位移位運算符

對每個操作數執行整數提升。 結果的類型是提升后的左操作數的類型。

編譯器所做的事情很自然。

您試圖將結果放置在更大的空間中,所以操作員會在空間允許的范圍內進行操作,否則您將明確地相反: 0xff & mask或(unsigned char) 這反映在語言規范中。

您應該知道自己在做什么,如果您期望通過向左移動來增加價值, unsigned short 0x700那么使用0x700時您有什么想知道的呢?

如果您想進行某種過濾-為什么不使用最合適的unsigned char 造成short原因顯然是過濾方案的出站(當然,您想節省空間並編寫多合一的行,但要小心)。

暫無
暫無

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

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