C++学习之路(五),C++primer plus 第六章 分支语句和逻辑运算符

程序清单6.1     

//using if statement    使用 if 语句
#include<iostream>
using namespace std;

void main()
{
    char ch;
    int spaces = 0, total = 0;
    cin.get(ch);
    while(ch != '.')
    {
        if (ch == ' ')
            ++spaces;
        ++total;
        cin.get(ch);
    }
    cout << spaces << " spaces, " << total << " characters toal in sentence." << endl;
}

代码运行如下
仅当 ch 为空格时,语句++spaces; 才被执行。因为语句++total;(这里第六版又出现一个印刷错误)位于 if 语句的外面,因此在每轮循环中都将被执行。注意,字符总数中包括按回车键生成的换行符。

程序清单6.2
 

//using the if else statement    使用if...esle语句
#include<iostream>
void main()
{
    char ch;
    
    std :: cout << "Type, and I shall repeat.\n" ;
    std :: cin.get(ch);
    while(ch != '.')
    {
        if (ch == '\n')
            std :: cout << ch;
        else
            std :: cout << ++ch;//这里注意ch++ 和++ch 的区别,两种方法的结果是不是同的
        std :: cin.get(ch);
    }
    std :: cout << "\nPlease excuse the slight confusion.\n";    //又有一个印刷错误
}

运行结果:
如果将 ++ch 改成 ch+1; 运行结果则是:
按类型运算规则,ch+1的类型是int型,因此输出的是数值而非字符。最后注意一点,这里 ++ch 是不能改成 ch++ ,效果如下:
根据运算规则,前缀是先运算再赋值,也就是说程序先接收到字符 s, 转换成ASII为115,由于s != \n,于是进入else语句,又因为ch++是后缀,根据运算规则,后缀是先赋值再运算,即 std :: cout << ch++,到这一句的时候,ch被先赋值为s,ASII码为115,而被打印出来 ch = s,此时并未执行++,
当此句执行完成了,到下一句std :: cin.get(ch); 时ch才被赋值为t, ASII码为116, 即15句未尾才执行++,而不是中间就++了,而虽然
的此时ch = t, ASII码为116,但ch的值已经被上一句赋值给s打印出来了,所以虽然这里ch = t, 已经无意义了

程序清单6.3

//using if else if else statement    使用if...else if...else语句
#include<iostream>
using namespace std;

const int Fave = 27;

void main()
{
    int n;

    cout << "Enter a number in the range 1-100 to find ";
    cout << "My favorite number: ";
    do
    {
        cin >> n;
        if (n < Fave)
            cout << "Too low -- guess again: ";
        else if (n > Fave)
            cout << "Too high -- guess again: ";
        else
            cout << Fave << " is right!\n:";
    }while (n != Fave);
}

程序运行结果: 

 程序清单6.4

//using the logical or operator    使用逻辑or运算符
#include<iostream>
using namespace std;

void main()
{
    cout << "This program may reformat your hard disk\n"
            "and destroy all your data.\n"
            "Do you wish to continue? <y \ n> ";

    char ch;
    cin >> ch;
    if (ch == 'y' || ch == 'Y')
        cout << "You were warned!\a\a\n";
    else if (ch == 'n' || ch == 'N')
        cout << "A wise choice ... bye\n";
    else
    cout << "That wasn't a y or n! Apparently you "
            "can't follow\ninstructions, so "
            "I'll trash your disk anyway.\a\a\a\n";
}


由于程序只读取一个字符,因此只读取响应的第一个字符,只要第一个字符是n 或者 N都行,然而,如果程序后面再读取输入时,将从刚才输入的第二个字符开始读取,如上面会读取n 字符。
6.22     逻辑 AND 运算符: &&
逻辑 AND 运算符(&&),也是将两个表达式组合成一个表达式。仅当原来的两个表达式都为true时,得到的表达式的值才为true.
5 == 5 && 4 == 4    // true(真), 因为两个表达式都为true(真)
5 == 3 && 4 == 4    // false(假), 因为第一个表达式为false(假),红色为假
5 > 3 && 5 > 10     // false(假), 因为第二个表达式为false(假),红色为假
5 > 8 && 5 < 10     // false(假), 因为第二个表达式为false(假),红色为假
5 < 8 && 5 > 2      // true(真), 因为两个表达式都为true(真)
5 > 8 && 5 < 2     // false(假), 因为两个个表达式都为false(假),红色为假

