以下代码导致:
0.000000
10
在这种情况下从“数据”返回什么?我知道n.data.idata
和n.data.fdata
将是正确的用法,我只是好奇为什么整数值在这种情况下有效,浮点值没有。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
union container
{
int idata;
float fdata;
} data;
struct node *next;
} Node;
int main()
{
Node i = {.data.idata = 10};
Node n = {.data.fdata = 10.0};
printf("%f\n", n.data);
printf("%d\n", i.data);
printf("\nExiting program...\n");
return 0;
}
答案 0 :(得分:4)
让我们暂时忽略明显的未定义行为,这是因为将不正确的类型传递给说明符$.when(1).then(function(data) {
alert(data)
})
的printf函数。那种类型是一个匿名联盟。
Specifier <script src="https://code.jquery.com/jquery-git.js">
</script>
假定从float到double的默认参数提升,在这种情况下不会发生,因为union f
被传递给函数。因此该函数接收由{4}字节组成的联合f
并表示一个浮点数,但尝试打印8个字节,因为它需要一个double。结果是无意义的值,在您的情况下为0.0。
(此答案假定为IEEE 754,而sizeof(int)&lt; = 4)
答案 1 :(得分:-2)
对我对错误问题的原始答案表示歉意。我想这个答案 可能有助于澄清那些接触这个问题的人谁是C新手2501正在谈论的(强调我的)
说明符f假定从float到double的默认参数提升, 哪个在这种情况下不会发生,因为传递了一个联合数据 功能。所以函数接收组成的联合数据 4个字节并表示一个浮点数,但尝试打印8个字节,因为 它预计会翻倍。结果是无意义的值,在您的情况下为0.0。
类型提升可以安全地或至少将一个二进制表示转换为另一个 以标准化的方式。以下内容全部在x86机器上完成。
无符号64位格式的10
二进制值
| 0 1 0的 1 0000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000
二进制值10为32位浮点数...
| 00000000 | 00000000 | 00000的 1 00 | 1 00000 1 0
10位值为64位格式的双倍...
| 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00的 1 00 1 00 | 000000的 1 0
数字10的所有三个表示都有显着差异。类型促销
没有发生意味着printf
语句中的数字被视为a
双,它是这样打印的。在这种情况下,它出现的唯一原因
零是精确的。
以下代码中的Node
数据结构是8个字节。没有衬垫
在结构中或它不能是8个字节长。如果我们将float
设置为10并next
到0我们在记忆中有这种表现......
| 00000000 | 00000000 | 00000的 1 00 | 1 00000 1 0 | 00000000 | 00000000 | 00000000 | 00000000
以上如果转换为双倍并打印printf("%f'\n");
就可以了
看起来像0.0
。如果您使用&#39; printf(&#34;%g \ n&#34;)&#39;你会看到一些
必须在8个字节中设置位,在我的情况下我得到了
5.39824e-315
要查看浮点类可以使用fpclassify
的内容。请参阅下面的代码......
#include <assert.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
union container {
float fdata;
int idata;
} data;
uint32_t next;
} Node;
int main(void) {
size_t nsize1 = sizeof(Node);
assert(nsize1 == 8);
assert(sizeof(int) == 4);
assert(sizeof(float) == 4);
assert(sizeof(double) == 8);
Node n = {.data.fdata = 10.0};
n.next = 0;
double d = *(double*)&n;
int class_of_d = fpclassify(d);
assert(d > 0);
switch(class_of_d) {
case FP_NAN : printf("FP_NAN\n");break;
case FP_INFINITE : printf("FP_INFINITE\n");break;
case FP_ZERO : printf("FP_ZERO\n");break;
case FP_NORMAL : printf("FP_NORMAL\n");break;
case FP_SUBNORMAL : printf("FP_SUBNORMAL\n");break;
case FP_SUPERNORMAL: printf("FP_SUPERNORMAL\n");break;
}
printf("%g\n", d);
return 0;
}