我一直在思考是否应该使用<cstdint>
内的typedef。
我个人更喜欢将uint32_t
优先于unsigned int
而int8_t
优先于char
等...因为它对我来说更直观。
你们觉得怎么样?使用<cstdint>
中的typedef是不是一个好主意?有什么缺点吗?
答案 0 :(得分:35)
实际上,我建议同时使用两者。
如果你想要一些肯定是32位无符号的东西,请使用uint32_t。例如,如果要实现“struct”来表示外部对象,该外部对象的规范将其中一个字段定义为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。
答案 1 :(得分:22)
你应该同时使用两者。当您需要“合理大小”的整数时,您应该使用int
,如其他答案中所述。当你需要一个角色时使用char
:它是自我记录的。
当你在二进制文件中与外部世界交互时,你应该使用uint32_t
和朋友:进行网络编程,处理二进制文件或使用外部多字节编码等。在这些情况下,类型的确切大小对于编写正确,可移植,自我记录的代码至关重要。这就是<stdint.h>
(或C ++ 0x <cstdint>
)的用途。
(Endianness同样重要,但这完全是另一回事。)
答案 2 :(得分:4)
这取决于变量的用途。
如果您需要循环计数器,请使用int
。如果需要字符串,请使用char
。
如果您需要一个可以容纳-1到100的数字变量,int8_t
是好的。如果您需要表示0到100,000之间的值,那么 uint32_t
uint_least32_t
(感谢@Serge)是一个很好的选择。
答案 3 :(得分:3)
您将需要使用cstdint中的typedef的一种特殊情况是在处理执行大量指针到int转换的代码时,在这种情况下使用intptr_t是绝对的要求。
在我工作的公司中,我们正在准备从32位迁移到64位吨的劣质C / C ++代码,这些代码将指针转换为int然后返回指针,这在64位架构上肯定会失败,所以我们将尽可能地尝试清理代码(即修改数据结构和接口以完全消除对转换的需要)并在其他地方使用intptr_t而不是int。
侧面说明:一般来说,施法会引起怀疑,但严重的是,指向整数的指针几乎总是你设计中某个严重缺陷的结果。基本上,每次在int后面隐藏指针时,你都会对编译器,平台以及更重要的是你的同事撒谎。
除此之外,像其他人一样说:尽可能使用泛型类型,并在需要时使用显式大小类型。
答案 4 :(得分:1)
你基本上似乎在uint32_t和unsigned int之间没有任何线索。这是完全正常的,因为您不一定知道以后如何使用您的类型。
只需使用typedef。
无论你是否需要unsigned int或uint32_t(你可以在以后想到,当你对程序的内容有更完整的视图时),使用typedef将通过指定什么来帮助你使代码更清晰你真的在操纵,当你想出最初的选择是最糟糕的几个月之后,它会让你更容易换到另一种类型。这里没有“正确的答案”,因为你通常会用艰难的方式解决这些问题。一些想要uint32_t的库和一些其他想要整理的库之间的互操作很痛苦。
答案 5 :(得分:-3)
尽可能使用template
和通用编程。如果您不需要,请不要依赖任何类型!
如果你有一个带数字的函数并返回它乘以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;
}
这样,如果您有一个使用int
,double
,uint64_t
的库 - 您可以命名它 - 您可以使用它,而无需重写代码。如果您需要使用二进制文件或网络编程,则可以使用固定大小的类型,而无需重写代码。如果你需要任意精度数字,你可以使用一个类,它通过运算符重载实现与原始整数或浮点类型相同的接口,例如GMP包装器,而无需重写代码。
您可以专门化模板化的函数或类,优化特定情况或使用不符合相关接口的类(或C struct
):
/*
* 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;
}