C 使用指针解引用生成的不明确输出?
我遇到了以下程序,无法理解输出是如何变成C 使用指针解引用生成的不明确输出?,c,pointers,output,dereference,C,Pointers,Output,Dereference,我遇到了以下程序,无法理解输出是如何变成-109 1683。输出是如何变成这样的 #include <stdio.h> int main() { int k = 1683; char *a = (char *)&k; int *l = &k; printf("%d " , *a); printf("%d" , *l); } Output is : -109 1683 #包括 int main() { int k=1683; 字符*a=(字符*
-109 1683
。输出是如何变成这样的
#include <stdio.h>
int main()
{
int k = 1683;
char *a = (char *)&k;
int *l = &k;
printf("%d " , *a);
printf("%d" , *l);
}
Output is : -109 1683
#包括
int main()
{
int k=1683;
字符*a=(字符*)&k;
int*l=&k;
printf(“%d”,*a);
printf(“%d”,*l);
}
输出为:-109 1683
取消对指针a
的引用如何给我-109
我希望它读取四字节整数的第一个字节
二进制表示法中的
1683
是00000000000000000000110010011
。因此读取第一个字节意味着输出应该是0 1683
。在幕后发生的事情,我听到了一些关于架构终结性的东西,但我无法理解。在大多数平台上,“char”和“int”类型的大小不同。具体来说,“int”通常为32或64位(4或8字节),而char仅为8位(1字节)。当取消引用“char”时,您要求程序将“int”的内存位置“解释”为“char”
此外,“int”的字节存储在内存中,可以是little-endian,也可以是big-endian(Google-it)。因此,您的程序的结果将因平台而异
如果您在x86上运行代码(这是little endian),那么如果您将“int”设置为小于128的值,则可能会看到“correct”值
更新:
正如您正确指出的,int的最低有效字节是
10010011
,它是147
的小数点,因此大于10000000
(128位小数)。由于设置了字节的最高位,因此该值被解释为-109
的2补码(Google it)负值。在大多数平台上,“char”和“int”类型的大小不同。具体来说,“int”通常为32或64位(4或8字节),而char仅为8位(1字节)。当取消引用“char”时,您要求程序将“int”的内存位置“解释”为“char”
此外,“int”的字节存储在内存中,可以是little-endian,也可以是big-endian(Google-it)。因此,您的程序的结果将因平台而异
如果您在x86上运行代码(这是little endian),那么如果您将“int”设置为小于128的值,则可能会看到“correct”值
更新:
正如您正确指出的,int的最低有效字节是
10010011
,它是147
的小数点,因此大于10000000
(128位小数)。由于设置了字节的最高位,因此该值被解释为-109
的2补码(Google it)负值。请注意1683=0x693
如果我们假设:
- 您的硬件架构是Little Endian
- 您的平台将字符位定义为8
0x693
中的第一个char
是0x93
此时,请注意:
- 在
2s补码格式中:unsigned
0x93=147
- 在
2s补码格式中:signed
0x93=147-256=-109
1683=0x693
如果我们假设:
- 您的硬件架构是Little Endian
- 您的平台将字符位定义为8
0x693
中的第一个char
是0x93
此时,请注意:
- 在
2s补码格式中:unsigned
0x93=147
- 在
2s补码格式中:signed
0x93=147-256=-109
发生这种情况是因为字节顺序:
您实际上获取字节的地址
10010011
,即-109
这是由于字节顺序:
实际上,您获取字节
10010011
的地址,即-109整数1683
等于0x00000693
(int
在现代系统中通常是32位)。在系统(如x86和x86-64)上,它像
+------+------+------+------+------+------+------+------+
| 0x93 | 0x06 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 |
+------+------+------+------+------+------+------+------+
+------+------+------+------+------+------+------+------+
|0x93 | 0x06 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00|
+------+------+------+------+------+------+------+------+
初始化指针a
时,使其指向该序列中的第一个字节,即包含值0x93
的字节,因此这是取消引用a
时得到的值
现在我们来讨论一下值0x93
如何变成-109
的问题。有两个原因:一是编译器的char
是signed
(如果char
是signed或unsigned类型,则取决于编译器)。第二个原因是因为算术。是一种能够在二进制计算机(如现代计算机)上对有符号整数进行编码的方法
基本上,对于单个8位字节,可以通过(无符号)十进制值减去256(28)得到负值。0x93
的无符号十进制值是147
,147-256
等于-109
整数1683
等于0x00000693
(int
在现代系统中通常是32位)。在系统(如x86和x86-64)上,它像
+------+------+------+------+------+------+------+------+
| 0x93 | 0x06 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 |
+------+------+------+------+------+------+------+------+
+------+------+------+------+------+------+------+------+
|0x93 | 0x06 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00|
+------+------+------+------+------+------+------+------+
初始化指针a
时,使其指向该序列中的第一个字节,即包含值0x93
的字节,因此这是取消引用a
时得到的值
现在我们来讨论一下值0x93
如何变成-109
的问题。有两个原因:一是char
与您的
00000110 10010011
^^^^^^^^
00000000 00000000 00000110 10010011
^^^^^^^^
int k = 1683 ;
int *l = &k;
int k = 1683;
char *a = &k;
int *l = &k;
BE: 00 01 02 03
+----+----+----+----+
y: | 00 | 00 | 06 | 93 |
+----+----+----+----+
LE: 00 01 02 03
+----+----+----+----+
y: | 93 | 06 | 00 | 00 |
+----+----+----+----+
(In Hexadecimal)