#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甚至是机器依赖的事实?我可以感觉到类型转换正在发挥重要作用,但幕后发生了什么,有人可以帮助我想象这个问题吗?
答案 0 :(得分:2)
int a
以4个字节存储在内存中。数字512
在您的计算机上显示为:
0 2 0 0
当您分配到x[0]
和x[1]
时,会将其更改为:
1 2 0 0
这是数字513
。
这与机器有关,因为C语言没有指定多字节数字的字节顺序。
答案 1 :(得分:2)
为简化起见假设如下:
在第3行x中引用a作为char,这意味着x认为他指向了一个char(他不知道a实际上是一个int。
第4行是为了让你感到困惑。不。
第5行 - 因为x认为他指向一个字符x [0] = 1只改变a的第一个字节(因为他认为他是一个字符)
第6行 - 再一次,x只改变了第二个字节。
请注意,第5行和第6行中的值覆盖了第4行中的值。 a的值现在为0 ... 0000 0010 0000 0001(513)。
现在当我们打印一个int作为int时,所有4个字节都将被视为预期。
答案 2 :(得分:1)
我无法理解输出如何是513甚至机器依赖的事实
输出是实现定义的。它取决于CPU对整数的解释中的字节顺序,通常称为endianness。
我可以感觉到类型转换正在发挥重要作用
代码将a
的值重新解释为int
,作为字节数组。它使用两个初始字节,保证可以工作,因为int
的大小至少为两个字节。
有人可以帮我看看这个问题吗?
int
由多个字节组成。它们可以作为一个表示整数的单元来寻址,但它们也可以作为字节集合进行寻址。 int
的值取决于您设置的字节数,以及CPU对整数解释中这些字节的顺序。
看起来您的系统将最低有效字节存储在最低地址,因此将1
和2
存储在偏移为零的结果,并生成此布局:
Byte 0 Byte 1 Byte 2 Byte 3
------ ------ ------ ------
1 2 0 0
整数值可以按如下方式计算:
1 + 2*256 + 0*65536 + 0*16777216
答案 3 :(得分:1)
通过x
char *
,并将其指向a
的地址int
,您可以使用x
修改代表a
的单个字节。
您看到的输出表明int
以小端格式存储,这意味着最低有效字节首先出现。但是,如果您在另一个系统上运行此代码(例如,大型enidan的Sun SPARC计算机),则可能会发生这种情况。
您首先将a
设置为512.在十六进制中,即0x200
。因此a
的内存假定为小端格式的32位int
,其布局如下:
-----------------------------
| 0x00 | 0x02 | 0x00 | 0x00 |
-----------------------------
接下来,将x[0]
设置为1,这将更新a
表示中的第一个字节(在这种情况下保持不变):
-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------
然后将x[1]
设置为2,这会更新a
表示中的第二个字节:
-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------
现在a
的值为0x201,十进制为513。
答案 4 :(得分:1)
除了之前的答案之外,让我试着为你解决这个问题:
#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 Bytes 大小整数的内存:
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
。
内存中的这个新数字相当于 little endian 系统上的513
。
让我们看一下如果您在 big endian 平台上尝试此操作会发生什么:
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
的整数。