2017-01-22 5 views
3
#include <stdio.h> 
#include <stdint.h> 
typedef unsigned char  uint8_t; 
typedef short    int16_t; 
typedef unsigned short  uint16_t; 
typedef int     int32_t; 
typedef unsigned int  uint32_t; 
int main(){ 
    uint8_t ball; 
    uint8_t fool; 
    ball=((unsigned char)13); 
    fool=((unsigned char)14); 
    uint16_t combined_value1=((uint16_t)ball)<<12+((uint16_t)fool)<<8; // WRONG ONE 
    uint16_t combined_value2=((uint16_t)ball<<12)+((uint16_t)fool<<8); 
    printf("%hu\n",(uint16_t)combined_value1); 
    printf("%hu\n",(uint16_t)combined_value2); 
    return 0; 
} 

なぜ「combined_value1」の値が間違っていますか?ここで、ボールとフールは0から15までの値をとり、combined_valueを{ball [4 bits]:fool [4 bits]:[8 zero bits]}として連結しようとしています。 intへの昇進後がかかるので(uint16_t)キャスティングは、この文脈ではあまり意味がありませんのでご注意くださいタイプキャスティングとビット操作ミステリー

+1

あなたのtypedefがおそらく 'stdint.h'と競合している可能性はありますか?実際には、ヘッダーの全体が、追加したもののようなtypedefを排除します。 – StoryTeller

答えて

5

+precedence<<よりも持っているので、

((uint16_t)ball)<<12+((uint16_t)fool)<<8; 

((uint16_t)ball) << (12+((uint16_t)fool)) << 8; 

として評価されます場所。代わりに、検討する

uint16_t combined_value = (uint16_t)((ball<<12) + (fool<<8)); 

他にもいくつかの冗長なキャストがあります。 @ StoryTellerが提案されているので、stdint.hを含めると良いでしょう。

+1

[** C Operator Precedence Table **](http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm)へのリンクは、「+」と「<<」だけでなく'が、将来的にはすべての演算子を対象にしています。 –

+0

@ DavidC.Rankinありがとう、私はあまりにも投稿へのリンクを追加しました。 – AlexD

+0

それは良い答えですが、私はいつも彼がそれに遭遇したときに自分自身で問題を解決することができるように、質問者の指示を参照に与えるようにしています。 (古い "人に魚を与えて、一日彼に食べさせてください。魚を釣る人に教えて、人生のために養う...アナロジー)。 –