1

型のない言語 (PHP) から来たので、C のデータ型について少し混乱しています。次の奇妙な動作に直面しています。

//First case
unsigned int a;
a = -1;
printf("a = %u", a); //Outputs a strange number, no problem here

//Second case
unsigned int a;
a = -1;
printf("a = %d", a); //Outputs -1

私が理解していないのはa、署名された値がどのように「含まれている」unsignedかです。

2番目のケースで出力をフォーマットするだけで、どうすればそれを行うことができますか?

4

4 に答える 4

4

他の人がすでに述べたように、Cではこれら2つの概念が大きく分離されているため、値とその表現の違いを常に念頭に置く必要があります。

割り当てを使用すると、メモリの特定の領域に値を入力します。printf()などを使用して、そのような値を解釈しようとします。

明確にするために、これを理解してみてください。

#include <stdio.h>

int main() {   
    int val = 2181448;;
    printf("%s\n", ((char*)&val));   // * Outputs: "HI!"
    return 0;
}   

「HI!」と表示されます 割り当てでは、メモリの連続した領域(ここでは、「int」は少なくとも4バイト幅です)に数値「2181448」を配置します。これは、16進数で0x00214948です。つまり、次のようになります。

  • 値が0x00、つまりゼロのバイト
  • 値が0x21、つまり10進数で33のバイト、つまり'!' アスキーで
  • 0x49のバイト、つまり10進数で73、つまりASCIIでは「I」
  • 最後に、値が0x48で、10進数で72であり、ASCIIでは「H」であるバイト。

printfに文字列として解釈させると(キャストはコンパイラの警告を回避するためだけのものであることに注意してください)(*エンディアンが逆になるため)、ゼロで終了する4つの長さの文字列'H''I''などの数値が出力されます。 ' '\ 0'

于 2012-09-11T09:08:14.507 に答える
3

それがすることだからですprintf。指定された値の型がわかりません。そのため、見つけたデータを受け取り、それをa符号付き整数として解釈します%d

printfまた、書式設定コードに間違った値を入力したり、完全に省略したりすると、非常に危険です。プログラムは何のメッセージもなくクラッシュします。

于 2012-09-11T06:18:55.823 に答える
2

は次の-1ように表されます10000000 00000000 00000000 00000001int私の場合のように4バイトの場合)。で出力すると%d、 は通常の intprintf()として解釈するため、先頭を記号として解釈し、 を出力します。として出力すると、署名されていないことがわかり、先頭が として解釈され、結果として出力されます。1-1%uprintf()12^324294967295

于 2012-09-11T06:17:53.357 に答える
2

コンパイラは、-1 をシステムの正しい符号付き数値形式に変換します。すべてのケースの 99.9% で、これは 2 の補数になります。32 ビット整数の 2 の補数システムでは、-1 は 0xFFFFFFFF に対応します。しかし、それを符号なし変数に格納すると、値は 42.9 億になります。

次に、負の数値用に予約されている %d 書式指定子を使用して、42.9 億を印刷しようとします。次に、プログラムは 0xFFFFFFFF を再び -1 として解釈します。

要約すると、バイナリ レベルで負の数などというものはありません。2 進数の表示方法によっては、負の数を形成できます。それでも、すべて 1 と 0 だけです。マイナス記号をコンピューターのメモリ セルに保存することはできません。

于 2012-09-11T06:22:21.047 に答える