关于C的整数类型的一些细节

时间:2018-02-06 14:20:27

标签: c

名为 verybig 的变量在C中声明如下:

<class 'flask_sqlalchemy.BaseQuery'>

然后以特定格式输出:

long long verybig = 12345678908642;

这些代码示例是“C Primer Plus,第6版”中的示例,预期输出为:

printf("verybig= %lld and not %ld\n", verybig, verybig);

本书解释说这是因为verybig= 12345678908642 and not 1942899938 说明符仅查看存储在最后32位中的值而不是完整值。 但是,当我自己运行代码时(使用gcc版本5.4.0,64位操作系统,C11标准),我得到以下输出:

%ld

如您所见,verybig= 12345678908642 and not 12345678908642 说明符似乎不起作用。你愿意为我做点什么吗?

1 个答案:

答案 0 :(得分:4)

C标准只要求整数类型具有最小大小。对于类型long,唯一的要求(C11 5.2.4.2.1)是long至少可以适合大小为2 31 -1的整数。这意味着long 至少 4个字节,但编译器可以自由地使其更大,例如8个字节。

同样,long long仅保证至少符合值2 63 -1。

格式说明符%ld假定参数类型为long%lld假定参数类型为long long。如果使用错误的格式说明符与传递的类型相比,那么严格来说,您的程序具有未定义的行为(C11 7.21.6.1/7)。

至于你的书,它做了以下无声的假设:

  • long long是8个字节
  • long是4个字节
  • 使用long long打印%ld可以提供某种确定性输出。
  • 系统使用2的补码,小端,无陷阱表示。

这些假设都不是由标准保证的,本书应该提到这一点。您的特定系统很可能将long作为8个字节,因此您可以得到上述结果。

至于如何进行专业编程,由于这些原因,longlong long类型在生产质量代码中大多无用。专业程序使用来自stdint.h的类型,例如int32_tint64_t,其中保证分别为32位和64位,具有2的补码表示。这使得编写可移植C代码成为可能。