我确实意识到这个头衔一开始可能听起来很傻,但是,拜托,请耐心等待一下.:)
从那以后我就开始使用size_t并且ptrdiff_t,我还没有一个使用int,早在我还记得.
我记得最近使用的唯一整数数据类型属于以下类别之一:
(无符号)整数与一些内存数据结构的索引相关联(例如vector).
几乎总是,最合适的类型是size_t(或者...::size_type,如果你加倍努力).
即使整数实际上并不代表索引,通常它仍然与某个索引相关联,因此size_t仍然是合适的.
签名版本size_t.在许多情况下,最适合的类型,这似乎是ptrdiff_t,因为很多时候,当你需要这个,你用迭代工作-并因此size_t而ptrdiff_t都适合他们.
long.我偶尔需要这个_InterlockedIncrement(引用计数).
(unsigned)long long,用于保存文件大小.
unsigned int或者unsigned long,用于"计数"目的(例如,每100万次迭代,更新UI).
unsigned char用于原始字节级访问内存.
(旁注:我从来没有找到任何用途signed char.)
intptr_t并uintptr_t偶尔存储操作系统句柄,指针等
一个特别int重要的方面是你不应该溢出它(因为它是未定义的行为),所以你甚至不能可靠地使用它来计算 - 特别是如果你的编译器将它定义为16位.
那么,何时,你应该使用int(除非你的依赖已经需要它)?
现在有没有真正的用途,至少在新编写的便携式代码中?
全部最重要的原因 - 可读性如何?(和简单的数学)
long weeklyHours = daysWorked * hoursPerDay;
Run Code Online (Sandbox Code Playgroud)
"好的......但话又说回来,人类实际上每周需要多少工作才能得到一个long"
size_t weeklyHours = daysWorked * hoursPerDay;
Run Code Online (Sandbox Code Playgroud)
"等等......我们是否正在weeklyHours迭代一个向量?"
unsigned int weeklyHours = daysWorked * hoursPerDay;
Run Code Online (Sandbox Code Playgroud)
"足够清楚." - 如果任何一个可能是负面的(错误的一部分 - 它可能是一种解释或离开的方式,不重要)可能的错误来源
int weeklyHours = daysWorked * hoursPerDay;
Run Code Online (Sandbox Code Playgroud)
"好吧,很简单.我得到了这样做."
Luchian有一些很好的可读性点,我将在其中添加一些技术性的:
int有效处理的大小,而long可能不会(每个操作有更多CPU周期,机器代码更多字节,需要更多寄存器等)abs(a - b)在数学上看起来正确但在b>时a它们没有给出直观结果而且它们是未签名的int second_delta = (x.seconds - y.seconds) + (x.minutes - y.minutes) * 60;if (pending - completed > 1) kick_off_threads()-1,经常使用:对于无符号类型,这将被转换为最大可能的值,但这可能导致误解和编码错误(例如,if (x >= 0)测试非哨兵)此外,在有符号整数和无符号整数之间进行隐式转换的范围很广 - 理解无符号类型很少有助于强制实施"非负"不变量非常重要:如果这是吸引力的一部分,那么最好写一个类构造函数和运算符强制执行不变量.
在可读性方面,int表示一个明显跨越问题域的数字的一般需求 - 它可能过多但在机器代码操作和CPU周期中已知便宜,因此是一般整体存储的首选类型.如果你开始使用say unsigned char来存储某人的年龄 - 它不仅不能很好地发挥作用operator<<(std::ostream&...),而且还会引发一些问题,例如"这里是否需要节省内存?" (特别是对基于堆栈的变量造成混淆),"是否有意将此视为用于I/O或IPC目的的二进制数据?",甚至"它是以ASCII存储的已知单位数年龄?".如果事情最终可能会出现在寄存器中,那么这int是一个自然的尺寸.
我自己终于找到了一个很好的用例:
int是存储整数对数的完美候选者,例如地图上的缩放级别。
short通常没有足够的精度(平滑的鼠标滚轮的旋转可以非常精确),并且long通常比我们需要的精度更高。
我们肯定需要负值,所以我们不应该使用无符号类型。因此int符合要求。