0

为什么下面代码的输出是-127。为什么不应该是-1?

#include<stdio.h>
int main(){
    int a = 129;
    char *ptr;
    ptr = (char *)&a;
    printf("%d ",*ptr);
    return 0;
}
4

3 回答 3

3

如果您a以十六进制输出变量,您将看到它表示为0x81.

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int a = 129;
    
    printf( "%#x\n", a );
    
    return 0;
}

它的输出是

0x81

0x80是 char 类型的对象的最小值,如果 char 类型的行为与带符号的 char 类型相同。该值等于十进制值-128

这是另一个演示程序。

#include <stdio.h>

int main(void) 
{
    char c = -128;
    
    printf( "%#hhx\n", c );
    
    return 0;
}

它的输出是

0x80

如果添加1您将获得价值-127

字符值的二进制补码表示形式-1看起来像0xff. 如果添加1您将获得0.

于 2020-08-10T00:06:50.750 回答
1

可以这样理解:

我们都知道 (signed) 的范围char是 from [-128 to 127],现在让我们把这个范围分解成二进制格式,所以,需要的位是8( 1Byte)

0 : 0000 0000
1 : 0000 0001
2 : 0000 0010
3 : 0000 0011
...
126: 0111 1110
127: 0111 1111<-- max +ve number 之后我们将溢出符号位
-128: 1000 0000<--奇怪的数字,因为数字和它的 2 的补码相同。
-127: 1000 0001
-126: 1000 0010
...
-3 : 1111 1101
-2 : 1111 1110
-1 :1111 1111


所以,现在回到问题上来 int a = 129;,很明显129,当存储在char数据类型中时,它会溢出,因为允许的最大正值为127但是为什么我们得到了-127而不是别的东西呢?

简单的二进制等价于129is1000 0001和用于char出现在某处的数据类型,

127: 0111 1111
-128: 1000 0000
-127: 1000 0001<--这里!
-126: 1000 0010
...
所以,我们得到的-127时候129是存储在里面的。

于 2020-08-10T02:02:14.843 回答
0

当您将有符号字符转换为 int 时,左 24 位将填充什么?答案并不总是“0”,而是“符号位”——最高位——。

您可能对以下演示代码感兴趣:

#include<stdio.h>
int main(){
    int a = 129;
    char *ptr;
    ptr = (char *)&a;
    
    // output "0x81", yes  129 == 0x81
    printf("0x%hhx\n",*ptr);


    // output 0xffffff81
    int b = *ptr;   // convert a 'signed char' to 'int'
                    // since the 'sign bit' of the char is 'minus', so left padding that much '1'
    printf("0x%x\n",b);
    
    unsigned char *ptru = (unsigned char *)&a;
    b = *ptru;
    printf("0x%x\n",b);  // still, output "0x81" 

    return 0;
}

于 2020-08-10T01:23:59.617 回答