C言語int回転char暗黙変換トラップ

3880 ワード

一.前言
今日コードを見ていると、問題が見つかりました.原因は分かりませんでした.問題は以下のように抽出しました.
char c = 0xFF;

if (c == 0xFF){
    printf("c == 0xFF
"
); } else{ printf("c != 0xFF
"
); }

もしあなたが答えを正確に知ることができたら、大神として本文はあなたに合わないかもしれません...答えた友达、がっかりしないで、私たちは一緒に原因を探求します!実行結果:
c != 0xFF

二.もんだいぶんせき
1.charの値をそれぞれ整数と符号なしの整数で印刷する.
char c = 0xFF;
printf("c: d[%d], u[%u]
"
, c, c);

実行結果:
c: d[-1], u[4294967295]

シンボル出力が-1であることは理解できますが、なぜシンボル出力が4バイトないのですか?(4294967295対応16進0 xFFFFFFFFFF)
2.原因、暗黙的な変換の鬼:ここでprintf%d,%uはchar回転intに関連する:文字型から整形への変換、printf関数の定義を見る:%d十進法整型出力;u十進法符号なし整数出力;一方、第1の例c==0 xFFでは、0 xFFのデフォルトは符号int型であり、タイプによっては関係演算子"==="が変換をトリガし、暗黙的な変換規則に基づいてcharもintに変換され、両者とも符号がある.
3.結論:例中char c=0 xFF;バイナリ表示:1111 1111;符号があれば-1を表し、このときint型に変換するとメモリは:0 xFFFFFFFFFF;符号なしで255を表すと、int型に変換するメモリは、0 x 0000 FFとなる.
4.例を見てみると、あなたは徹底的に理解します.
char c = 0xFF;
int n = c;
int m = (unsigned char)c;

if (n == m){
    printf("n == m
"
); } else{ printf("n != m
"
"n: d[%3d], u[%u], x[%08X]
"
"m: d[%d], u[%10u], x[%08X]
"
, n, n, n, m, m, m); }

結果:
n != m
n: d[ -1], u[4294967295], x[FFFFFFFF]
m: d[255], u[       255], x[000000FF]

三.まとめ
この例の問題はchar==intにおける暗黙的な変換によるものであり,比較時にできるだけ同じタイプを用いることを提案し,強転しなければならない場合,2つの方法で解決する.値を割り当てるときはunsigned charとして定義します.
unsigned char c = 0xFF;
if(c == 0xFF)//  

2.比較時にintを切断する:
char c = 0xFF;
if(c == (char)0xFF)//  

もし不足があれば、ご指導を惜しまないでください.ありがとうございます.