【问题标题】:can someone explain the purpose of %f and %d to me?有人可以向我解释 %f 和 %d 的目的吗?
【发布时间】:2013-01-23 14:46:09
【问题描述】:
#include <stdio.h>

 int main(int argc, const char * argv[])
 {

    float apples = 1.1;

    float bananas = 2.2;

    double fruit = apples + bananas;

    printf("%f.\n",fruit);

    return 0;

 }

好吧....那么为什么需要 %f 呢?我知道它正在为我打印“水果”的十进制表示法,但为什么我不能只要求程序打印数字“水果”?是因为我必须声明我是否希望以十进制 %f 或科学记数法 %e 打印“水果”?我有时也遇到过 %d。这意味着什么?

【问题讨论】:

标签: objective-c c


【解决方案1】:

如果你看一下definition of the printf function,那么你就会知道这些值是作为 %d : int 格式说明符 %f : 浮点格式说明符

被称为格式说明符

printf 也是库中定义的简单方法 并根据参数打印值

例如

int a = 5;
float b = 5.43 ;

现在如果你写

printf("%d",a);

它打印存储在变量 a ==>> 中的整数值,即 5

printf("%f",b);

它打印存储在变量 b ==>> 中的浮点值,即 5.430000 // 最多六位数

如果您尝试使用代码

printf("%f",a);
printf("%d",b);

这两行打印出称为垃圾值的尴尬值,由于您使用了错误的格式说明符,因此从未知位置获取

您可以参考link

1: http://www.elook.org/programming/c/printf.html 获取格式说明符列表

到 Alok Save :

这有点复杂,如果我无法解释清楚,请告诉我,我会尝试创建一个具有更好答案的差异问题。

实际发生的是 当你写

int a = 5 // 101 in binary

然后在内存中分配 2 个字节 = 16 位,如


0000000000000101

但是当您尝试通过将 %f 作为格式说明符将其打印为浮点数时 它要求一个 4 字节 = 32 位的表达式 但你得到的是 16 位表示 和最重要的一点 浮点数的第 16 位为“。”保留。那是十进制 所以你的


0000000000000101 变成了


  1. = 二进制 10 // 十进制 2

所以小数点前的值变为 2 而不是 5 由于浮点数仍然有 16 位,表示十进制后的值 并且 int 变量仅提供 16 位来表示十进制前的值 因此代表小数点后值的最后 16 位选择垃圾值 这些垃圾值代表一些随机二进制值 最终产生一些价值

所以你的输出永远是 2.something

这部分对于每台机器都会有所不同,因为它会选择垃圾值 但是按照给定的解释,小数点前的值总是相同的

我希望这有用

但如果它不让我知道

我会尝试提出更好的表示方式

link 也会很有帮助

【讨论】:

  • *像你一样从一个未知的位置拍摄.."。为什么以及如何未知位​​置?你有一个变量,谁的地址是位置(地址)。位置是已知的。如何解释该位置的值就是区别所在。
  • @MichaelLefkowitz:现在你做到了……哈哈
【解决方案2】:

printf 函数的原型是

int printf(const char * restrict format, ...);

第一个参数始终是描述输出的格式的文本字符串(因此不能只写printf(fruit);)。 ... 表示printf 可以在格式字符串之后使用零个或多个附加参数(这称为 variadic 函数)。

不幸的是,可变参数函数不会自动知道在参数列表的可变部分中传递给它们的参数的数量或类型。他们只是在最后一个固定参数之后看到下一个可用参数的起始地址。您必须以某种方式将该信息作为固定参数的一部分传递。对于printf,附加参数的数量和类型由格式字符串中的转换说明符 指示。所以当你写

printf("%f\n", fruit);

转换说明符%f 告诉printf 在格式字符串后面还有一个double 类型的附加参数。转换说明符还告诉printf 该值应如何格式化以进行显示。例如,在

printf("%7.2f\n", fruit);

转换说明符 %7.2f 告诉 printf 将值显示为 7 字符宽的字段,小数点后有 2 位数字,或 9999.99

如果参数的类型与转换说明符不匹配,则行为未定义。例如,如果你写

printf("%d\n", fruit);

您告诉printf 期待int,而您实际上是在传递double,这是一个逻辑错误。根据底层架构,可能会发生许多不同的事情,因此行为是 undefined 并且编译器不必对此做任何特别的事情; 任何结果都被认为是“正确的”。真正好的编译器会发出参数与转换说明符不匹配的诊断。大多数人会简单地按原样翻译代码,结果可能是从意外输出到访问冲突的任何结果。

同样,如果您没有传递足够的参数来匹配转换说明符的数量,则行为未定义:

printf("%f %d\n", fruit);

如果您传递 更多 个参数而不是转换说明符,则会评估附加参数,否则会被忽略:

printf("%f\n", fruit, apples, bananas);

【讨论】:

  • +1 用于花时间制定正确和解释性的答案。它使我的答案变得多余但是这个答案解释得更详细,所以我很乐意删除我的答案。这应该是公认的答案。
【解决方案3】:

%d 是用于打印整数的格式说明符,%f 打印双精度数。由于C 中使用的参数数量可变机制,您需要使用格式说明符指定要打印的内容的类型,以便编译器知道下一个参数是什么类型。

【讨论】:

    【解决方案4】:

    printf 无法猜测您的变量是什么类型。因此你给他一个提示:格式。然后该函数可以将您的参数解释为给定类型。

    【讨论】:

      【解决方案5】:

      printf 代表print formatted,这意味着您向它提供两种数据:

      • 如何呈现数据(格式字符串)
      • 要呈现哪些数据(其余)。

      printf 的格式字符串语法在支持此功能的语言之间或多或少是统一的。维基百科有一个很好的描述:Format placeholders

      【讨论】:

        【解决方案6】:

        "%f" 格式说明符是一种特殊的字符串格式,用于向printf 指示您将打印double。 (For more details)

        "%d" 格式说明符是一种特殊的字符串格式,用于向printf 指示您要打印decimalinteger

        【讨论】:

          【解决方案7】:

          如果您不希望 4.11 等数字变为 4.110000,您可以使用 %g 代替 %f。 %g 使用 %f 或 %e (智能确定编译器在这种情况下找到更好的方式),它可以很好地在数字末尾切割零。

          Scanf 也不是类型安全的,你需要告诉编译器你想使用什么类型的数据。还有 %d 和 %f 的区别,%f 仅指浮点数而不是双精度数。使用 scanf 时,%lf 指的是双精度。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-08
            • 2012-04-09
            • 2021-02-18
            • 1970-01-01
            • 2012-08-24
            • 2021-01-05
            相关资源
            最近更新 更多