抄书:C语言中字符类型使用中的几个误区

http://blog.vckbase.com/smileonce/archive/2005/04/06/4435.html

本不愿写本文,原因已经多次声明过:但凡有大师名著提到过的观点,不愿在重复copy于此处,以免有抄书之嫌。另外,我的陈述也确实与大师们的见解有太大差距,若考虑不周全、理解不通彻,写出来东西就难免误导别人。现在我的观点发生了改变:中国人太穷,买不起书,你若推荐一本书给他买他便割肉一般的疼(省下的钱有用呀,现在把马子吊凯子什么不要钱呀^_^);中国人有的是时间,老外文档里面写的清清楚楚的细节自己偏要用不完全归纳法实验总结一下,然后对得出的不知对错的结论欢喜若狂,以为有所得。

好了,今天偶便从Andrew Koenig所著的《C Traps and Pit falls》(中文版是高巍译的《C陷阱与缺陷》,人民邮电出版社出版,在拙著《C语言之四书五经 》中有提到)抄下来若干语句来,希望能引起诸位高手的关注,花钱买书看。(主要是针对周星星的《不常用的一个字符常量(character constant )的用法 》中的问题,真不好意思说,嘿嘿,第一段的观点对事不对人:p)或者说给诸位GG们省些买书钱泡MM也是有意义的一件事。^_^

一、关于标识字符常量的''中还有多个字符时的含义

16位或32位)的存储空间可以容纳 多个字符(一般为8位),因此有的C编译器允许在一个字符常量(以及字符串常量)中包含多个字符。也就是说,用'yes'代替''yes''不会被该编译器检测到。后者(即''yes'')的含义是“依此包含'y'、'e'、's'以及空字符'/0'的4个连续内存单元空间的首地址”。前者(即'yes')的含义并没有准确地进行定义,但大多数C编译器理解为,“一个整数值,由'y'、'e'、's'所代表地整数值按照特定编译器实现中定义的方式组合得到”。 因此,这两者如果在数值上有什么相似之处,也完全是一种巧合 而已。

译注(高巍注): 在Borland C++ v5.5和LCC v3.6中采取的做法是,忽略多余的字符,最后的整数值即第一个字符的整数值;而在Visual C++ 6.0和GCC v2.95中采取的做法是,依次用后一个字符覆盖前一个字符,最后得到的整数值即最后一个字符的整数值。

二、关于字符强制类型转换为int

解决这个问题,最关键要明白一点:字符是有符号整数还是无符号整数?

现在大多数计算机都支持8位字符,因此大多数现代C编译器都把字符实现为8位整数。然而,并非所有的编译器都按照同样的方式来解释这些8位数值。

只有在我们需要把一个字符值转化为一个较大的整数时,这个问题才变得重要起来。而在其他情况下,结果都是已定义的:多余的位将被简单的“丢弃”。编译器在转换char类型到int类型时,需要做出选择:应该将字符作为有符号数还是无符号数处理?如果是前一种情况,编译器在char类型的数扩展到int类型时,应该同时复制符号位;而如果是后一种情况,编译器只需在多余的位上直接填充0即可。

如果一个字符的最高位是1,编译器是将该字符当作有符号数还是无符号数?对于任何一个需要处理该字符的程序员来说,上述选择的结果非常重要。它决定着一个8位字符的取值范围是从-128到127,还是从0到255。而这一点,又反过来影响到程序员对哈希表或转换表的设计方式。

如果编程者关注一个最高位是1的字符其数值究竟是正还是负,可以将这个字符声明为无符号字符(unsigned char)。这样,无论是什么编译器,在将该字符转换为整数时都只需将多余的位填充为0即可。而如果声明为一般的字符变量,那么在某些编译器上可能会作为有符号数处理,在另外一些编译器上又会作为无符号数处理。

与此相关的一个常见的错误认识 是:如果 c 是一个字符变量,使用 (unsigned )c 就可以得到与c 等价的无符号整数。 这是会失败的,因为在将字符 c 转换为无符号整数时, c 将首先被转换为int型整数,而因此可能得到非预期的结果。

正确的方式是使用语句(unsigned char)c ,因为一个unsigned char类型的字符在转换为无符号整数时无需先转换为int型整数,而是直接进行转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值