while((c= getchar()) != EOF)的隐藏问题

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表示的字符,则问题就会显现出来,这种错误和底层实现息息相关,在没有了解底层实现的情况下,逻辑层面、代码层面根本不能发现这一问题。或者在某一环境、平台下正常运行,但一旦移植到其他环境就存在隐患,而且难以被发觉。

猜你喜欢

转载自blog.csdn.net/smallerxuan/article/details/79288032