何时在C中使用plain char类型
在普通C中,按标准有三种不同的“字符”类型:
- 普通
char
,其中一个人的签名是实现定义的。 -
signed char
。 -
unsigned char
。
让我们假设至少是C99,其中stdint.h
已经存在(所以你有int8_t
和uint8_t
类型作为可推荐的替代方案,显式宽度为有符号和无符号字符)。
对于我来说,似乎使用普通char
类型只有在需要接口标准库的函数(如printf
)时才真正有用(或必要),并且在所有其他场景中,而不是要避免。 使用char
可能会在实现上签名时导致未定义的行为,并且出于任何原因,您需要对此类数据执行任何算法。
在处理例如Unicode文本(或使用大于127的值表示字符的任何代码页)时,使用适当类型的问题可能是最明显的,否则可以作为普通C字符串处理。 但是,相关的string.h
函数都接受char
,如果这样的数据是类型化的char
,那么在尝试解释它时会产生问题,例如对于能够处理其编码的显示例程。
在这种情况下,最值得推荐的方法是什么? 是否有任何特殊原因可以推荐使用char
不是stdint.h
的合适的固定宽度类型?
char
类型用于字符和字符串。 它是所有字符串处理函数所期望并返回的类型。 (*)你真的应该永远不必对char
进行算术运算,尤其不是那种sign-ness会产生影响的那种算法。
unsigned char
是用于原始数据的类型。 例如, memcpy()
或fread()
将其void *
参数解释为unsigned char
数组。 该标准保证任何类型也可以表示为unsigned char
数组。 任何其他转换可能是“信令”,即触发exception。 (ISO / IEC 9899:2011,第6.2.6节“类型表示”)。 (**)
signed char
是需要char
大小的有符号整数(用于算术)。
(*):
中的字符处理函数对此有点奇怪,因为它们满足EOF(负),因此将字符值“强制”为unsigned char
范围(ISO / IEC 9899:2011) ,第7.4节字符处理)。 但是,由于保证可以将char
为unsigned char
并返回而不会丢失信息,如6.2.6节所述……你明白了。
当char
signed-ness 会产生影响时 – 比较函数就像在strcmp()
– 标准规定char
被解释为unsigned char
(ISO / IEC 9899:2011,第7.24.4节比较函数)。
(**):实际上,很难看出原始数据到char
和back的转换是如何发出信号的,用unsigned char
完成相同的操作就不会发出信号。 但是, unsigned char
是标准部分所说的。 😉
使用char
存储字符(标准仅定义基本执行字符集元素的行为,大致为ASCII 7位字符)。
使用signed char
或unsigned char
来获得相应的算术(有符号或无符号算术具有不同的整数属性 – char
是整数类型)。
这并不意味着您不能使用原始字符进行算术运算,如下所述:
6.2.5类型 – 3.声明为char 类型的对象足够大,可以存储基本执行字符集的任何成员。 如果基本执行字符集的成员存储在char对象中,则其值保证为非负值。
然后,如果您只使用字符集元素,则对它们进行正确定义。