14

我喜欢将我的变量初始化为一些“虚拟”值,并开始使用int64_tand uint64_t。到目前为止,看起来至少有三种方法可以将 an 初始化int64_t为特定值(并且对无符号等效项稍作更改):

int64_t method_one   = 0;
int64_t method_two   = 0LL;
int64_t method_three = INT64_C(0);

我使用 GCC 并以 OS X 和 Linux 为目标。我想选择一种旨在易于移植和清晰的方法——但最重要的是正确性。我是否过度考虑了这一点,或者是否有一种“最佳”或“最推荐”的方法来初始化这个变量类型,对于我抛出的任何特定值(当然是在它的范围内)?

4

3 回答 3

8
int64_t method_one   = 0;

……完全合理。C99(参见此处的草案;是的,我知道它不再是最新的标准,但它是引入int<N>_t类型的标准)说:

  • 0具有类型int(§6.4.4.1 第 5 段);
  • 表达式的类型是int64_t(§6.5.16 para.3);
  • 右侧的类型将转换为表达式的类型(第 6.5.16.1 段第 2 节);
  • 此转换不会更改值(§6.3.1.3 第 1 段)。

所以这完全没有问题,并且没有额外的混乱使得它在初始化为 0 或int.

int64_t method_two   = 0LL;

int64_t不保证与long long; 然而,这实际上也应该适用于任何有符号的 64 位值(ULL对于无符号的 64 位值也是如此):long long(and unsigned long long) 在符合 C99 的实现中应该至少为 64 位(§5.2.4.2.1 ),因此LL(and ULL) 对于初始化 64 位值应该始终是安全的。

int64_t method_three = INT64_C(0);

对于可能在范围之外的值,这可以说是一个更好的选择int,因为它更清楚地表达了意图:INT64_C(n)将扩展到适合n(至少)64 位范围内的任何值(一般参见第 7.18 节,以及特别是第 7.8.4.1 节)。


在实践中,我可能会根据上下文使用上述任何一种。例如:

uint64_t counter = 0;

(为什么要添加不必要的混乱?)

uint64_t some_bit = 1ULL << 40;

(除非非常宽,1 << 40否则根本无法工作;在这里对我来说似乎不太可读。)intUINT64_C(1) << 40

uint64_t some_mask = UINT64_C(0xFF00FF00FF00FF00);

(在这种情况下,将值显式调用为 64 位常量对我来说似乎比写易读0xFF00FF00FF00FF00ULL。)

于 2012-11-08T00:39:44.610 回答
7

就个人而言,我会使用第三种,这是实现这一目标的最便携的方式。

#include <stdint.h>

int64_t method_three  = INT64_C(0);
uint64_t method_three = UINT64_C(0);

无论如何,我认为这不是一件很重要的事情。

于 2012-11-07T17:51:33.693 回答
0

根据 ANSI C 标准,along long intunsigned long long intisLL的后缀ULL分别为:

以ll 或 LL为后缀的八进制或十六进制long long int、unsigned long long int 十进制、八进制或以u 或 U 以及 ll 或 LL为后缀的十六进制unsigned long long int

如果您知道int64_t定义为:

typedef signed long long int int64_t

那么方法二绝对是正确的:

int64_t method_two   = 0LL;
uint64_t method_two   = 0ULL;

编辑

牢记可移植性问题,并且不能保证将其定义为long long,那么最好使用第三种方法:

INT64_C()
UINT64_C()
于 2012-11-07T17:58:14.577 回答