为什么下面代码的输出是-127。为什么不应该是-1?
#include<stdio.h>
int main(){
int a = 129;
char *ptr;
ptr = (char *)&a;
printf("%d ",*ptr);
return 0;
}
为什么下面代码的输出是-127。为什么不应该是-1?
#include<stdio.h>
int main(){
int a = 129;
char *ptr;
ptr = (char *)&a;
printf("%d ",*ptr);
return 0;
}
如果您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
.
可以这样理解:
我们都知道 (signed) 的范围char
是 from [-128 to 127]
,现在让我们把这个范围分解成二进制格式,所以,需要的位是8
( 1
Byte)
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
而不是别的东西呢?
简单的二进制等价于129
is1000 0001
和用于char
出现在某处的数据类型,
127
: 0111 1111
-128
: 1000 0000
-127
: 1000 0001
<--这里!
-126
: 1000 0010
...
所以,我们得到的-127
时候129
是存储在里面的。
当您将有符号字符转换为 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;
}