Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否有任何理由不使用固定宽度整数类型(例如uint8\u t)?_C_Integer_Byte_Sizeof_C99 - Fatal编程技术网

C 是否有任何理由不使用固定宽度整数类型(例如uint8\u t)?

C 是否有任何理由不使用固定宽度整数类型(例如uint8\u t)?,c,integer,byte,sizeof,c99,C,Integer,Byte,Sizeof,C99,假设您使用的编译器支持C99(甚至只是stdint.h),那么有没有理由不使用固定宽度的整数类型,比如uint8\t 我知道的一个原因是,在处理字符时使用chars比使用(u)int8\ts更有意义,如中所述 但是,如果您计划存储一个数字,您什么时候想使用一个您不知道它有多大的类型?也就是说,在什么情况下,您希望在不知道数字是8位、16位还是32位的情况下,将数字存储在无符号短码中,而不是使用uint16t 在此基础上,使用固定宽度的整数,或者使用普通整数类型,并且永远不要假设任何东西,在需要知

假设您使用的编译器支持C99(甚至只是stdint.h),那么有没有理由不使用固定宽度的整数类型,比如uint8\t

我知道的一个原因是,在处理字符时使用
char
s比使用
(u)int8\t
s更有意义,如中所述

但是,如果您计划存储一个数字,您什么时候想使用一个您不知道它有多大的类型?也就是说,在什么情况下,您希望在不知道数字是8位、16位还是32位的情况下,将数字存储在
无符号短码中,而不是使用
uint16t


在此基础上,使用固定宽度的整数,或者使用普通整数类型,并且永远不要假设任何东西,在需要知道它们使用了多少字节的地方使用
sizeof
,这被认为是更好的做法吗?

实际上,在不需要知道类型的确切大小的情况下存储数字是很常见的。我的程序中有很多数量,我可以合理地假设不会超过20亿,或者强制执行它们不会超过20亿。但这并不意味着我需要一个精确的32位类型来存储它们,任何可以计数到至少20亿的类型我都可以

如果您试图编写非常可移植的代码,那么必须记住,固定宽度类型都是可选的

CHAR\u BIT
大于
8
的C99实现上,没有
int8\u t
。标准禁止它存在,因为它必须有填充位,
intN\t
类型被定义为没有填充位(7.18.1.1/1)<因此,code>uint8\u t
也被禁止,因为(谢谢,ouah)不允许实现在没有
int8\u t
的情况下定义
uint8\u t

因此,在非常可移植的代码中,如果您需要一个能够容纳最多127个值的有符号类型,那么您应该根据您是否希望要求编译器生成它,使用
signed char
int
int\u least8\u t
中的一种:

  • 使用C89(
    signed char
    int
  • 避免在算术表达式中出现意外的整数提升(
    int
  • 小(
    int至少8\t
    signed char
  • 快速(
    int\u fast8\t
    int
对于最大255的无符号类型,也同样适用于
unsigned char
unsigned int
uint\u least8\u t
uint\u fast8\u t

如果您需要在非常可移植的代码中使用模256算法,那么您可以自己取模,屏蔽位,或者使用位字段玩游戏

实际上,大多数人从来不需要编写可移植的代码。目前,
CHAR\u BIT>8
只在专用硬件上出现,而您的通用代码不会在其上使用。当然,这在将来可能会发生变化,但如果真的发生了,我怀疑有太多的代码对Posix和/或Windows(两者都保证
CHAR\u BIT==8
)做出假设,那么处理代码的不可移植性将是将代码移植到新平台的巨大努力的一小部分。任何这样的实现都可能需要担心如何连接到互联网(以八位字节为单位),而不是担心如何启动和运行代码:-)


如果您假设
CHAR\u BIT==8
,那么我不认为有任何特别的理由避免
(u)int8\u t
,除非您希望代码在C89中工作。即使在C89中,为特定的实现找到或编写一个版本的
stdint.h
也不难。但是如果您可以轻松地编写代码,只要求该类型可以容纳
255
,而不是要求它不能容纳
256
,然后您还可以避免依赖于
CHAR\u BIT==8

标准整数类型的宽度确实可以从一个平台更改到另一个平台,但不是其最小宽度

例如,C标准规定
int
至少为
16位
long
至少为
32位


如果在存储对象时没有一些大小限制,可以将其应用到实现中。例如,如果最大有符号值适合
16位
,则可以使用
int
。然后,让实现最终确定实现目标体系结构的自然
int
宽度。

在假设宽度时,应仅使用固定宽度类型

uint8\t
unsigned char
在大多数平台上是相同的,但并非在所有平台上都是相同的。使用
uint8\u t
强调一个事实,即您假设一个体系结构具有8位
char
,并且不会在其他体系结构上编译,因此这是一个特性

否则我会使用“语义”
typedef
,比如
size\u t
uintptpr\u t
ptrdiff\u t
,因为它们更好地反映了您对数据的想法。我几乎从不直接使用基类型,
int
只用于返回错误,我也不记得曾经使用过
short


编辑:在仔细阅读C11之后,我得出结论,如果存在
uint8\u t
,则它必须是
无符号字符
,并且不能只是
字符
,即使该类型是无符号的。这源于7.20.1 p1中的要求,即所有
intN\u t
uintN\u t
必须是相应的有符号和无符号类型。字符类型的唯一这一对是
有符号字符
无符号字符

,代码应该向普通读者(以及程序员自己)揭示什么是重要的。是整数还是无符号 uint64_t a,b,c; ... a &= ~0x40000000; b &= ~0x80000000; c &= ~0x100000000;