此问题已在此处有答案:
printf cannot print float/double correctly on the screen(3个答案)
上个月关门了。
例如,我可以做printf("%d",1);
,还是必须先将1
赋给一个变量?
此外,当我尝试prinf("%d",2.5)
时,输出不是整数部分,而是一个奇怪的数字,如602556751
。为什么?为什么?
此问题已在此处有答案:
printf cannot print float/double correctly on the screen(3个答案)
上个月关门了。
例如,我可以做printf("%d",1);
,还是必须先将1
赋给一个变量?
此外,当我尝试prinf("%d",2.5)
时,输出不是整数部分,而是一个奇怪的数字,如602556751
。为什么?为什么?
1条答案
按热度按时间yhxst69z1#
printf(“%d”,1);我想知道我可以这样做或%d %f,其中任何一个只能使用printf(“%d”,num);...
C不提供抽象的数学,你可以自由地处理各种数字。它使用
int
、float
、double
等类型系统处理由字节表示的值。在要求C做事情时,你必须记住所涉及的类型。此外,当调用函数时,所有参数都作为特定类型的值传递。C从来不传递一个“变量”给函数,只是一个值。如果num
是值为1的int
,则printf("%d", 1)
和printf("%d", num)
相同;两者都将int
值1传递到printf
。在具有四字节
int
和四字节float
的C实现中,相同的四个字节可能表示不同的值,这取决于它们被解释的类型。对于int
类型,字节中的位表示二进制数,该数字表示的值是int
的值。(这些比特并不构成一个纯二进制数,因为有些规定是为负数编码的。这个答案没有讨论)。对于
float
常用的格式,1位表示符号,8位主要编码用于缩放值的指数,23位编码称为有效数的分数值。(完整的有效位有24位,其中一位来自指数位。)在
printf("%d", 1);
中,%d
告诉printf
“我正在传递一个int
值,我希望它被格式化为十进制。”printf
通过在传递给它的参数中查找int
的字节并将这些字节解释为二进制数字来响应。如果执行printf("%f", 1);
,则会告诉printf
查找double
的字节。(由于历史原因,当传递函数调用的变量参数部分时,float
值作为double
值传递。)然后有两个问题:1
,您传递的字节将使用int
的方案进行编码。如果printf
将它们解释为double
的字节,它通常会产生不同的值,特别是因为double
通常比int
需要更多的字节。double
参数的字节传递到与int
参数的字节不同的位置。当printf
获取double
的字节时,但您已经传递了int
,它不会获取您传递给它的字节。它将从printf
获取字节的位置获取一些剩余的字节。从形式上讲,C标准没有定义当您为转换说明符传递错误类型的参数时的行为。
.我还有一个问题,我尝试prinf(“%d”,2.5)。我认为输出应该是2.5的整数部分,但输出是奇怪的数字,如602556751。这个数字从何而来?
2.5
是double
。当您执行此操作时,%d
通知printf
期望int
,因此printf
尝试获取int
的字节,这些字节在与double
的字节不同的位置传递。所以它可能得到了一些字节,这些字节是程序中以前的工作遗留在那个位置的。它将这些字节解释为int
并打印它们。为了使
%d
与double
或%f
与int
一起工作,编译器必须在调用函数之前转换参数。对于printf
,它必须检查格式字符串以确定要进行的转换。这对于一个常量格式字符串是可能的,但是程序也可以计算一个格式字符串,并通过指针传递它,而不是使用一个常量格式字符串,然后编译器将无法知道要执行什么转换。此外,还有其他函数使用变量参数列表和其他方法来确定参数类型,而不是格式字符串,编译器也无法处理这些。程序员负责传递正确类型的参数。