为什么C中的字符串函数在使用char而不是unsigned char的数组上工作?
在为什么C中的字符串函数在使用char而不是unsigned char的数组上工作?,c,string,C,String,在C标准库函数中,字符串的元素是chars。是否有一个很好的理由来决定它而不是无符号字符 对8位字符串使用无符号字符,有一些优点,尽管很小: 这更直观,因为我们通常将ASCII码存储为无符号值,并且在处理二进制数据时,我们更喜欢0x00到0xFF的无符号范围,而不是处理负数。所以我们必须投 使用无符号整数可能更快/更有效,或者在某些处理器上生成更小的代码 因为标准没有将字符定义为有符号字符,所以没有充分的理由。也没有任何好的理由说明char的符号性是由实现定义的。不存在任何类型的使用负数索引的
C
标准库函数中,字符串的元素是char
s。是否有一个很好的理由来决定它而不是无符号字符
对8位字符串使用无符号字符
,有一些优点,尽管很小:
- 这更直观,因为我们通常将ASCII码存储为无符号值,并且在处理二进制数据时,我们更喜欢0x00到0xFF的无符号范围,而不是处理负数。所以我们必须投
- 使用无符号整数可能更快/更有效,或者在某些处理器上生成更小的代码
char a = 'a';
char b = 'b';
char c = a + b;
字里行间有许多模糊的事情。首先,文本“a”和“b”会被无声地从int
截断为有符号/无符号字符。然后在表达式a+b
中,a和b都被整数提升规则隐式提升为int
类型。在两个int
上执行加法。然后,结果会自动截断回有符号/无符号字符
如果编译器能够证明优化不会影响上述任何模糊性,那么它可能会用正常的8位操作来代替 好问题。由于该标准没有将
char
定义为无符号或有符号(这由实现决定),因此我猜想对char
的偏好来自两个角度:
比char
花费更少的时间进行键入,使得字符串操作函数的原型更易于阅读和使用unsigned char
- 因为最初的ASCII规范是7位的,所以为了C规范的缘故,有效值是否在0到127或0到255之间并不重要。8位字符集的标准化发生得晚得多
,用于存储小的有符号整数有符号字符
,用于存储小的无符号整数无符号字符
,用于存储字符char
char
不是无符号类型
曾经有一段时间[1]char
被描述为已签名(见第4页),但即使在当时,“符号传播功能在其他实现中消失”,因此它的行为已经表现为在某些地方已签名,在其他地方未签名。我认为实现的选择仅仅反映了对他们来说最简单的方式(例如,在PDP-11上,第一个C实现是针对它的,MOVB
做了符号扩展,我不记得有一种方法可以将字节移动到一个字而不获得符号扩展)
现在,我知道的大多数实现都使用带符号的char
。我所知道的唯一一个无符号的char
是来自IBM的,是EBCDIC委托it的支持(基本字符集中字符的字符代码必须是正数,EBCDIC的大多数字符代码都在128以上)
[1] 字符的签名是由实现定义的 对于您所描述的问题,一个更干净的解决方案是强制要求纯
char
必须无符号
普通char
可能有符号或无符号的原因部分是历史原因,部分与性能有关
C的早期版本没有无符号类型。由于ASCII仅涵盖0到127的范围,因此假定将
char
设为有符号类型没有特别的缺点。一旦做出了这个决定,一些程序员可能已经编写了依赖于此的代码,后来的编译器将char
保留为有符号类型,以避免破坏这样的代码
引用1975年《K&R1》出版前3年的a:
字符(声明的,以下称为,char
)从
ASCII集;它们占据8位中最右边的7位
字节。也可以将char
s解释为带符号的2的补码
8位数字
EBCDIC需要8位无符号字符
,但显然基于EBCDIC的机器
char ch = '0';
ch ++;