由于 && 的优先级低于关系运算符, 因此不必在这些表达式中使用括号。和 || 运算符一样, && 运算符也是个顺序点,因此将首先判定左侧,并且在右侧被判定之前产生所有的副作用。如果左侧为 fale, 则整个逻辑表达式必定为 false, 在这种情况下, C++ 将不会再对右侧进行判定。

         程序清单 6.5演示了如何使用 && 来处理一种常见的情况-------由于两种不同的原因而结束 while 循环。 在这个程序清单中, 一个 while 循环将值读入到数组中。 一个测试 (i < ArSize) 在数组被填满时循环结束, 另一个测试 (temp >= 0) 让用户通过一个负值来提前结束循环。该程序使用 && 运算符瘵两个测试条件组合成一个条件。该程序还使用了两条 if 语句、 一条 if else 语句和一个 for 循环, 因此它演示了本章和第 5 章的多个主题。

程序清单 6.5    and.cpp

#include<iostream>
using namespace std;

const int ArSize = 6;

void main()
{
    float naaq[ ArSize ];
    cout << "Enter the NAAQs ( New Age Awareness Quotients) "
         << "of\nyour neighbors. Program terminates "
         << "when you make\n" << ArSize << " entries "
         << "or enter a negative value.\n";

    int i = 0;
    float temp;
    cout << "First value: ";
    cin >> temp;
    while (i < ArSize && temp >= 0)
    {
        naaq[ i ] = temp;
        ++i;
        if (i < ArSize)
        {
            cout << "Next value: ";
            cin >> temp;
        }
    }
    if(i == 0)
        cout << "No data -- bye\n";
    else
    {
        cout << "Enter your NAAQ: ";
        float you;
        cin >> you;
        int count = 0;
        for (int j = 0; j < i; j++)
            if (naaq[ j ] > you)
            ++count;
        cout << count;
        cout << " of your neighbors have greater awareness of\n"
             << "the New Age than you do.\n";
    }
}

注意: 该程序将输入放在临时变量 temp 中。在核实输入有效后, 程序才将这个值赋给数组。下面是该程序的运行情况。一次在输入6个数值后结束:

另一次在输入负值后结束: 

该程序还有另一种情况,就是第一次输入负值,结果如下: 

程序说明
来看看该程序的输入部分:

cin >> temp;
while (i < ArSize && temp >= 0)
{
       naaq[ i ] = temp;
       ++i;
       if (i < ArSize)
       {
              cout << "Next value: ";
              cin >> temp;
       }
}

        该程序首先将第一个输入值读入到临时变量(temp)中。然后, while 测试条件查看数组中是否还有空间 (i < ArSize) 以及输入值是否非负 (temp >= 0)。 如果条件满足, 则将temp的值复制到数组中,并将数组索引加1。 此时, 由于数组下标从0开始, 因此 i 指示输入了多少个值。 也是说, 如果i 从0 开始,则第一轮循环将一个值赋给 naaq[ 0 ], 然后将 i 设置为1。
         当数组被填满或用户输入了负值时, 循环将结束。注意仅当i 小于ArSize 时, 即数组中还有空间时,循环才将另处一个值读入到temp 中。
        获得数据后, 如果没有输入任何数据(即第一次输入的是一个负数), 程序将使用if else 语句指出这一点。这里发现一个问题,程序是说输入一个负数就结束循环,那么if else的条件应该是 temp < 0吧,为何程序清单中使用的代码却是数组下标 i == 0;有些不解,于是我把条件改成temp < 0; 结果和程序清单中运行还是有些不一样,于是继续用F10一步步运行,当输入的temp < 0,则由于while循环测试条件不满足,程度直接来到if else语句,正好满足if (temp < 0), 根据if else规则,将执行if 语句,跳过else语句,因此无论前面输入了多少非负数,只到碰到一个负数,程序就会来到

if (temp < 0)
    cout << "No data -- bye\n";

然后程序直接结束;如果是条件改成i == 0; 则当输入一个负数后,程序由于while 测试条件不成立,跳出while循环,来到if else语句,此时,i 应该是大于0,假设前面输入了正数, 再根据if else规则,if 条件不成立,跳过if,执行else语句,因此会执行和自己输入的NAAQ进行比对,并打印出count的值。

