18

次のコードは正しいですか?

char mychar = 200;
printf("%x", mychar);

http://www.cplusplus.com/reference/clibrary/cstdio/printf/ によると%x、整数 (私のコンパイラでは 4 バイト) が必要で、ここでは 1 バイトしか渡しません。printfvarargs を使用するため、これはスタック上のバ​​イト アラインメントのためにのみ機能するのではないかと心配しています (つまり、スタックにプッシュされると、char は常に 4 バイトを使用します) 。

次のように書いたほうがよいと思います。

char mychar = 200;
printf("%x", static_cast<int>(mychar));

とにかく最初のコードは安全だと思いますか? そうでない場合、bigendian アーキテクチャに切り替えると、別の出力が得られると思いますか?

4

4 に答える 4

27

あなたの例では、引数は実際には typeintです。デフォルトの引数 Promotionsにより、 にmychar昇格されます。int

(C99, 6.5.2.2p6) 「呼び出された関数を示す式がプロトタイプを含まない型を持つ場合、各引数に対して整数昇格が実行され、float 型の引数は double に昇格されます。これらは呼び出されます。デフォルトの引数プロモーション。

そして(私のものを強調してください):

(C99, 6.5.2.2p7) "呼び出された関数を表す式が、プロトタイプを含む型を持つ場合、引数は、割り当てによるかのように、対応するパラメーターの型に暗黙的に変換され、それぞれの型が取得されます。パラメータは、その宣言された型の修飾されていないバージョンになります。関数プロトタイプ宣言子の省略記号表記により、最後に宣言されたパラメータの後で引数の型変換が停止します。デフォルトの引数昇格は、末尾の引数で実行されます。"

x技術的には、変換指定子にはunsigned int引数が必要ですがintunsigned int型は同じ表現を持つことが保証されていることに注意してください。

于 2012-07-11T11:53:39.307 に答える
3

intこれは、プラットフォームが(あなたのchar昇格先の) を として解釈できるため、あなたにしか機能しません。unsignedこれが%x期待されていることです。これが常に機能することを確認するには、適切な書式指定子、つまり を使用する必要があります%d

数値として使いたいようなのでchar、2種類を使い分けるsigned charunsigned char、意図を明確にした方が良いでしょう。charプラットフォームの機能に応じて、符号付きまたは符号なしの型にすることができます。の正しい指定子はunsigned charになります%hhx

于 2012-07-11T12:04:13.883 に答える
0

単純にprintf("%hhx", mychar) を使用してください。また、cplusplus.com を参照として使用しないでください。この質問は、多くのエラーが含まれ、多くの情報が省略されているという評判を証明するだけです.

于 2012-07-13T18:18:57.987 に答える
-1

C++ を使用している場合は、代わりにストリームを使用することをお勧めします。

文字を整数にキャストする必要があります。そうしないと、グリフとして出力されます。また、符号付き文字はキャスト時に符号拡張されるため、unsigned char を使用することをお勧めします。たとえば、最初に unsigned char にキャストしない限り、0xFF を保持する char は 0xFFFFFFFF として出力されます。

#include <iostream>
#include <iomanip>

int main(void){

    char c = 0xFF;
    std::cout << std::hex << std::setw(2) << std::setfill('0');
    std::cout << static_cast<int>(static_cast<unsigned char>(c)) << std::endl;

    return 0;
}
于 2012-07-11T12:20:26.293 に答える