错误与断言

首先声明:这些内容主要是面向C语言的初学者,尤其是正在学习C语言的学生。

    在《C语言字符型数据(一)》中,我们对文本文件中的内容进行了简单的加密处理。程序如下所示:

#include "stdio.h"

int main()

{

   char ch;

   freopen("original.txt","r",stdin) ; //输入输出被分别重定向到两个文件。

   freopen("result.txt","w",stdout);

   ch=getchar();

   while(ch!=EOF)    //EOF指文件的末尾

   {

        if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')

        {

            ch=ch+3;

            if(ch>'z'||(ch>'Z'&&ch<='Z'+3))

                 ch= ch-26;

        }               

        printf("%c",ch);

        ch = getchar();

   }

   return 0;

}

    有一个学生在练习上述程序时,误将while(ch!=EOF) 写成了while(ch=!EOF),程序编译通过,运行后,result.txt文件中什么结果都没有。花了很长时间才最终发现了这个错误。其实很多初学者都曾犯过类似的错误。比如,在写if语句的条件时,也很容易将if(ch!=EOF)写成if(ch=!EOF),或者本来是判断是否相等if(ch==’a’),结果写成了if(ch=’a’)。对初学者而言,最大的困难是这类错误并没有语法问题,从而很难查找,这也是C语言灵活性的一个体现。下面我们先分析错误的原因,再给出解决方法。

错误分析:

    while后面的括号中可以是任何表达式,表达式首先被求值,然后判断该值的真假,C语言判断真假的规则是:零是假,非零的值都为真。当写成ch=!EOF时,这实际上是一个赋值表达式,因为感叹号现在是逻辑运算符“非”,它的优先级高于赋值“=”,所以ch=!EOF等价于ch=!EOF)。EOF是一个常量,等于-1(非零为真),所以!EOF的值为假,注意逻辑表达式求值后的真假是用10来表示的,因此!EOF的值为0ch也被赋值为0,表达式ch=!EOF的值等于ch的值,也为0。因此,while后面的条件恒为假,循环体一次都没有执行。这就是为什么result.txt文件中什么结果都没有。

解决方法:

    1.有牛人曾经给出过一个解决方案:在写while或者if后面的条件时,把常量写在左面,变量写在右边。这样写的好处是,当写错运算符时,编译会报错。比如上面的例子,建议写成while(EOF!= ch),这样写并不影响判断,但如果误写为while(EOF=!ch),编译时会报错,因为EOF是一个常量,常量是不能被赋值的。这样就很容易纠正错误。

    2.适当加入断言来防止错误的发生。比如上面的程序中,如果while循环正常结束的话,ch应该等于EOF,因此我们可以断言循环结束后ch等于EOF。加了断言的程序如下所示:

#include "stdio.h"

#include"assert.h"

int main()

{

    char ch;

    freopen("original.txt","r",stdin);

    freopen("result.txt","w",stdout);

    ch=getchar();

    while(ch!=EOF)    //当这个表达式写成while(ch=!EOF),运行时后面的assert会检测到问题。

    {

         if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')

         {

              ch=ch+3;

              if(ch>'z'||(ch>'Z'&&ch<='Z'+3))

                   ch = ch-26;

          }               

          printf("%c",ch);

          ch = getchar();

     }

     assert(c==EOF);  //正常情况下,循环结束时,c==EOF,断言是正确的。当while后面的表达式写错时,循环

                      //一次都没有执行,这时c!=EOF ,因此断言会报错。

     return 0;

}


    初学者可以自己上机去试试上面的程序,看断言报错的结果是怎样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值