我在想程序已经用 while语句设置了条件 while (i < ArSize  && temp >= 0), 红色部分, 为何 while 循环体里还要用同样的条件来测试 if (i < ArSize); 于是乎,我把if (i < ArSize) 和大括号去掉,保留中间两句,运行是不会报错,随便输入了几个值,发现和程序清单中情况没什么区别?例子中应该不会出现画蛇添足的情况了,于是输入和清单中同样的数字时,发现了情况,发现了提示虽然只要输入6次,但是实际中输入了7次,而第7次没有参加 if (i < ArSize) 条件测试,通过F10一步步的运行明白,当第 6 次输入,++i = 6, 由于没有测试条件 if (i < ArSize),直接进入了cout << "Next value: "; 并由语句cin >> temp; 将输入的值赋给了 temp, 再由于此时naaq[ 6 ] = 56; 数组的下标6在测试条件 i < ArSize已经不成立,所以for循环中naaq[ 6 ]将不会被参加if(naaq[ j ] > you)比对。

6.2.3    用&&来设置取值范围

         &&运算符还允许建立一系列 if else if else语句, 其中每种选择都对应一个特定的取值范围。 程序清单6.6演示了这种方法。另外, 它还演示了一种用于处理一系列消息的技术。与char指针变量可以通过指向一个字符串的开始位置来标识该字符串一样, char指针数组也可以标识一系列字符串, 只要将每一个字符串的地址赋给各个数组元素即可。 程序清单6.6使用qualify数组来存储4个字符串的地址, 例如, qualify[ 1 ]存储字符串"mud tug-of-war\n" 的地址。然后,程序便能够将cout、 strlen()、 或strcmp()用于qualify[ 1 ], 就像用于其它字符串指针一样。 使用const限定符可以避免无意间修改这些字符串。

程序清单     6.6      mor_and.cpp

//mor_and.cpp -- using the logical AND operator
#include<iostream>
using namespace std;

const char * qualify[ 4 ] =
{
    "10,000-meter race.\n",
    "mud tug-of-war.\n",
    "masters canoe jousting.\n",
    "pie-throwing festival.\n"
};

void main()
{
    int age;
    cout << "Enter your age in years: ";
    cin >> age;
    int index;

    if (age > 17 && age < 35)
        index = 0;
    else if (age >= 35 && age < 50)
        index = 1;
    else if (age >= 50 && age < 65)
        index = 2;
    else
        index = 3;

    cout << "You qualify for the " << qualify[ index ];
}

运行结果如下:

       由于输入的年龄不与任何测试取值范围匹配, 因此程序将索引设置为3,然后打印相应的字符串。

       程序说明
       在程序清单6.6中, 表达式age > 17 && age < 35 测试年龄是否位于两个值之间,即年龄是否在18岁到34岁之间。 表达式 age >= 35 && age < 50 使用 <=运算符将35包括在取值范围内。 如果程序使用 age > 35 && age < 50, 则35将被所有的测试忽略。 在使用取值范围测试时, 应确保取值范围之间没有缝隙,又没有重叠。 另外, 应确保正确设置每个取值范围(参见本节后面的旁注“取值范围测试”)。
        if else 语句用来选择数组索引,而索引则标识特定的字符串。

                                                                                               取值范围测试
       取值范围测试的每一部分都使用AND运算符将两个完整的关系表达式组合起来:

       if (age > 17 && age < 35 )              //OK
       不要使用数学符号将其表示为:
        
if (17 < age <35)                             //表这样使用!
        编译器不会捕获这种错误, 因为它仍然是有效的C++语法。<运算符从左向右结合, 因此上述表达式的含义如下:
        if ( (17 < age) < 35)
        但17 < age 的值要么为true(1), 要么为false(0)。不管是哪种情况,表达式17 < age 的值都小于35,因此整个测试的结果总是true! 

6.2.4     逻辑 NOT 运算符: !

  !运算符将它后面的表达式的真值取反。也就是说,如果 expression (表达式)为 true, 则!expression 是 false; 如果expression 为 false, 则!expression 是true。更准确地说,如果expression 为 true 或者非零,则!expression为false。
  通常,不使用这个运算符可以更清楚地表示关系:
  if ( ! (x > 5)                                        // if ( x <= 5) is clearer (表达更清楚)
        然则,!运算符对于返回 true - false 值或可以被解释为 true - false 值的函数来说很有用。例如,如果C-风格字符串 s1 和 s2 不同,则 strcmp(s1, s2) 将返回非零 (true) 值,否则返回 0。这意味着如果这两个字符串相同,则 !strcmp(s1, s2)为 true。
  程序清单 6.7 使用这种技术(将!运算符用于函数返回值)来筛选可赋给 int 变量的数字输入。如果用户定义的函数 is_int()(这个稍后详细介绍) 的参数位于 int 类型的取值范围内,则它将返回 true。然后,程序使用 while(!is-int(num))测试来拒绝不该取值范围内的值。

  程序清单 6.7   not.cpp

//not.cpp -- using the not operat
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值