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