Union 不在 C 中打印正确的值
Union doesn't print right values in C
当我执行这个程序时,它没有打印回我输入的内容。
#include <stdio.h>
#include <conio.h>
union integer{
char c;
short s;
int i;
long b;
};
int main( void )
{
union integer aInteger;
printf( "Enter a char: " );
scanf( "%c", &aInteger.c );
printf( "\nEnter a short: " );
scanf( "%hd", &aInteger.s );
printf( "\nEnter a int: " );
scanf( "%d", &aInteger.i );
printf( "\nEnter a long: " );
scanf( "%ld", &aInteger.b );
printf( "\nChar: %c\nShort: %hd\nInt: %d\nLong: %ld",
aInteger.c, aInteger.s, aInteger.i, aInteger.b );
getche();
return 0;
}
我输入了 A、12、1234 和 123456789 作为输入,结果是一个看起来像口袋妖怪中未知形状 Z 的字符,-13035、123456789 和 123456789.I 希望这个程序会打印回来我 inputted.Is 是因为我通过赋值来引用联合体的所有成员
对他们所有人?我应该更改什么以便它可以使用联合而不是结构打印回输入?
来自 Kernighan 和 Ritchie 的 "The C programming language":
6.8 UNIONS
A union is a variable that may hold (at different times) objects of different types and sizes, with the compiler keeping track of size and alignment requirements.
关键词是"at different times"。每个对其元素之一的写操作也会更改其他成员的值,因为元素本身 在内存中重叠 。
在打印输出时,将丢弃最后一个之前的所有写操作结果。 (不是定义;你最后的写操作只是写了最大量的数据。更短的数据量是否会覆盖其他元素的全部或部分,取决于编译器的 char
和 short
大小。)
如果您觉得 必须 使用 union
而不是 struct
,您必须确保不能用 "old" 覆盖数据"new"。这要求您知道基本类型的大小,并且必须使每个元素成为一个数组,其中包含 最大 元素的总长度 - and为最大元素的值预留足够space:
union integer {
char c[2*sizeof(long)/sizeof(char)];
short s[2*sizeof(long)/sizeof(short)];
int i[2*sizeof(int)/sizeof(long)];
long b[2];
};
这假设所有较大尺寸都是较小尺寸的倍数,即,当(想象中)sizeof(short)
为 3 但 sizeof(int)
为 4 时,它将不起作用。
现在您可以读取和写入 aInteger.c[0]
、aInteger.s[1]
、aInteger.i[2]
和 aInteger.b[1]
,而不会覆盖任何其他人的 "important" 数据。
我这里的一些索引可能有误。再一次,我不想测试这个,因为它是一个纯粹的学术问题,实际上你应该简单地使用常规 struct
,或者从 structs
.[= 构建联合元素24=]
当我执行这个程序时,它没有打印回我输入的内容。
#include <stdio.h>
#include <conio.h>
union integer{
char c;
short s;
int i;
long b;
};
int main( void )
{
union integer aInteger;
printf( "Enter a char: " );
scanf( "%c", &aInteger.c );
printf( "\nEnter a short: " );
scanf( "%hd", &aInteger.s );
printf( "\nEnter a int: " );
scanf( "%d", &aInteger.i );
printf( "\nEnter a long: " );
scanf( "%ld", &aInteger.b );
printf( "\nChar: %c\nShort: %hd\nInt: %d\nLong: %ld",
aInteger.c, aInteger.s, aInteger.i, aInteger.b );
getche();
return 0;
}
我输入了 A、12、1234 和 123456789 作为输入,结果是一个看起来像口袋妖怪中未知形状 Z 的字符,-13035、123456789 和 123456789.I 希望这个程序会打印回来我 inputted.Is 是因为我通过赋值来引用联合体的所有成员 对他们所有人?我应该更改什么以便它可以使用联合而不是结构打印回输入?
来自 Kernighan 和 Ritchie 的 "The C programming language":
6.8 UNIONS
A union is a variable that may hold (at different times) objects of different types and sizes, with the compiler keeping track of size and alignment requirements.
关键词是"at different times"。每个对其元素之一的写操作也会更改其他成员的值,因为元素本身 在内存中重叠 。
在打印输出时,将丢弃最后一个之前的所有写操作结果。 (不是定义;你最后的写操作只是写了最大量的数据。更短的数据量是否会覆盖其他元素的全部或部分,取决于编译器的 char
和 short
大小。)
如果您觉得 必须 使用 union
而不是 struct
,您必须确保不能用 "old" 覆盖数据"new"。这要求您知道基本类型的大小,并且必须使每个元素成为一个数组,其中包含 最大 元素的总长度 - and为最大元素的值预留足够space:
union integer {
char c[2*sizeof(long)/sizeof(char)];
short s[2*sizeof(long)/sizeof(short)];
int i[2*sizeof(int)/sizeof(long)];
long b[2];
};
这假设所有较大尺寸都是较小尺寸的倍数,即,当(想象中)sizeof(short)
为 3 但 sizeof(int)
为 4 时,它将不起作用。
现在您可以读取和写入 aInteger.c[0]
、aInteger.s[1]
、aInteger.i[2]
和 aInteger.b[1]
,而不会覆盖任何其他人的 "important" 数据。
我这里的一些索引可能有误。再一次,我不想测试这个,因为它是一个纯粹的学术问题,实际上你应该简单地使用常规 struct
,或者从 structs
.[= 构建联合元素24=]