是否有任何合法使用无符号数据的例子(即unsigned int)或者应该使用无符号数据类型只是被视为非常糟糕的编码实践,作为20世纪70年代和80年代资源受损平台的遗留物?
考虑一下:
int main ()
{
unsigned int a = 5; /*or uint32_t if you prefer*/
unsigned int b = 8
unsigned int c = a - b; // I can't even store a subtraction result
// from my own data type!
float f; // ISO didn't even bother to make a signed version of float.
double d; // ISO didn't even bother to make a signed version of double.
// size_t is an unsigned integer, length varies
// (4 bytes on 32 bit platforms typically, 8 on 64 bit, ...)
size_t size1 = 100;
size_t size2 = 200;
// What's a ssize_t -- it's a signed size_t because size_t can't store subtractions.
// So ssize_t is an bad idea to correct for the bad idea of a size_t being unsigned
ssize_t size3 = size1 - size3;
// unsigned operations don't overflow/underflow
size_t size4 = size1 - size3; // I don't even underflow, I just wrap.
// Which means unsigned isn't even good
// For use as a pseudo data "validation"
}
Run Code Online (Sandbox Code Playgroud)
另外,memset的C定义,例如:
void * memset ( void * ptr, int value, size_t num );
Run Code Online (Sandbox Code Playgroud)
memset的value参数实际上是一个unsigned char,但是大量函数将unsigned char转换为int只是为了避免使用无符号数据类型或者printf如何将char提升为int.
并且在一个场景中,unsigned用于稍微更大的范围(即32位4GB),这更多地表明正在使用错误的数据类型,并且实际上应该使用int64变量或double来存储值首先.
必须有一些合法使用unsigned,但我想不出一个场景.那么应该使用无符号类型的场景呢?
在这种情况下,拇指规则非常简单:使用无符号类型表示无符号值,使用带符号类型表示有符号值.所以,实际上恰恰相反:大部分时间无偿使用签名类型是一种可怕的编码实践.我甚至可以说代码中的大多数整数类型都应该是无符号的.当然,实际比率将取决于应用程序区域,但对于组合问题和相关域:它是无符号的,无符号的,只有未签名的.
上面的环绕行为示例只是演示了典型的新手编码错误.从本质上说它与流行的没有什么不同
double d = 1/2;
Run Code Online (Sandbox Code Playgroud)
接着是"为什么我d的不是0.5?"之类的东西.
还要注意,在积分计算的领域中,无符号类型通常比有符号类型更有效(除法的C舍入规则与典型的机器支持类型不同,并对签名类型的性能产生负面影响).在混合整数浮点计算中,有符号整数类型可能具有边(FPU指令集通常直接支持有符号整数,但不支持无符号整数).
大量函数将unsigned char转换为int只是为了避免使用无符号数据类型
不.转换为intC语言没有函数原型的过去时代的雏形.所有函数都是在没有原型的情况下声明的(或未声明的),它触发了较小整数参数的自动提升int.一旦标准功能的原型出现,就会有意识地定制以与传统行为兼容.因此,您永远不会看到接受[signed/unsigned] char,[signed/unsigned] short参数(或float就此而言)的"经典"标准库函数.签名与此无关.