0
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
    char i = -128; 
    int j = i; 
    printf("%d %u\n", j, j); 
   return 0;
}

結果は-128 4294967168

私が思うのは

i: 10000000 

代入演算子の後、符号拡張を行います

j: 11111111 11111111 11111111 10000000 

私が聞きたいのは、ただ使うだけprintf("%d",j)で印刷する方法を知ることです-128

最後のバイト?使い方?

どうも!

4

5 に答える 5

6

私が聞きたいのは、printf("%d",j) が最後のバイトを使用して -128 を出力することをどのように知っているかということです。

そうではありません。signed を出力するように指示されているintため、スタックから適切なバイト数 (最近では通常 4) を取得し、そのビット パターンを signed として解釈しますint

ここのように変数に負charを代入すると、実際には符号拡張ではなく、 aが表すことができるすべての値は a としても表すことができるため、値を保持する変換が行われ、 は同じ値でan に変換されます。価値。intint j = i;charintchar iint

現在最も一般的な 2 の補数マシン (1 の補数マシンでも) では、その値を保存する変換はたまたま符号拡張と一致しますが、表現が符号と大きさである場合、変換は異なります。

-128 は 1 の補数または符号と大きさで符号付き 8 ビット整数として表現できないため、-127 を同じ種類の符号付き 32 ビット符号付き整数に変換するときにビットパターンに何が起こるかを見てみましょう表現:

2 の補数:

10000001 -> 11111111 11111111 11111111 10000001

1 の補数:

10000000 -> 11111111 11111111 11111111 10000000

符号と大きさ:

11111111 -> 10000000 00000000 00000000 01111111
于 2012-07-22T19:29:05.220 に答える
2

-128 の符号なしバージョン (この場合はint ) を出力するだけです。

于 2012-07-22T19:28:47.463 に答える
1

あなたのプログラムは、間違った型を に渡すことによって、未定義の動作を呼び出していprintfます。%u引数unsignedが必要ですが、 (signed) を渡しましたintprintf特に何もする必要がないため、「何をすべきかわからない」。UB を呼び出したために何が起こっても自由です。

于 2012-07-22T19:36:16.390 に答える
1

何が起こっているのかを理解するのに役立つ簡単なテスト プログラムを次に示します。C99 の長さ修飾子 を使用していることに注意してください。つまり、次のことhhを意味します。

hhdの , i, o, u,xまたはX変換指定子が signed charorunsigned char引数に適用されることを指定します (引数は整数の昇格に従って昇格されますが、その値はsigned charまたはunsigned charに変換されてから出力されます)。または、次のn変換指定子が引数へのポインターに適用されsigned char ます。

これは、型がどのように処理されるかを理解するのに役立ちます。

#include <stdio.h>
#include <limits.h>

static void print_value(signed char sc, unsigned char uc, /*plain*/ char pc)
{
    int j1 = sc;
    int j2 = uc;
    int j3 = pc;
    printf("%-9s  %4hhd %4hhu %4d 0x%hhX %10u\n", "Signed:",   j1, j1, j1, j1, j1);
    printf("%-9s  %4hhd %4hhu %4d 0x%hhX %10u\n", "Unsigned:", j2, j2, j2, j2, j2);
    printf("%-9s  %4hhd %4hhu %4d 0x%hhX %10u\n", "Plain:",    j3, j3, j3, j3, j3);
}

static void check_value(int i)
{
        signed    char sc = i;
        unsigned  char uc = i;
        /*plain*/ char pc = i;
        print_value(sc, uc, pc);
}

int main(void)
{
    for (int i = 0; i <= 3; i++)
        check_value(i);
    for (int i = SCHAR_MAX - 3; i <= SCHAR_MAX+3; i++)
        check_value(i);
    for (int i = UCHAR_MAX - 3; i <= UCHAR_MAX; i++)
        check_value(i);
    return 0;
}

-fsigned-char(「プレーン」は符号付きタイプです)でコンパイルするとchar、出力は次のようになります。

