【问题标题】:What is the argument for printf that formats a long?格式化 long 的 printf 的论点是什么?
【发布时间】:2010-09-07 12:04:29
【问题描述】:

printf 函数采用参数类型,例如 %d%i 用于 signed int。但是,我看不到任何 long 值。

【问题讨论】:

标签: c printf long-integer


【解决方案1】:

在说明符之前直接放置一个l(小写字母L)。

unsigned long n;
long m;

printf("%lu %ld", n, m);

【讨论】:

  • printf("%ld", ULONG_MAX) 将值输出为 -1。应该是printf("%lu", ULONG_MAX) 无符号长,如下@Blorgbeard 所述。
  • 其实应该改成%ld,和OP问题更和谐。
  • 是的,贝科博士;此外,只需 %l 触发 warning: unknown conversion type character 0x20 in format [-Wformat]
【解决方案2】:

我想你的意思是:

unsigned long n;
printf("%lu", n);   // unsigned long

long n;
printf("%ld", n);   // signed long

【讨论】:

    【解决方案3】:

    在大多数平台上,longint 的大小相同(32 位)。不过,它确实有自己的格式说明符:

    long n;
    unsigned long un;
    printf("%ld", n); // signed
    printf("%lu", un); // unsigned
    

    对于 64 位,您需要 long long:

    long long n;
    unsigned long long un;
    printf("%lld", n); // signed
    printf("%llu", un); // unsigned
    

    哦,当然,在 Windows 中是不同的:

    printf("%l64d", n); // signed
    printf("%l64u", un); // unsigned
    

    通常,当我打印 64 位值时,我发现以十六进制打印它们会很有帮助(通常使用很大的数字,它们是指针或位域)。

    unsigned long long n;
    printf("0x%016llX", n); // "0x" followed by "0-padded", "16 char wide", "long long", "HEX with 0-9A-F"
    

    将打印:

    0x00000000DEADBEEF
    

    顺便说一句,“长”不再意味着那么多(在主流 x64 上)。 “int”是平台默认的 int 大小,通常为 32 位。 “长”通常是相同的大小。但是,它们在旧平台(和现代嵌入式平台!)上具有不同的可移植性语义。 “long long”是一个 64 位的数字,通常是人们想要使用的,除非他们真的知道自己在做什么,编辑一段 x 平台可移植代码。即使这样,他们也可能会使用宏来捕获类型的语义含义(例如 uint64_t)。

    char c;       // 8 bits
    short s;      // 16 bits
    int i;        // 32 bits (on modern platforms)
    long l;       // 32 bits
    long long ll; // 64 bits 
    

    过去,“int”是 16 位。你会认为它现在是 64 位,但不,这会导致严重的可移植性问题。当然,即使这是对神秘而历史悠久的真理的简化。见wiki:Integer

    【讨论】:

    • 澄清一下:架构比 x86 和 x64 还多,在这些架构上,char、short、int、long 和 long long 有不同的含义。例如,具有 16 位内存对齐的 32 位 mcu 可以使用: char=short=int=16 bit;长=32位; long long = 64 位
    • @AndresR - 绝对如此,这对从事嵌入式编程的人来说非常重要(我曾经为烟雾报警器构建了一个内核模块)。可怜那些尝试使用并非为可移植性而编写的代码的可怜人。
    • 我不太确定“大多数平台都有一个大小为 32 的 long”是否仍然正确。例如,我在 Oracle Linux x86_64/amd64 上,nvcc long 是 8 个字节。
    • “哦,当然,在 Windows 中是不同的”。有跨平台解决方案吗?
    • @interestedparty333 是的,我 >95% 确定在 Linux 中 long 具有与字/指针大小相同的大小(因此在 32 位 Linux 上为 32 位,在 Linux 上为 64 位64 位 Linux)。如果您查看 Linux 内核代码或 Linux 驱动程序内部,它们通常将指针存储在 longunsigned long 变量中。实际上,几周前我的一位同事将一些代码从 Windows 移植到 Linux,不得不将我们所有的 longs 更改为 uint32_t,因为我们在 Windows 下开发时会经常滥用它们。
    【解决方案4】:

    这取决于,如果您指的是 unsigned long 格式字符是"%lu"。如果您指的是signed long,则格式字符为"%ld"

    【讨论】:

      【解决方案5】:

      【讨论】:

        【解决方案6】:

        如果您想像我一样打印unsigned long long,请使用:

        unsigned long long n;
        printf("%llu", n);
        

        对于所有其他组合,我相信您使用来自the printf manual 的表格,获取您要打印的任何类型的行和列标签(就像我对上面的printf("%llu", n) 所做的那样)。

        【讨论】:

          【解决方案7】:

          我认为要明确回答这个问题需要知道您正在使用的编译器名称和版本以及它正在编译的平台(CPU 类型、操作系统等)。

          【讨论】:

          • 您的答案应该是评论而不是答案本身。
          猜你喜欢
          • 2010-09-05
          • 2020-03-11
          • 2013-06-22
          • 2013-06-22
          • 1970-01-01
          • 1970-01-01
          • 2019-07-01
          • 2012-04-17
          相关资源
          最近更新 更多