microsoft c

1、假如使用了禁止while的条件部分进行赋值的变异程序选择项,为什么可以查出下面代码中的un算优先级错误?

while(ch = getchar() != EOF)

答:

编译程序会查获优先顺序错。因为它把表达式解释为:

while( ch = ( getchar() != EOF ) )

换句话说,编译程序把它看作是将表达式的值赋给ch,因而认为你把“==”错误的键为“=”,并向你发出可能有复制错误的警告。

2、看看你怎样使用编译程序查出无意使用的空语句和赋值语句。值得推荐的办法是进行相应的选择,使编译程序能够对下列常见问题产生警告信息。怎样才能消除这些警告信息呢?

a) if(flight == 063)。这里程序员的本意是对63号航班进行测试,但是因为前面多了一个0使063成了八进制数。结果变成对51号航班进行测试。

答:

b)if(pb != NULL & pb != 0xff)。这里不小心把&&写成&,结果即使pb等于NULL还会执行*pb != 0xff。

答:

为了查获程序员将“&&”误键入为“&”(或“||”误键为“|”)的情况,编译程序采用了与查获将“==”误键为“=”的同样测试。当程序员在if语句中或复合条件中使用了“&”(或“|”),并且没有明确地将结果与0进行比较时,编译程序将产生一个错误。所以见到下面这条语句会产生一个警告。

if ( u & 1 )  /* u是奇数吗?*/

而下面这条语句则不会产生警告信息。

if( (u & 1) != 0 )   /* u是奇数吗?*/


c)quot = numer/*pdenom。这里无意间多了个*号结果使/*被解释为注释的开始 。

答:

警告一个无意而误成为注释的最简单的方法是,当编译发现注释的第一个字符是字母或(时,发出一个警告。这样的测试将查获下面两个可疑情况:

quot = numer/*pdenom;

quot = number/*( pointer expression );

为了避免发出警告,你可以通过将“/”与“*”之间用空格或括号分开,使你的意图更明确。

quot = numer / *pdenom;

quot = number / (*pdenom);

/*注意:本注释将产生一个警告 */

/* 本注释不产生警告 */

/*----------------- 警告勿忧 -----------------*/


d)word = bHigh<<8 + bLow。由于出现了运算优先级错误,该语句被解释成了:wod = bHigh << (8 + bLow)

答:

编译查出可能存在的优先级顺序错的方法是,寻找在同一个不含括号的表达式中的“有麻烦的运算符对”。例如,当程序员偶然将“< <”和“+”运算符一起使用时,编译程序会发现优先级顺序错,对下面的代码发出警告:

word = bHigh << 8 + bLow;

但是,由于下面的语句含有括号,因此编译程序不发出警告信息:

word = ( bHigh << 8 ) + bLow;

word = bHigh << ( 8 + bLow );

如果不专设注释则可写警告式注释:“如果两个运算符具有不同的优先级顺序并没被括号括起,那么就要发出一个警告。”这样的注释太贫,但你在思想上要明白这点。开发一个好的启发式注释,需要在计算机上运行大量的代码直到最后产生有用的结果。你肯定不希望对下面这些常见的惯用语也产生警告信息:

word = bHigh * 256 + bLow ;

if ( ch == ‘ ’ || ch == ‘\t’ || ch == ‘\n’)


3、编译程序怎样才能对"没有与之配对的else"这一错误给出警告?用户怎样消除这一警告?

答:

当编译程序发现两个连续的if语句其后跟有一个else语句时,编译程序就会发出可能有悬挂else的警告信息:

if(expression 1)

if(expression 2)

……

else

……

if(expression 1)

if(expression 2)

……

else

……

为了避免编译程序发出警告信息,可以用括号将内层if语句括起:

if(expression1)

{

if(expression2)

……

}

else

……

if(expression1)

{

if(expression2)

……

else

……

}


4、在看一次下面的代码:

if('\t' == ch)

ExpandTab()'

这样如果应该键入==时键入了=,编译程序就会薄脆,因为不允许常量进行赋值。这个办法彻底么?为什么它不像编译程序开关自动化程度那么高?为什么新程序员会用赋值号代替等号?

答:

将常量和表达式置于比较操作的左边是很有意义的,它提供了自动检查错误的有一个方法。但时,这种方法必须有一个操作数是常量或表达式作为前提,如果两个操作数都是变量,这个方法就不起作用了。请注意,程序员在写代码的时候,一定要学会并记住使用这一技术。

通过使用编译开关,编译程序将警告每一种可能的赋值错。特别是对于没有经验的程序员,编译开关更显得特别有作用。

如果有编译开关,就一定要使用;如果没有,就把常量和表达式放在比较式的左边。


5、C的预处理程序也可能引起某些意想不到的结果。例如,宏UINT_MAX定义在limit.h中,但假如在程序中忘了include这个头文件,下面的伪指令就会无声无息地失败,因为

#if UINT_MAX > 65535u

.....

#endif

怎样使预处理程序报告出这一错误?

答:

为了防止误定义的预处理的宏产生不可预料的结果,编译(实际是预处理)程序应该具有一个开关允许程序员可以把无定义的宏用于错误情况。由于ANSI编译程序及支持老的#ifdef预处理指令,又支持新预处理的defined一元算子,那么就几乎没有必要将无定义的宏“定义”为0。以下代码将会产生错误:

/* 建立目标等式 */

# if INTEL8080

……

#elif INTEL80x86

……

#elif MC6809

……

#elif MC680x0

……

#endif

因此,应写为如下代码:

/* 建立目标等式 */

#if  defined ( INTEL8080 )

……

#elif defined ( INTEL80x86 )

……

#elif defined ( MC6809 )

……

#elif defined ( MC680x0 )

……

#endif

如果在# ifdef语句中使用了无定义的宏,此开关不会给出警告,因为这是有意安排的。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值