Signed:       0    0    0 0x0          0
Unsigned:     0    0    0 0x0          0
Plain:        0    0    0 0x0          0
Signed:       1    1    1 0x1          1
Unsigned:     1    1    1 0x1          1
Plain:        1    1    1 0x1          1
Signed:       2    2    2 0x2          2
Unsigned:     2    2    2 0x2          2
Plain:        2    2    2 0x2          2
Signed:       3    3    3 0x3          3
Unsigned:     3    3    3 0x3          3
Plain:        3    3    3 0x3          3
Signed:     124  124  124 0x7C        124
Unsigned:   124  124  124 0x7C        124
Plain:      124  124  124 0x7C        124
Signed:     125  125  125 0x7D        125
Unsigned:   125  125  125 0x7D        125
Plain:      125  125  125 0x7D        125
Signed:     126  126  126 0x7E        126
Unsigned:   126  126  126 0x7E        126
Plain:      126  126  126 0x7E        126
Signed:     127  127  127 0x7F        127
Unsigned:   127  127  127 0x7F        127
Plain:      127  127  127 0x7F        127
Signed:    -128  128 -128 0x80 4294967168
Unsigned:  -128  128  128 0x80        128
Plain:     -128  128 -128 0x80 4294967168
Signed:    -127  129 -127 0x81 4294967169
Unsigned:  -127  129  129 0x81        129
Plain:     -127  129 -127 0x81 4294967169
Signed:    -126  130 -126 0x82 4294967170
Unsigned:  -126  130  130 0x82        130
Plain:     -126  130 -126 0x82 4294967170
Signed:      -4  252   -4 0xFC 4294967292
Unsigned:    -4  252  252 0xFC        252
Plain:       -4  252   -4 0xFC 4294967292
Signed:      -3  253   -3 0xFD 4294967293
Unsigned:    -3  253  253 0xFD        253
Plain:       -3  253   -3 0xFD 4294967293
Signed:      -2  254   -2 0xFE 4294967294
Unsigned:    -2  254  254 0xFE        254
Plain:       -2  254   -2 0xFE 4294967294
Signed:      -1  255   -1 0xFF 4294967295
Unsigned:    -1  255  255 0xFF        255
Plain:       -1  255   -1 0xFF 4294967295

-funsigned-char (so 'plain'char` でコンパイルすると、符号なしの型になります)、出力は次のようになります。

Signed:       0    0    0 0x0          0
Unsigned:     0    0    0 0x0          0
Plain:        0    0    0 0x0          0
Signed:       1    1    1 0x1          1
Unsigned:     1    1    1 0x1          1
Plain:        1    1    1 0x1          1
Signed:       2    2    2 0x2          2
Unsigned:     2    2    2 0x2          2
Plain:        2    2    2 0x2          2
Signed:       3    3    3 0x3          3
Unsigned:     3    3    3 0x3          3
Plain:        3    3    3 0x3          3
Signed:     124  124  124 0x7C        124
Unsigned:   124  124  124 0x7C        124
Plain:      124  124  124 0x7C        124
Signed:     125  125  125 0x7D        125
Unsigned:   125  125  125 0x7D        125
Plain:      125  125  125 0x7D        125
Signed:     126  126  126 0x7E        126
Unsigned:   126  126  126 0x7E        126
Plain:      126  126  126 0x7E        126
Signed:     127  127  127 0x7F        127
Unsigned:   127  127  127 0x7F        127
Plain:      127  127  127 0x7F        127
Signed:    -128  128 -128 0x80 4294967168
Unsigned:  -128  128  128 0x80        128
Plain:     -128  128  128 0x80        128
Signed:    -127  129 -127 0x81 4294967169
Unsigned:  -127  129  129 0x81        129
Plain:     -127  129  129 0x81        129
Signed:    -126  130 -126 0x82 4294967170
Unsigned:  -126  130  130 0x82        130
Plain:     -126  130  130 0x82        130
Signed:      -4  252   -4 0xFC 4294967292
Unsigned:    -4  252  252 0xFC        252
Plain:       -4  252  252 0xFC        252
Signed:      -3  253   -3 0xFD 4294967293
Unsigned:    -3  253  253 0xFD        253
Plain:       -3  253  253 0xFD        253
Signed:      -2  254   -2 0xFE 4294967294
Unsigned:    -2  254  254 0xFE        254
Plain:       -2  254  254 0xFE        254
Signed:      -1  255   -1 0xFF 4294967295
Unsigned:    -1  255  255 0xFF        255
Plain:       -1  255  255 0xFF        255

Mac OS X 10.7.4 上の GCC 4.7.1 でコンパイルされています (ただし、プラットフォームの標準 C ライブラリを使用しています)。

于 2012-07-22T20:10:29.867 に答える
1

整数の最初のバイトを見るようにキャストを強制します。

char j = -128; 
printf("%d", (char) j); 

2 番目のバイトを 10 進数として表示するには、次のいずれかのキャストを強制します。

printf("%d", *(((char *) &j) + 1 ) ); 

整数の最後のバイト:

printf("%d", *(((char *) &j) + 3 ) ); 
于 2012-07-22T19:32:58.667 に答える