C:打印大数字

前端之家收集整理的这篇文章主要介绍了C:打印大数字前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
采取以下措施:
#include <stdio.h>

main() {
    unsigned long long verybig = 285212672;

    printf("Without variable : %llu\n",285212672);
    printf("With variable    : %llu",verybig);
}

这是上面程序的输出

Without variable : 18035667472744448
With variable    : 285212672

从上面可以看出,当printf通过数字作为常量时,它会打印出一些非常大的不正确的数字,但是当该值首先存储在变量中时,printf会输出正确的数字.

这背后的原因是什么?

解决方法

尝试285212672ULL;如果你没有后缀,你会发现编译器把它当成一个正则整数.它在变量中工作的原因是因为整数在赋值中被转换为无符号long long,因此传递给printf()的值是正确的类型.

在你问之前,不,编译器可能不够聪明,不能从printf()格式字符串中的“%llu”中找出它.这是一个不同的抽象层次.编译器负责语言语法,printf()语义不是语法的一部分,它是一个运行时库函数(与标准中包含的函数不同).

考虑以下32位int和64位无符号long long系统的代码

#include <stdio.h>

int main (void) {
    printf ("%llu\n",1,2);
    printf ("%llu\n",1ULL,2);
    return 0;
}

输出

8589934593
1

在第一种情况下,两个32位整数1和2被推送到堆栈,printf()将其解释为单个64位ULL值2 x 232 1.两个参数无意中包含在ULL值中.

在第二个,你实际上推64位1值和一个多余的32位整数2,这被忽略.

请注意,您的格式字符串与实际参数之间的“脱离步骤”是一个坏主意.就像是:

printf ("%llu %s %d\n","hello",0);

可能会崩溃,因为32位“hello”指针将被%llu消耗,%s将尝试取消引用最终的0参数.以下“图片”说明了这一点(我们假设单元格是32位,“hello”字符串存储在0xbf000000.

What you pass     Stack frames     What printf() uses
                 +------------+
0                | 0          | \
                 +------------+  > 64-bit value for %llu.
"hello"          | 0xbf000000 | /
                 +------------+
0                | 0          |    value for %s (likely core dump here).
                 +------------+
                 | ?          |    value for %d (could be anything).
                 +------------+

猜你在找的C&C++相关文章