uint8_t,uint_fast8_t和uint_least8_t之间的区别

C99标准引入了以下数据types。 文档可以在这里findAVR stdint库。

  • uint8_t表示这是一个8位无符号types。
  • uint_fast8_t意味着它是至less有8位的最快的unsigned int。
  • uint_least8_t表示它是一个至less有8位的无符号整数。

我理解uint8_t和什么是uint_fast8_t (我不知道它是如何实现的寄存器级别)。

你能解释“这是一个至less有8位的unsigned int ”的含义吗?

2.与uint8_t相比, uint_fast8_tuint_least8_t帮助提高效率/代码空间?

uint_least8_t是具有至less8位的最小types。 uint_fast8_t是具有至less8位的最快types。

您可以通过想象异国build筑来看到差异。 想象一下20位架构。 它的unsigned int有20位(一个寄存器), unsigned char有10位。 所以sizeof(int) == 2 ,但是使用chartypes需要额外的指令来将寄存器减半。 然后:

  • uint8_t :未定义(不是8位types)。
  • uint_least8_t :是unsigned char ,最小的types至less是8位。
  • uint_fast8_t :是unsigned int ,因为在我的虚构体系结构中,半寄存器variables比全寄存器variables慢。

这个理论是这样的:

uint8_t必须是8位,但不是必须存在的。 所以你应该把它用在你依赖8位整数的模256运算行为的地方,并且你希望编译失败的地方在不明确的体系结构上进行错误行为。

uint_least8_t必须是可以存储至less8位的最小可用无符号整数types。 当你想尽量减less像大数组这样的内存使用时,你会使用它。

uint_fast8_t应该是可以存储至less8位的“最快”无符号types; 然而,实际上并不保证在任何给定的处理器上进行任何给定的操作都是最快的。 你会用它来处理对值执行大量操作的代码。

实践是,“快”和“最less”types没有太多用处。

如果你关心可移植性,用CHAR_BIT!= 8隐藏体系结构,而“大多数人不需要”,那么“最less”types才是真正有用的。

“快”types的问题是“最快”难以确定。 较小的types可能意味着内存/caching系统上的负载较less,但使用小于本机的types可能需要额外的指令。 此外,架构版本之间可能会有所不同,但实施者往往希望在这种情况下避免打破ABI。

从一些stream行的实现来看, uint_fastn_t的定义似乎是相当随意的。 glibc似乎将它们定义为至less是所讨论的系统的“本地字大小”,而不考虑许多现代处理器(尤其是64位处理器)对小于其本地字的项进行快速操作的具体支持尺寸。 IOS显然将它们定义为等同于固定大小的types。 其他平台可能不同。

总而言之,如果使用小整数来执行紧密代码是您的目标,那么您应该在您关心的平台上使用不同大小的types对您的代码进行基准testing,以查看最佳效果。

uint8_t意思是:给我一个正好8位的无符号整数。

uint_least8_t意思是:给我最小的8位无符号整型。 优化内存消耗。

uint_fast8_t意思是:给我一个至less8位的无符号整数。 select一个更大的types,如果它会使我的程序更快,因为alignment的考虑。 优化速度。

另外,与纯inttypes不同,上述stdint.htypes的签名版本保证是2的补码格式。

你能解释“这是一个至less有8位的无符号整数”的含义吗?

这应该是显而易见的。 这意味着它是一个无符号整数types,它的宽度至less是8位。 实际上,这意味着它至less可以保存0到255的数字,并且绝对不能保留负数,但可以保存高于255的数字。

显然你不应该使用任何这些types,如果你打算存储0到255范围以外的任何数字(并且你希望它是可移植的)。

2.与uint8_t相比,uint_fast8_t和uint_least8_t如何帮助提高效率/代码空间?

uint_fast8_t需要更快,所以如果你的要求是代码要快,你应该使用它。 另一方面, uint_least8_t要求不存在较小尺寸的候选 – 所以如果尺寸是关注的话,那么你会使用它。


当然你只需要使用uint8_t当你绝对要求它是正确的8位。 使用uint8_t可能会使代码不可移植,因为uint8_t不需要存在(因为在某些平台上不存在这样的小整数types)。

“快”整数types被定义为可用的最快整数,至less需要的位数(在你的情况8)。

一个平台可以将uint_fast8_t定义为uint8_t那么速度绝对没有差别。

原因是有些平台在不使用本地字长度时速度较慢。

有些处理器不能像小型数据处理器那样高效地运行。 例如,给出:

 uint32_t foo(uint32_t x, uint8_t y) { x+=y; y+=2; x+=y; y+=4; x+=y; y+=6; x+=y; return x; } 

如果yuint32_t ,那么ARM Cortex-M3的编译器可以简单地生成

 add r0,r0,r1,asl #2 ; x+=(y<<2) add r0,r0,#12 ; x+=12 bx lr ; return x 

但是因为yuint8_t ,编译器将不得不生成:

 add r0,r0,r1 ; x+=y add r1,r1,#2 ; Compute y+2 and r1,r1,#255 ; y=(y+2) & 255 add r0,r0,r1 ; x+=y add r1,r1,#4 ; Compute y+4 and r1,r1,#255 ; y=(y+4) & 255 add r0,r0,r1 ; x+=y add r1,r1,#6 ; Compute y+6 and r1,r1,#255 ; y=(y+6) & 255 add r0,r0,r1 ; x+=y bx lr ; return x 

“快速”types的预期目的是为了让编译器能够用较快的typesreplace那些无法高效处理的较小types。 不幸的是,“快速”types的语义是相当不明确的,这反过来又留下了一些关于expression式是否会使用有符号或无符号math进行评估的模糊问题。