为什么printf的需要投? [英] Why cast is needed in printf?

查看:156
本文介绍了为什么printf的需要投?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要打印一些类型的 off_t 有人建议使用下面的一块code的:

To print a number of type off_t it was recommended to use the following piece of code:

off_t a;
printf("%llu\n", (unsigned long long)a);


  • 为什么格式字符串的的还不够吗?

  • 会有什么问题,如果它不是铸造?

    • Why the format string is not enough?
    • What will be the problem if it were not casted?
    • 推荐答案

      格式字符串没有告诉编译器执行强制转换为无符号长长,它只是告诉的printf ,这是怎么回事收到一个无符号长长。如果你的东西传递的的的一个无符号长长(其中 off_t 可能不),那么的printf 就干脆misinter preT它,以惊人的结果。

      The format string doesn't tell the compiler to perform a cast to unsigned long long, it just tells printf that it's going to receive an unsigned long long. If you pass in something that's not an unsigned long long (which off_t might not be), then printf will simply misinterpret it, with surprising results.

      这样做的原因是,编译器不必了解格式字符串什么。如果你写一个好的编译器会给你一个警告讯息的printf(%d个,3.0),但什么可以,如果你写一个编译器做的printf(S,3.0)取值是在运行时动态确定一个字符串?

      The reason for this is that the compiler doesn't have to know anything about format strings. A good compiler will give you a warning message if you write printf("%d", 3.0), but what can a compiler do if you write printf(s, 3.0), with s being a string determined dynamically at run-time?

      编辑补充:基思·汤普森在下面的评论中指出,有很多地方的编译器的可以的执行这种隐式转换。 的printf 是比较特殊的,是在一种情况下它的不能的。但是,如果你声明一个函数来接受无符号长长,那么编译器的将会的执行转换:

      Edited to add: As Keith Thompson points out in the comments below, there are many places where the compiler can perform this sort of implicit conversion. printf is rather exceptional, in being one case where it can't. But if you declare a function to accept an unsigned long long, then the compiler will perform the conversion:

      #include <stdio.h>
      #include <sys/types.h>
      
      
      int print_llu(unsigned long long ull)
      {
        return printf("%llu\n", ull); // O.K.; already converted
      }
      
      
      int main()
      {
        off_t a;
      
        printf("%llu\n", a); // WRONG! Undefined behavior!
        printf("%llu\n", (unsigned long long) a); // O.K.; explicit conversion
        print_llu((unsigned long long) a); // O.K.; explicit conversion
        print_llu(a); // O.K.; implicit conversion
      
        return 0;
      }
      

      这样做的原因是,的printf 声明为 INT的printf(为const char *格式,...),其中 ... 是可变参数或可变参数符号,告诉它可以接受之后的任何参数数目和类型的<编译器code>格式。 (显然的printf 不能确实的接受任何参数的数量和类型:它只能到,使用接受你告诉它的数量和类型格式但是,编译器不知道任何事情;它留给程序员来处理吧)

      The reason for this is that printf is declared as int printf(const char *format, ...), where the ... is a "variadic" or "variable-arguments" notation, telling the compiler that it can accept any number and types of arguments after the format. (Obviously printf can't really accept any number and types of arguments: it can only accept the number and types that you tell it to, using format. But the compiler doesn't know anything about that; it's left to the programmer to handle it.)

      即使 ... ,编译器做了一些隐式转换,如促进字符 INT 浮动双击。但是,这些转换是不特定的printf ,他们不这样做,并不能,取决于格式字符串。

      Even with ..., the compiler does do some implicit conversions, such as promoting char to int and float to double. But these conversions are not specific to printf, and they do not, and cannot, depend on the format string.

      这篇关于为什么printf的需要投?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