2009-07-21 9 views
2

私はbig and little-endiannessを勉強しています。エンディアンに関するCコードを理解するには

1. | \の目的は次のコードに含まれていますか?

... 

#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) 

    #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ 
        (((uint16_t)(A) & 0x00ff) << 8)) 
... 

2.コードで(A)の目的は何ですか?

+0

ありがとうございました! –

+1

マスクと0xff00または&0x00ffのどちらも必要ありません。最初のケースでは、下から8ビットはマスクされます。後者の場合、ビットはオーバーフローして失われます。 (uint16_t)((uint16_t)(A)>> 8)|((uint16_t)(A)<< 8)))は同じ結果になります –

+0

@Tom Leysは2番目のケースについて同意しません。 '(((uint16_t)(A))<< 8))'となります。 'A'はその16個のLSビットを保持する' uint16_t'にキャストされます。次に、通常の整数宣伝が考えられます。これは例えば32ビットの 'int'になります。その値はシフト8されます。 – chux

答えて

16

'|'ビットごとのOR演算子です。基本的には値を組み合わせています。 'A'は#define htonsのパラメータです。式がプログラマまたはコンパイラを混乱させないように、カッコで囲まれています。 '\'はマクロを次の行に続けます。 (マクロは通常、行末で終了します)

このマクロは、Aの16ビット値を取り、上位8ビットをマスクします。それはその値をとり、右に8ビットシフトします。これは、上位8ビットが現在16ビット値の最下部にあることを意味します。次に、Aの元の値の上位8ビットをマスクし、その8ビットをシフトします。つまり、下位8ビットがトップになります。最後に、2つの値を1つの値に再結合します。

最終的に、トップとボトムのそれぞれの場所が入れ替えられました。

3

| 2つの整数でビット単位の "OR"を実行します。 \は#defineを次の行に割り当てるエスケープ文字です

+0

質問に30秒遅れてしまったようです。 :P – Victor

4

このコードは標準のCプリプロセッサマクロです。

|はビット単位のOR演算子です。 \は改行をエスケープし、#defineは次の行に進むことができます。 (A)はマクロのパラメータです。

2

これはマクロなので、使用すると拡大されます。

これは、関数内の変数とは違っていないことだ

uint16_t i = ((((uint16_t)(0x1234) & 0xff00) >> 8) |(((uint16_t)(0x1234) & 0x00ff) << 8)); 

、例えば:にそれが拡大します

uint16_t i = htons(0x1234); 

としてマクロ(「コール」)を使用

uint16_t htons(uint16_t A) 
{ 
    return (A & 0xff00) >> 8) | (A & 0x00ff) << 8); 
} 
+0

すばらしい例! –

+1

'8)'の最後のコードに2つの ')'がありますか? –

+2

C/C++プログラマーにとって最も重要な啓示の1つは、 'uint16_t i = 0x1233; uint16_t j = htons(i ++); 'の結果が返されます。 –

関連する問題