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 只使用最后一个字节?

它没有。它被告知要打印一个有符号的int,因此它从堆栈中获取适当数量的字节 - 现在通常为 4 个 - 并将该位模式解释为有符号int

当您将负数分配给char变量int时,就像在int j = i;这里一样,发生的事情并不是真正的符号扩展,而是 - 因为 achar可以表示的所有值也可以表示为int- 保值转换,所以char i转换为int具有相同的价值。

在迄今为止最常见的二进制补码机器上,以及在二进制补码中,保值转换恰好与符号扩展一致,但如果表示是符号和幅度,则转换会有所不同。

由于 -128 不能表示为 1 的补码或符号和幅度中的有符号 8 位整数,让我们看看在将 -127 转换为具有相同类型的 32 位有符号整数时位模式会发生什么表示:

二进制补码:

10000001 -> 11111111 11111111 11111111 10000001

一个的补码:

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

您强制强制转换以查看整数的第一个字节:

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

要将第二个字节视为十进制,您可以强制进行强制转换:

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

整数的最后一个字节:

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

您的程序通过将错误的类型传递给printf. %u需要一个unsigned参数,但您传递了一个 (signed) intprintf不“知道该做什么”,因为它不需要做任何特别的事情;因为你调用了UB,所以无论发生什么都是自由的。

于 2012-07-22T19:36:16.390 回答
1

这是一个简单的测试程序,可以帮助您了解发生了什么。请注意,它使用 C99 长度修饰符hh,这意味着:

hh指定后面的d, i, o, u, x, 或X转换说明符应用于 signed charorunsigned char参数(该参数将根据整数提升进行提升,但其值应转换为signed charunsigned 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(所以 '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 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 回答