C Primer Plus(6) 中文版 第7章 C控制语句:分支和跳转 7.3 逻辑运算符

发布于:2023-01-15 ⋅ 阅读:(210) ⋅ 点赞:(0)

7.3 逻辑运算符
有时,把多个关系表达式组合起来会很有用。
使用逻辑运算符
// chcount.c  -- use the logical AND operator
#include <stdio.h>
#define PERIOD '.'
int main(void)
{
    char ch;
    int charcount = 0;
    
    while ((ch = getchar()) != PERIOD)
    {
        if (ch != '"' && ch != '\'')
            charcount++;
    }
    printf("There are %d non-quote characters.\n", charcount);
 
    return 0;

/* 输出:

*/ 

逻辑运算符&&两侧的条件必须都为真,整个表达式才为真。逻辑运算符的优先级比关系运算符低,所以不必在子表达式两侧加圆括号。
C有3种逻辑运算符,见表7.3。
        表7.3 3种逻辑运算符
逻辑运算符        含义
&&                与
||                   或
!                    非
假设exp1和exp2是两个简单的关系表达式,那么:
*当且仅当exp1和exp2都为真时,exp1 && exp2才为真; 
*如果exp1或exp2为真,则exp1 || exp2为真;
*如果exp1为假,则!exp1为真;如果exp1为真,则!exp1为假。
!(4 > 7) 与 4 <= 7表达式等价。
请记住:(练习&&时间)== 完美。
7.3.1 备选拼写:iso646.h头文件
C是在美国用标准键盘开发的语言。但是在世界各地,并非所有的键盘都有和美式键盘一样的符号。因此,C99标准新增了可代替逻辑运算符的拼写,它们被定义在iso646.h头文件中。如果在程序中包含该头文件,便可用and代替&&,or代替||,not代替!。例如,可以把下面的代码:
if( ch != '"' && ch != '\'' ){
    ...

改写为:
if( ch != '"' and ch != '\'' ){
    ...

C不直接使用and、or和not的原因是C一直坚持尽量保留较少的关键字。
        表7.4 逻辑运算符的备选拼写
传统写法    iso646.h
&&            and
||               or
!                not
7.3.2 优先级
!运算符的优先级很高,比乘法运算符还高,与递增运算符的优先级相同,只比圆括号的优先级低。&&运算符的优先级比||运算符高,但是两者的优先级都比关系运算符低,比赋值运算符高。
使用圆括号可以使表达式的含义更清楚明了。
7.3.3 求值顺序
除了两个运算符共享一个运算符对象的情况外,C通常不保证先对复杂表达式哪部分求值。但是,对于逻辑运算符是个例外,C保证逻辑表达式的求值顺序是从左到右。&&和||运算符都是序列点,所以程序在从一个运算对象执行到下一个运算对象之前,所有的副作用都会生效。而且,C保证一旦发现某个元素让整个表达式无效,便立即停止求值。正是由于有这些规定,才能写出这样结构的代码: 
while( (c = getchar()) != ' ' && c != '\n' )
保证了必须先执行赋值操作再进行比较操作。 
if( number != 0 && 12 / number == 2 ) 
保证了number不等于0时才执行除法操作。 
while( x++ < 10 && x + y < 20 ) //
&&是一个序列点,这保证了在对&&右侧的表达式求值之前,已经递增了x。 
7.3.4 范围
&&运算符可用于测试范围。可以这样写:
if( range >= 90 && range <= 100 ){
    ...

千万不要模仿数学上的写法:
if( 90 <= range <= 100 ) //千万不要这样写
这样写的问题是有语义错误,而不是语法错误,所以编译器不会捕获这样的问题。由于<=运算符的求值顺序是从左到右,所以编译器把测试表达式解释为:
(90 <= range) <= 100
整个表达式都恒为真。因此,在范围测试中要使用&&。
ASCII字符编码内有效:
if( ch >= 'a' && ch <= 'z' ){
    ...

相应的可移植方法是用ctype.h系列中的islower()函数。
if( islower( ch ) ){
    ...

无论使用那种特定的字符编码,islower()函数都能正常运行。