Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用指针解引用生成的不明确输出?_C_Pointers_Output_Dereference - Fatal编程技术网

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

此时,请注意:

  • unsigned
    2s补码格式中:
    0x93=147
  • signed
    2s补码格式中:
    0x93=147-256=-109

注意
1683=0x693

如果我们假设:

  • 您的硬件架构是Little Endian
  • 您的平台将字符位定义为8
然后
0x693
中的第一个
char
0x93

此时,请注意:

  • unsigned
    2s补码格式中:
    0x93=147
  • signed
    2s补码格式中:
    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)