自学编程,从此开始

上第2学堂,听有趣的编程课

课文: 《你好,分支!》 (点击查看完整内容:视频+评测+讨论+……)

作者:null

女神迎面走来,如何给她一个不同常人的问候?很着急,在线等!

课文题图

 

第6节:你好,分支!

0. bool 类型

现实生活中大量用到真或假、是或否、对与错、存在或不存在、买或不买、嫁或不嫁这样非A即B的数据,在C++中,可以使用bool类型表达。在C++中,使用true表示真,使用false表示假。不过在C/C++中,非零0都能直接转换为true,而零值可以直接转换为false;倒过,true若转为整数,只能是1,而false是0。

出于历史原因,cout 对 bool类型的输出,默认使用整数0或1表达。比如:

cout << true << ", " << false << endl; //1, 0

1. 条件表达式

表达式是可以计算出结果的代码,比如1+2+3,可以计算出6。条件表达式则是能计算出bool类型的结果的表达式。当然,由于前面所说,一些数据,典型如整数,只要是非零值,都可以直接转义为true,而零值可以直接转义为false。我们可以将“直接转换”视为计算出bool类型的最后一步。

2. 不带else结构

视频课程讲的是if/else流程结构,即,条件成立时和条件不成立两个分支,各有各的事情的要做,比如:


if (条件)
{
事A;
}
else 
{
    事B;
}

事C;

条件成立,做事A,不成立,做事B;分支流程结束,然后代码继续往下走,开始做事C。

但有时候,希望条件成立,做事A,条件不成立,不做额外的什么事,直接走分支流程结束之后的事,也就是上例中的事C。这也是很常见的。比如假设有这么一段描述:

走路,如果遇到小卖部,就买瓶汽水再走;否则继续走……

描述中有如果(if),也有否则(else),但我们不能被自然语言天生的表达不精确所误导;要加以分析:实际上不管买不买汽水,之后我们还是要继续往前走;所以“继续走”这个操作是公共项。

实现只有如果没有否则的流程,很简单,直接不写else语句块就是:

走啊走;

if (遇到小卖部)
{
    卖汽水;
}

继续走;
}

课堂作业-1

​请将本课Hello函数中的if/else结构,改为if结构实现。提示:如果是女神,就先说一句恭维话,然后再补一句和普通人一样的“你好,某某某!”。

3. 多级if/else 分支

有些事情需要多次判断,比如,如果遇上志玲就说:“你好,志玲,你的美赐予我一天好心情。”,而如果遇上嘉玲,就说:”你好,嘉玲,你家那位最近去欧洲喂鸽子吗?“,再如果是普通同事,就说:”你好,某某!“。代码可以像下面这么写,可以实现功能,但存在不足:

if (name == "志玲")
{
    cout << "你好,志玲,你的美赐予我一天好心情。" << endl; // 语句块A
}

if (name == "嘉玲")
{
    cout << "你好,嘉玲,你家那位最近去欧洲喂鸽子吗?" << endl;
}
else 
{
    cout << "你好," << name << endl;
}

不足之处在哪里?假设当前遇上的是志玲 ,那么流程进入语句块A(见代码中注释),输出对志玲的问候,按说这事就完了,但是流程将走出语句块A,继续往下走,于是开始判断当前遇上的是不是嘉玲……都已经知道当前所遇已经是志玲了,何必再判断她是不是其他什么人呢?这一步是浪费了。解决此类问题的方法是使用联动的、多组if/else-if:

if (name == "志玲")
{
    cout << "你好,志玲,你的美赐予我一天好心情。" << endl;
}
else if (name == "嘉玲")
{
    cout << "你好,嘉玲,你家那位最近去欧洲喂鸽子吗?" << endl;
}
else 
{
    cout << "你好," << name << endl;
}

以下自然语言的表达,有助于理解这段代码:”如果是志玲…… 否则,如果是嘉玲……,(再)否则……“。其中的”否则,如果“,就对应”else if “。正是一个典型的 ”if - else if - else ……“。依据需要,中间的else-if 可以有多级。

课堂作业-2

测试上述多级联动if/else-if代码,然后再加上针对遇到”贾玲“这一情况的特殊问候。

再来看一个例子:

接受用户输入一个整数0到9之间的整数;

如果大于9,输出:”太大,不合法。“;

否则,如果大于7,输出:”挺大的“;

再否则,如果大于3,输出:”中间水平“;

再否则,如果大于等于0,输出:”好小“;

再否则:输出:”太小,不合法。“

