对于表示长度或计数变量,使用带符号还是使用无符号整数更好?
在我看来,C++ STL倾向于使用无符号(std::size_t
,就像在std::vector::size()中一样),而C# BCL倾向于使用有符号整数(就像在ICollection.Count中一样。
考虑到长度或计数都是非负整数,我的直觉是选择unsigned;但是我不能理解为什么.NET设计者选择有符号整数。
最好的方法是什么?每种方法的优缺点是什么?
发布于 2012-04-06 16:56:22
C++使用无符号值,因为它们需要完整的范围。在32位系统上,该语言应该使4 GB的向量成为可能,而不仅仅是2 GB的向量。(操作系统可能不允许您使用全部4 GB的空间,但语言本身并不想妨碍您)
在.NET中,无符号整数不符合CLS。您可以使用它们(在一些.NET语言中),但是它限制了可移植性和兼容性。所以对于基类库,它们只使用带符号的整数。
然而,这两种情况都是边缘情况。在大多数情况下,带签名的int
就足够大了。因此,只要两者都提供了您需要的范围,您就可以同时使用这两种方法。
有符号整数有时具有的一个优点是,它们使检测下溢变得更容易。假设您正在计算一个数组索引,并且由于一些错误的输入,或者您的程序中可能存在逻辑错误,您最终试图访问索引-1
。
使用带符号的整数,这很容易检测到。如果没有签名,它就会被包裹起来,变成UINT_MAX
。这使得检测错误变得更加困难,因为您期望的是一个正数,而您得到的是一个正数。
所以真的,这要看情况。C++使用unsigned,因为它需要范围。.NET使用带符号的语言是因为它需要与没有带符号的语言一起工作。
在大多数情况下,这两种方法都可以工作,有时,签名可以使您的代码更可靠地检测错误。
发布于 2012-04-06 17:03:07
对于计数和大小,使用无符号类型是很自然的,除非我们在某些上下文中,它们可以是负的,但却是有意义的。我的猜测是,C++遵循了它的兄弟C的相同逻辑,即strlen()
返回size_t
,malloc()
获取size_t
。
C++ (和C)中有符号整数和无符号整数的问题在于,当您混合使用这两种整数时,您必须知道它们是如何相互转换的。有些人主张对所有的整数都使用带符号的整数,以避免程序员的疏忽和疏忽。但我认为程序员必须知道如何使用他们的工具(编程语言、编译器等)。他们迟早会被转换,如果不是他们写的东西,那么是别人写的东西。这是不可避免的。
所以,了解你的工具,选择在你的情况下有意义的。
发布于 2012-04-06 17:03:33
这里有几个方面:
1)最大值:有符号数的最大值通常是对应的无符号最大值的1/2。例如,在C中,最大有符号短值是32767,而最大无符号短值是65535 (因为-ve数字不需要范围的1/2 )。因此,如果您期望的长度或计数会很大,则无符号表示更有意义。
2)安全性:您可以浏览网络以查找整数溢出错误,但请想象如下代码:
if (length <= 100)
{
// do something with file
}
..。如果'length‘是一个带符号的值,你就会冒着'length’是一个-ve数字的风险(虽然是恶意的,一些强制转换等),并且代码不会执行你期望的。我在以前的一个项目中看到过这种情况,在这个项目中,每个事务都会递增一个序列,但是当我们使用的带符号整数达到最大带符号整数值(2147483647)时,它在下一个递增之后突然变成了-ve,我们的代码无法处理它。
只需要考虑一些事情,而不管底层语言/API的考虑。
https://stackoverflow.com/questions/10040884
复制相似问题