本文共 847 字,大约阅读时间需要 2 分钟。
曾今写过这样的代码:while((c= getchar()) != EOF)的隐藏问题
char c;while((c= getchar()) != EOF){ Do……}用以读取文本中的数据,曾一直以为这段代码应该是正确的,从语法到逻辑上看起来它都应该是正确的,但其实不然,因为这尽在逻辑层面是正确的,但结合底层实现来思考,它是存在问题的,而且问题很大。 先分析库函数getchar(),该函数会返回int值,而EOF在大多数实现中都是一个特殊值-1(EOF表示的是getchar()返回的超出范围的特殊值,是与getchar()可能返回的所有字符都不同的特殊值)。在这里有一点需要注意,符号、值,这两者本质上有什么不同么?都是用0和1表示的二进制数据而已。getchar()返回的数据或者说值,在什么情况下才能不失真的保存下来?当然是要保存在一个char型及以上的变量中,才能不失真。 那么问题到底存在哪里呢?接下来我们具体讲述,依据C语言标准我们知道,数据类型的具体大小决定于实现,假定某一实现下char型为有符号型,占用8 bit 存储空间,那么便能表示255个不同的值,该环境中EOF标志位常见的定义-1。那么十进制255对应的字符’\377’或’\XFF’在解释的时候就会被扩展为与EOF相等的值,而造成错误,使得该段代码被错误的提前结束。如果某一实现下char型为无符号型,EOF会被截断而失去最高位,无法被识别为与EOF相等的值,会导致该段代码陷入死循环。 这段代码的问题就是getchar()返回的字符究竟是多少个bit所表示的,如果在某一实现中char为8 bit,getchar()返回的字符在7 bit表示以内则不会出现任何问题,如果返回的是一个8 bit表示的字符,则问题就会显现出来,这种错误和底层实现息息相关,在没有了解底层实现的情况下,逻辑层面、代码层面根本不能发现这一问题。或者在某一环境、平台下正常运行,但一旦移植到其他环境就存在隐患,而且难以被发觉。
转载地址:http://mmmsi.baihongyu.com/