提示代码:

……
int number;

cout << "请输入一个0到9之间的整数(含0和9):"
cin >> number;

if () 
{

}
else if ()
{

}
else if ()
{

}
else if ()
{

}
else
{

}

课堂作业-3

完成上例。

4. 关系比较操作

大于:>

大于或等于: >=

等于: ==

小于或等于: <=

小于: <

不等于: !=

感叹号在逻辑判断中,表示”取反“,在此处也是该意。

数学上的数比较大小,很直观,什么2大于1啊,3.2大于3.0啊。但是,坑还是有的。

数值比较之”坑“一:整数之间的除法,商取整

除法用在C++中的整数类型之上,就只能是整除,比如 5/2 ,三年级小学生就知道等于2.5,但在C++中,被除数5和除数2都是整数,商也是整数值:2。不要以为这很奇怪,现实生活中很多数值计算并不需要很高的精度,因此不需要带小数的除法结果。这是5/2得到2的原因之一,另一个原因是:相比5/2要得到2.5,像这样的整除计算,对计算机来说,真是的超快的,性能超高的。

数值比较之”坑“二:带小数位比较,存在精度问题

计算机使用二进制表记录数据,而许多十进制数(带小数)转换成二进制时,需要用到除法,会出现”除不尽“

的情况。除不尽的情况在十进制中其中也存在,比如 1除以3,用十进制的小数表达,就是0.3333333无穷无劲的啊。计算机的内存是有限的,所以碰上这种情况必须截断,这就有了精度问题。比如,十进制中的0.1,要转换成二进制表达,就会出现精度丢失。

来看这个例子:

    double R = 2.335 - 2.334 ;
    cout << R << endl;

    if (R == 0.001)
    {
        cout << "OK!" << endl;
    }

将这段代码放在main()函数中,编译运行,你将看到屏幕输出 ”0.001“。也就是说,R的值 是0.001,这很符合我们的判断,但是,你看不到”OK!“,也就是说,if的条件 ”R == 0.001“竟然又不成立。那R到底是不是0.001呢?

这是算是一个”坑“吧?想象一下,如果将来某一天,你进入国家金融中心当一名光荣的程序员,然后你掉进了这个坑。所谓差之毫厘,谬以千里,你的小失误造成了国家数以千亿的财产损失——是不是有一种后背发凉的感受?那就对了。我们这本就叫《感受篇》。

带小数位的数值,在计算机中的表达方法称为”浮点数“。记住,直接比较浮点数是不安全的,事实上在编译上面的代码中,编译器就会给我们一个警告……

课堂作业-4

完成以上代码测试,说出编译器的警告内容是什么,并翻译成中文。

字符、字符串比较原则

英文字母、标点,比如键盘上的各种字符: a,b,A,b, @,# 等的大小,由 “ASCII” 表定义。请执行到百度百科 ASCII 词条 阅读。比如 ‘(’ 的 ASCII 值是 40,而 ')' 是 41,那么 后者就比前者大。

当多个字符组成一个字符串时,并以 std::string 类型存储时,比较大小从第一个字母开始比,一直比到第一个不相同的值为止。如果比到某个字符串已经结束了,但另一个字符串还有字符,后者大。请自行测试:

std::string s1 = "ABC";
std::string s2 = "ABCD";

cout << (s1 > s2) << endl; // 0

s1 = "abc";
s2 = "ABC";
cout << (s1 > s2) << endl; //1 , 没错,小写字母的ASCII值比较大写的大。

注意,再一次强调:比较字符串时,请让参与比较的两个字符串数据,至少有一个使用std::string。否则,比较的是两个字符串字面常量背后的,内存地址的大小……还记得我们偷窥到的 (long long ) "任盈盈" 的地址吧?

汉字的比较

汉字进入计算时,存在如何表达的问题(称为编码方案),历史上出现很多不同的方案,因此对汉字的比较还需要考虑它的编码。通常,单独比较汉字的大小,没有什么业务上的意义,因此我们认为不用去深究汉字之间如何比大小,只需知道包含有汉字的字符串,同样可以比较大小,因此可以参与排序即可。

5. 逻辑操作符

重点是视频中所讲的几张表。

5.1 && 并且操作

true && true == true;

true && false == false;

false && true == true;

false && false == false;

5.2 ||或者操作

true || true == true;

true || false == true;

false || true == true;

false || false == false;

5.3 !取反

! true == false;
! false == true;

课堂作业-5

在代码中实践,测试以上三个逻辑操作。