C++ 关于机器相关指针值的混淆

C++ 关于机器相关指针值的混淆,c++,c,arrays,pointers,char,C++,C,Arrays,Pointers,Char,我对C语言中的指针做了一点回顾,我被我遇到的一些代码弄糊涂了。我在qeeksquiz.com/pointers上做了一个小测验来复习,我发现了这段代码: #include<stdio.h> int main() { int a; char *x; x = (char *) &a; a = 512; x[0] = 1; x[1] = 2; printf("%d\n",a); return 0; } #包

我对C语言中的指针做了一点回顾,我被我遇到的一些代码弄糊涂了。我在
qeeksquiz.com/pointers
上做了一个小测验来复习,我发现了这段代码:

#include<stdio.h> 
int main() 
{ 
   int a; 
   char *x; 
   x = (char *) &a; 
   a = 512; 
   x[0] = 1; 
   x[1] = 2; 
   printf("%d\n",a);   
   return 0; 
}
#包括
int main()
{ 
INTA;
char*x;
x=(字符*)&a;
a=512;
x[0]=1;
x[1]=2;
printf(“%d\n”,a);
返回0;
}
当我遇到
x=(char*)&a
时,我有点困惑。我知道x是一个指针,它保存a的地址,但是当我们分配
x[0]=1
x[1]=2时打印时的答案是513。答案是关于它如何依赖于我们使用的机器,以及小端机如何改变它读取二进制文件的方式。我完全搞不清楚我们是如何从512到513的。我猜这是因为x[0]=1,但我不是100%确定。有人能解释一下吗?如果我们将
x[0]=2
,那么更改的值是多少


谢谢你的帮助

由于x是指向char的指针,这意味着x[0]和x[1]是对单字节数据的引用,所以在内存中有如下数据:

1 2
但是,在输出过程中,您试图引用16/32位的相同数据,因此我们没有2个单字节,而是1个字,作为0x01 0x02存储在内存中,对于小端,这意味着我们应该交换它们,所以我们得到了数字0x201,以十进制表示法表示为513


对于big-endian,它将是0x102,十进制为258,因为x是指向char的指针,这意味着x[0]和x[1]是单字节数据的引用,所以在内存中有如下数据:

1 2
但是,在输出过程中,您试图引用16/32位的相同数据,因此我们没有2个单字节,而是1个字,作为0x01 0x02存储在内存中,对于小端,这意味着我们应该交换它们,所以我们得到了数字0x201,以十进制表示法表示为513

对于big-endian,它将是0x102,十进制为258

                   Little endian              Big endian

               +----+----+----+----+     +----+----+----+----+
a = 0x200:     | 00 | 02 | 00 | 00 |     | 00 | 00 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

               +----+----+----+----+     +----+----+----+----+
x[0] = 1:      | 01 | 02 | 00 | 00 |     | 01 | 00 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

               +----+----+----+----+     +----+----+----+----+
x[1] = 2:      | 01 | 02 | 00 | 00 |     | 01 | 02 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

result:          1x1 + 2x256 = 513     1x16777216 + 1x65536 + 2x256 + 0x1 = big
ASCII艺术

                   Little endian              Big endian

               +----+----+----+----+     +----+----+----+----+
a = 0x200:     | 00 | 02 | 00 | 00 |     | 00 | 00 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

               +----+----+----+----+     +----+----+----+----+
x[0] = 1:      | 01 | 02 | 00 | 00 |     | 01 | 00 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

               +----+----+----+----+     +----+----+----+----+
x[1] = 2:      | 01 | 02 | 00 | 00 |     | 01 | 02 | 02 | 00 |
               +----+----+----+----+     +----+----+----+----+

result:          1x1 + 2x256 = 513     1x16777216 + 1x65536 + 2x256 + 0x1 = big

整数由字节序列组成。但是在不同的系统中,字节的顺序是不同的。例如,考虑数字134480385(二进制=10000,100000,10000,10000,10000,100000,000)。在little endian系统中,它是(最低地址在左边)

00000001100000010000010000001000

但在大端系统中,字节的存储方式是相反的。左边仍然是最低的地址

0000100000001000001000000001

当您获取整数a的地址并转换为字符(字节)指针时,它将指向整数中的第一个字节(最低地址)。将1写入指针时,最低字节设置为00000001。但是,char只有1字节长,因此其他字节不变。然后将第二个字节设置为00000010

在您的示例中,512 In little endian是

00000000000010

Big-endian更复杂,因为结果取决于int中的字节数。它通常是4,但可能是2或更多。作为2字节整数,内存中的512是

000000100000000

作为一个4字节的int,它是

000000000000000000000000100000000

(这对于little endian并不重要,因为额外的字节只是零)

将1写入第一个字节,将2写入第二个字节后,您将在内存中获得一个4字节的小尾端

0000000110000001000000000000

一个4字节的big-endian

000000010000000100000000

注意,第三个字节中的位仍然存在。这是因为我们只写入了前两个字节。第三和第四个字节不变

和一个2字节的大端号

00000001100000010

将2字节或4字节内存(2字节忽略额外的零)解释为与正常二进制数一样小的尾数

000000000000000001000000001=513

将4字节内存解释为big-endian数是一个普通的二进制数

0000000 1000000000001000000000=16908800

将2字节内存解释为big-endian数,即正常的二进制数

0000000 10000010=258


我可能在计算中出错了,但希望你能理解。这就是为什么在不同类型的指针之间进行强制转换时需要小心的原因。

整数是由字节序列组成的。但是在不同的系统中,字节的顺序是不同的。例如,考虑数字134480385(二进制=10000,100000,10000,10000,10000,100000,000)。在little endian系统中,它是(最低地址在左边)

00000001100000010000010000001000

但在大端系统中,字节的存储方式是相反的。左边仍然是最低的地址

0000100000001000001000000001

当您获取整数a的地址并转换为字符(字节)指针时,它将指向整数中的第一个字节(最低地址)。将1写入指针时,最低字节设置为00000001。但是,char只有1字节长,因此其他字节不变。然后将第二个字节设置为00000010

在您的示例中,512 In little endian是

00000000000010

Big-endian更复杂,因为结果取决于int中的字节数。它通常是4,但可能是2或更多。作为2字节整数,内存中的512是

000000100000000

作为一个4字节的int,它是

000000000000000000000000100000000

(这对于little endian并不重要,因为额外的字节只是零)

将1写入第一个字节,将2写入第二个字节后,您将在内存中获得一个4字节的小尾端

0000000110000001000000000000

一个4字节的big-endian

000000010000000100000000

记下表中的位