42

我一直在思考是否应该使用里面的typedef <cstdint>

uint32_t我个人更喜欢一遍又一unsigned int遍地int8_t写作……char因为它对我来说更直观。

你们有什么感想?<cstdint>使用来自或不使用 typedef 是一个好主意 吗?有什么缺点吗?

4

6 回答 6

39

实际上,我建议同时使用两者。

如果您想要绝对是 32 位无符号的东西,请使用 uint32_t。例如,如果您正在实现一个“结构”来表示一个外部对象,其规范将其字段之一定义为 32 位无符号。

如果您想要“机器的自然字长”,请使用 int 或 unsigned int。例如:

for (int i = 0 ; i < 200 ; ++i)
    // stuff

“机器的自然字长”将为您提供最佳性能,无论是在今天的处理器上还是在明天的处理器上。

如果您的意思是“字符”,请使用“char”;如果您的意思是“字节”,则为“char”或“unsigned char”。C/C++ 允许您通过“char *”访问任意对象的字节,而不是其他任何东西,严格来说。

如果您特别想要一个 8 位整数,请使用 uint8_t 或 int8_t,类似于 uint32_t。

于 2011-05-26T20:37:11.533 回答
24

你应该同时使用两者。int如其他答案中所述,当您需要“大小合理”的整数时,您应该使用。当你需要一个角色时使用char:它是自我记录的。

在二进制与外界交互时,你应该使用uint32_t和朋友:在进行网络编程、处理二进制文件或使用外部多字节编码等时。在这些情况下,类型的确切大小对于编写正确、可移植、自记录代码。这就是<stdint.h>(或 C++0x <cstdint>)的用途。

(字节顺序同样重要,但这完全是另一回事。)

于 2011-05-26T20:41:36.800 回答
4

这取决于变量的用途。

如果您需要循环计数器,请使用int. 如果需要字符串,请使用char.

如果您需要一个可以容纳 -1 到 100 的数值变量,那就int8_t太好了。如果您需要表示 0 到 100,000 之间的值,那么(感谢@Serge)是一个很好的选择。uint32_t uint_least32_t

于 2011-05-26T20:34:27.237 回答
3

需要使用 cstdint 中的 typedef 的一种特殊情况是,在处理执行大量指针到 int 转换的代码时,在这种情况下使用 intptr_t 是绝对要求。

在我工作的公司中,我们正准备从 32 位迁移到 64 位大量劣质 C/C++ 代码,这些代码不断将指针转换为 int,然后再转换回指针,这在 64 位架构上肯定会失败,所以我们将尽可能尝试清理代码(即修改数据结构和接口以完全消除强制转换的需要)并在其他任何地方使用 intptr_t 而不是 int。

附带说明:一般来说,强制转换应该引起怀疑,但说真的,将指针强制转换为整数几乎总是设计中某个地方存在严重缺陷的结果。基本上,每次您将指针隐藏在 int 后面时,您都是在对编译器、平台以及更重要的是您的同事撒谎。

除此之外,就像其他人所说的那样:尽可能使用泛型类型,并在需要时使用显式大小的类型。

于 2011-05-26T20:50:13.343 回答
1

您基本上似乎在 uint32_t 和 unsigned int 之间没有任何线索。这是完全正常的,因为您不一定知道以后将如何使用您的类型。

只需使用 typedef。

无论您是需要 unsigned int 还是 uint32_t(您可以稍后想到,当您对程序将有更完整的看法时),使用 typedef 将帮助您通过指定您的真实身份来使您的代码更清晰操纵,当你在几个月后发现你最初的选择是最糟糕的选择时,它会更容易改变到另一种类型。这里没有“正确答案”,因为您通常很难弄清楚这些事情。在一些需要 uint32_t 的库和一些需要 int 的其他库之间进行互操作是很痛苦的。

于 2011-05-26T21:23:53.827 回答
-2

template尽可能使用s 和泛型编程。如果不需要,不要依赖任何类型!

如果你有一个函数,它接受一个数字并返回它乘以 2,这样写:

template <typename Number>
inline Number doubleNum(Number n) {
  return 2*n;
}

甚至这样:

template <typename RetType, typename NumberType>
inline RetType doubleNum(NumberType n) {
  return 2*n;
}

这样,如果你有一个使用ints、doubles、uint64_ts 的库——你可以命名它——你可以使用它,而无需重写你的代码。如果您需要使用二进制文件或网络编程,您可以使用固定大小的类型,而无需重写代码。如果您需要任意精度的数字,您可以使用通过运算符重载(例如 GMP 包装器)实现与原始整数或浮点类型相同接口的类,而无需重写代码

您可以专门化模板函数或类,以优化特定情况或使用struct不符合相关接口的类(或 C s):

/*
 * optimization:
 * primitive integers can be bit-shifted left to
 * achieve multiplication by powers of 2
 * (note that any decent compiler will do this
 *  for you, behind the hood.)
 */
template <>
inline int doubleNum<int>(int n) {
  return n<<1;
}
/*
 * optimization:
 * use assembly code
 */
template <>
inline int32_t doubleNum<int32_t>(int32_t n) {
  asm {
    ...
  }
}
/*
 * work with awkward number class
 */
template <>
inline AwkwardNumber doubleNum<AwkwardNumber>(AwkwardNumber n) {
  n.multiplyBy(2);
  return n;
}
于 2012-01-23T03:36:10.983 回答