作业帮 > 综合 > 作业

#include union utype { int i; double x; }s1,s2,*p=&s1; void

来源:学生作业帮 编辑:作业帮 分类:综合作业 时间:2024/07/18 10:28:56
#include union utype { int i; double x; }s1,s2,*p=&s1; void main() { s1.x=123.4; s1.
#include
union utype
{
\x05int i;
\x05double x;
}s1,s2,*p=&s1;
void main()
{
\x05s1.x=123.4;
\x05s1.i=100;
\x05int x=sizeof(s2);
int y=sizeof(s1);
int z=sizeof(*p);
\x05printf("%d %d %d %d\n",s1.x,x,y,z);
}
为什么 y,z都是8 x不等于8?x的输出=1079957913
可是
#include
union utype
{
\x05int i;
\x05double x;
}s1,s2,*p=&s1;
void main()
{
\x05int x=sizeof(s2);
int y=sizeof(s1);
int z=sizeof(*p);
\x05printf("%d %d %d %d\n",x,y,z);
}
这时候x y z又都是8了
到底是什么原因呢 我知道从字面看是赋值引起的 就是求下解释
printf("%d %d %d %d\n",s1.x,x,y,z);
第二个%d本意输出一个int类型长度,然而s1.x是double长度,则这的double的低四位将覆盖掉后面x所需要的4位,当字节截断时,输出的时double,即是s1.x的低4位的int值
再问: void main() { s1.x=123.4; s1.i=100; int x=sizeof(s2); int y=sizeof(s1); int z=sizeof(*p); printf("%d %d %d %d\n",s1.x,x,y,z); 你仔细看 我的第二个%d是输出的int x=sizeof(s2); 也就是s2的长度 第一个%d输出的是s1.x的值(但是s1.x的值其实是s1.i的值了) x y z 其中 x是s2的长度 yz是s1的长度 都是double的长度 都应该是8啊
再答: 既然你知道sizeof(s1) = sizeof(s2) = sizeof(*p) = sizeof(utype) = 8,那你应该知道共用体肯定是选择最高类型的字符宽度来决定其字长。既然是8,那肯定是公用一个double的8字节64位。其中i成员,在小尾寻址中使用这个double的低4字节。 现在讨论printf() printf函数包含一个char * 指针用以一字节一字节的找到下一个变量输出的位置(内部重命名为typedef char * va_list),他将按照提供的_format格式字符串来确定。 现在你第一个是%d格式,那么这个Va_list会尝试从_format下一个不确定形参偏移4个字节来寻找一个整数。而你现在提供的时s1.x显然是一个double。printf函数采用C标准调用方式(_cdecl)压栈,从右到左(高地址到低地址),那么首先他截取s1.x的低4个字节(也就是你再main重新赋值过得s1.i),那么第一个输出100没有问题,接下来一个空格,直接输出,随后又是一个%d,va_list又尝试偏移4字节寻找一个整数,而现在这4字节正是这个double的高4字节,由于在内存中实型数和整型数的补码形式完全不是一个概念,所以你不会知道在低4字节填充100的二进制时,高4字节的指数位和尾数的32位是什么内容,所以输出这4自己就出现了未知数。 这个结果也就是告诉你,你给printf提供的形参z根本不会输出到,因为va_list早已按照_format执行完毕,不信你可以把z去掉看结果 也就是告诉你共用体中s1.x = 123.4 那么此时他对应的s1.i不确定,如果s1.i = 100,那么此时s1.x也是不确定的,一句话,只能有一个是确定的 这个的问题都是关于printf()的实现的。实际上printf是根据格式字符串来“猜”类型,他只能知道%d就是寻找4个字节并把它用整数表示。若果他知道确切类型,那么第一个参数s1.x当然要报错呀。关于不确定参数的函数printf,scanf, 甚至你自己定义的。都是一个道理
再问: 哦 好的 谢谢 我以为s1.x和s1.i只要赋值了就可以相互表示了...