[英]Pointers in C with typecasting
#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;
}
我无法掌握输出是如何513甚至机器依赖的事实? 我可以感觉到类型转换正在发挥重要作用,但幕后发生了什么,有人可以帮助我想象这个问题吗?
int a
作为4个字节存储在内存中。 数字512
在您的机器上表示为:
0 2 0 0
分配给x[0]
和x[1]
,它将其更改为:
1 2 0 0
这是513
。
这与机器有关,因为C语言没有指定多字节数字中的字节顺序。
为简化假设以下内容:
在第3行x中引用a作为char,这意味着x认为他指向了一个char(他不知道a实际上是一个int。
第4行是为了让你感到困惑。 别。
第5行 - 因为x认为他指向一个字符x [0] = 1只改变a的第一个字节(因为他认为他是一个字符)
第6行 - 再一次,x改变了a的第二个字节。
请注意,第5行和第6行中的值位于第4行的值之上.a的值现在为0 ... 0000 0010 0000 0001(513)。
现在当我们打印一个int作为int时,所有4个字节都将被视为预期。
我无法理解输出如何是513甚至是机器依赖的事实
输出是实现定义的。 它取决于CPU对整数解释的字节顺序 ,通常称为字节序 。
我可以感觉到类型转换正在发挥重要作用
代码重新解释的值a
,这是一个int
,作为字节数组。 它使用两个初始字节,保证可以工作,因为int
大小至少为两个字节。
有人可以帮助我想象这个问题吗?
int
由多个字节组成。 它们可以作为一个表示整数的单元来寻址,但它们也可以作为字节集合进行寻址。 int
的值取决于您设置的字节数,以及CPU对整数的解释中这些字节的顺序。
看起来你的系统将最低有效字节存储在最低地址,因此将1
和2
存储在偏移0和1的结果产生这种布局:
Byte 0 Byte 1 Byte 2 Byte 3
------ ------ ------ ------
1 2 0 0
整数值可以如下计算:
1 + 2*256 + 0*65536 + 0*16777216
通过取x
(它是一个char *
)并将其指向a
的地址(即int
,可以使用x
来修改表示a
的各个字节。
您看到的输出表明int
以little-endian格式存储,这意味着最不重要的字节首先出现。 但是,如果您在另一个系统上运行此代码(例如,大型enidan的Sun SPARC计算机),则可能会发生这种情况。
首先将a
设置为512.在十六进制中,即0x200
。 因此,假设以小端格式表示32位int
a
的内存布局如下:
-----------------------------
| 0x00 | 0x02 | 0x00 | 0x00 |
-----------------------------
接下来将x[0]
设置为1,这将更新a
表示中的第一个字节(在这种情况下保持不变):
-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------
然后将x[1]
设置为2,这将更新a
表示中的第二个字节:
-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------
现在a
的值为0x201,十进制为513。
除了之前的答案之外,让我试着为你解决这个问题:
#include<stdio.h>
int main()
{
int a; //declares an integer called a
char *x; //declares a pointer to a character called x
x = (char *) &a; //points x to the first byte of a
a = 512; //writes 512 to the int variable
x[0] = 1; //writes 1 to the first byte
x[1] = 2; //writes 2 to the second byte
printf("%d\n",a); //prints the integer
return 0;
}
请注意,我写了第一个字节和第二个字节。 根据平台的字节顺序和整数的大小,您可能得不到相同的结果。
让我们看一下32位或4字节大小的内存:
first byte | second byte | third byte | forth byte
0x00 0x02 0x00 0x00
现在为第一个字节分配1,为第二个字节分配2,这给我们留下了:
first byte | second byte | third byte | forth byte
0x01 0x02 0x00 0x00
请注意,第一个字节更改为0x01
而第二个字节已经是0x02
。 内存中的这个新数字相当于小端系统上的513
。
让我们看一下如果你在一个大端平台上尝试这个会发生什么:
first byte | second byte | third byte | forth byte
0x00 0x00 0x02 0x00
这次将1分配给第一个字节,将2分配给第二个字节给我们留下:
first byte | second byte | third byte | forth byte
0x01 0x02 0x02 0x00
相当于16,908,800
整数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.