在 C 中使用指针访问 int 变量中的字符
Accessing a character from int variable using pointer in C
为什么下面代码的输出是-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
如果 char 类型的行为与 signed char 类型相同,0x80
是 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转int后,剩下的24位填什么?
答案并不总是“0”,而是 'sign bit' -- 最高位 -- .
您可能会对以下演示代码感兴趣:
#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;
}
可以这样理解:
我们都知道(signed)char
的取值范围是[-128 to 127]
,现在我们把这个取值范围分解成二进制,那么,需要的位数是8
(1
字节)
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
的简单二进制等价物是 1000 0001
而对于 char
data-type 来说,
127
: 0111 1111
-128
: 1000 0000
-127
: 1000 0001
<-- 这里!
-126
: 1000 0010
...
因此,当 129
存储在其中时,我们得到 -127
。
为什么下面代码的输出是-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
如果 char 类型的行为与 signed char 类型相同,0x80
是 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转int后,剩下的24位填什么? 答案并不总是“0”,而是 'sign bit' -- 最高位 -- .
您可能会对以下演示代码感兴趣:
#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;
}
可以这样理解:
我们都知道(signed)char
的取值范围是[-128 to 127]
,现在我们把这个取值范围分解成二进制,那么,需要的位数是8
(1
字节)
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
的简单二进制等价物是 1000 0001
而对于 char
data-type 来说,
127
: 0111 1111
-128
: 1000 0000
-127
: 1000 0001
<-- 这里!
-126
: 1000 0010
...
因此,当 129
存储在其中时,我们得到 -127
。