根据格式说明符的不同,可以将D_1值scanf
合并为一个并集。
union {
int i;
double f;
} u;
scanf("%lf", &u.i); // implicitly scan the double
printf("%lf", u.f); // explicitly print the double
这是因为scanf
将指针作为参数,并且并集中的所有元素都对齐,(void*)&u.i == (void*)&u.f
。
是否可以以同样的方式更改printf
行,根据格式从并集中选择正确的值进行打印,而不会意外地对一些可能的值进行切片?
printf("%lf", ???); // implicitly print the double
printf
无法推断传递给它的参数的类型。该参数将根据格式字符串中相应的转换说明符进行解释。因此,参数必须与其各自的转换说明符正确对应。引用C11标准§7.21.6.1&段;9关于fprintf
如果转换规范无效,则行为未定义。如果任何参数不是对应的转换规范,行为未定义。
再次引用C11标准§7.21.6.2&第;13关于fscanf
如果转换规范无效,则行为未定义。
因此,以下对scanf
的调用调用了未定义的行为,因为u.i
的类型是int
,但%lf
转换说明符意味着您正在读取double
。
scanf("%lf", &u.i);
请阅读这些-
- 当我使用错误的格式说明符时会发生什么
- scanf或printf中的格式说明符错误
此外,进入工会领域是一种不明确的行为,这是最近才写的。
union {
int i;
double f;
} u;
// undefined behaviour. u.i is of type int but %lf
// means scanf will read a double
scanf("%lf", &u.i);
// undefined behaviour because reading the field u.f
// but the last written field is u.i
printf("%lf", u.f);
不,你不能那样做。
没有间接的printf()
格式说明符,联合的不同成员可以具有不同的大小,因此作为varargs参数处理方式不同。
即使有一种方法可以说"pointer to integer"而不仅仅是"integer",当然也没有办法让printf()
仅根据指针值在"pointer到integer"one_answers"pointer至double"之间做出决定。
如果我理解正确,你会喜欢这样的东西:
printf("%>gn", &u); /* prints the double */
printf("%>dn", &u); /* prints the int */
我发明了(!)>
格式修饰符,用来表示"参数是指向相应数据类型的指针,即>g is "pointer to
double`"。遗憾的是,这不是标准。你当然可以自己实现。