在以下代码中
const
AFilename = '/tmp/folders/bla.txt';
begin
if NOT FileExists(AFilename) then begin
if NOT DirectoryExists(ExtractFilePath(AFilename)) then
if NOT ForceDirectories(ExtractFilePath(AFilename)) then RaiseLastOSError;
if (FileCreate(AFilename) = INVALID_HANDLE_VALUE) then RaiseLastOSError;
end;
我得到的输出是
#include <stdio.h>
int main() {
union a {
int i;
char ch[2];
};
union a u;
int b;
u.ch[0] = 3;
u.ch[1] = 2;
printf("%d,%d,%d\n", u.ch[0], u.ch[1], u.i);
return 0;
}
任何人都可以解释为什么3,2,515
的价值是i
吗?
答案 0 :(得分:4)
union a {
int i;
char ch[2];
};
union a u; /* initially it contains gargage data */
联盟的所有成员共享公共记忆。在上面的情况下,为u
分配了总共4个字节,因为在4个字节(需要MAX内存)中,您可以存储i
和ch
。
ch[1] ch[0]
----------------------------------
| G | G | G | G | => G means garbage/junk data, because u didn't initialized
----------------------------------
u
MSB LSB
当语句u.ch[0] = 3;
仅执行ch[0]
初始化时。
ch[1] ch[0]
--------------------------------------
| G | G | G | 0000 0011 | => G means garbage/junk data, because u didn't initialized
--------------------------------------
u
MSB LSB
当u.ch[1] = 2;
接下来执行时,1个字节被初始化为
ch[1] ch[0]
------------------------------------------
| G | G | 0000 0010 | 0000 0011 | => G means garbage/junk data, because u didn't initialized
------------------------------------------
u
MSB LSB
正如您在上面看到的4 bytes
只有前2个字节得到已初始化,仍然剩下的2个字节未初始化,因此当您打印{{1 },未定义的行为。
如果你想要预期的结果,那么先将union变量初始化为
u.i
现在当你打印union a u = { 0 }; /* all 4 bytes got initialized at first instance itself, no chance of any junk data */
u.ch[0] = 3;
u.ch[1] = 2;
时,它会打印整个4字节的数据u.i
(如果是小的enidian处理器)
答案 1 :(得分:0)
你的工会变量的大小&#39; u&#39;是4个字节(32位机器)。 假设您有工会变量的起始地址&#39; u&#39;如2000年。
现在,3存储在2000(ch [0])中,2存储在2001(ch [1])中。 内存位置2000的二进制值为00000011(十进制为3),内存位置2001的二进制值为00000010(十进制为2)。
现在,当您尝试打印&#39; u.i&#39;时,两个char变量的值&#39; ch [0]&#39;和&#39; ch [1]&#39;组合在一起形成一个16位的整数,其值为0000001000000011(十进制为515)。这就是为什么你得到整数变量&#39; u.i&#39;的值515。您的机器遵循little-endian格式对内存中的字节进行排序。如果您的机器是一个大端机器,那么您可能已经得到了“u.i&#39;如770而不是515.