![](/img/trans.png)
[英]What is the difference between directly assigning the result of left shift operation to a variable and the left shift assignment operation in 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
整數提升。
對每個操作數執行整數提升。 結果的類型是提升后的左操作數的類型。
你必須寫
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.