如何停止printf根据订单产生不同的值?

问题描述

| 码:
#include <stdio.h>

int main()
{
    printf(
            \" %f,%u,%x,\\n\",1.0f,1.0f);
    return 0;
}
输出:1.000000,1072693248,0, 码:
#include <stdio.h>

int main()
{
    printf(
            \" %x,%f,1.0f);
    return 0;
}
输出:3ff00000,0.000000,0 码:
#include <stdio.h>

int main()
{
    printf(
            \" %x,1.0f);
    return 0;
}
输出:3ff00000,0,1.000000 这仅仅是%u和%x消耗的字节数的问题,如何使值保持一致?     

解决方法

如您所知,传递其类型与格式字符串的相应组成部分不匹配的参数将导致不确定的结果。特别是
\"%x\"
\"%u\"
都期望类型为(unsigned)
int
的值。从语法上讲,传递ѭ6(根据ABI实际上通常表示为
double
long double
)是不正确的。 您的编译器应就此警告您-如果没有,请确保已启用所有警告(对于GCC,
-Wall
)。 如果您想将1.0f用作整数,则只需强制转换:
printf(\" %x,%u,%f\\n\",(unsigned)1.0f,1.0f);
如果您尝试获取二进制表示形式,请尝试如下操作:
float a = 1.0f;
printf(\" %x,*((unsigned*)&a),a);
    ,您通过第一个参数(格式字符串)告诉printf需要哪些参数。您传递给printf的其他值必须与格式字符串匹配。如果没有,您将得到垃圾输出。在您的示例中,您传递的是浮点值ѭ12you,并告诉printf使用
%u
格式说明符将其视为整数。这样就得到了垃圾输出。 printf的手册页包含了为要打印的值创建正确的格式字符串所需的所有详细信息。     ,你不能。 每个格式字段都期望与格式说明符指定的类型完全相同。 在x86系统上,参数通常在堆栈上传递,并且使用不正确的格式说明符将导致变量参数功能从堆栈中获取错误的字节数。 在您的情况下,您用3个浮点值调用printf,但是浮点值被提升为两倍(请参阅http://en.wikipedia.org/wiki/Type_conversion#Type_promotion_in_C-like_languages)。 因此,在这种情况下(在x86系统上),堆栈上将有3乘8字节。 第一个格式字段将采用其在堆栈上期望的字节数: %x将占用4个字节 %u也将占用4个字节 %f将占用8个字节 因此,格式字段的顺序将影响实际打印的数据。 (对于%f,浮点值甚至可能是无效的值,这可能会导致崩溃)。 如果您想了解更多有关变量参数列表的信息,请参阅在C中传递变量参数中的答案。     ,当我用gcc编译时,收到以下警告:
crazy.c: In function ‘main’:
crazy.c:4: warning: format ‘%u’ expects type ‘unsigned int’,but argument 3 has type ‘double’
crazy.c:4: warning: format ‘%x’ expects type ‘unsigned int’,but argument 4 has type ‘double’
crazy.c:5: warning: format ‘%x’ expects type ‘unsigned int’,but argument 2 has type ‘double’
crazy.c:5: warning: format ‘%u’ expects type ‘unsigned int’,but argument 4 has type ‘double’
crazy.c:6: warning: format ‘%x’ expects type ‘unsigned int’,but argument 2 has type ‘double’
crazy.c:6: warning: format ‘%u’ expects type ‘unsigned int’,but argument 3 has type ‘double’
这就是为什么您得到正在使用的垃圾输出的原因。最好使用最严格的警告进行编译,这样您就可以及早发现此类问题。
%u
%x
是期望无符号整数的格式说明符。所有示例都应使用“ 17”浮点说明符。给定浮点数,这将始终给出一致的结果。     ,这是参数列表与格式描述符不匹配的问题。如果要将1.0f打印为整数值,请先将其转换为整数:
printf(\"%x,%f,\\n\",(int)1.0f,1.0f);