C/C++语言提供了一系列实用的运算符以便计算。
算术运算符
有+,-,*,/,%
前面四个是相对熟悉的四则运算,不过这里要提一下的是,由于在C/C++语言中有数据类型的限制,计算的结果是和参与运算的类型有关的:
C++:
1 | int a=5,b=2; |
C:
1 | int a=5,b=2; |
输出:
a/b=2.000000
a/d=2.500000
由此发现:只有整型运算时,/进行整数除法,有实型参与运算时,将会进行实数除法。
这里的%是取模运算,a%b即求a/b的余数,虽然这个运算平时很少出现,但在离散数学领域,是有很多奇妙效果的,我们将在后续的实践中体验到。
关系运算符
有>,<,>=,<=,==,!=
分别为大于、小于,大于等于,小于等于,等于,不等于
在C/C++语言中,它们用于判断两个量之间的关系,如果成立,结果为1,不成立结果为0。
C++:
1 | int a=1,b=2,c=2,d=4; |
C:
1 | int a=1,b=2,c=2,d=4; |
输出:
a>b ?0
b==c ?1
c!=d ?1
输出显示:a>b的结果为假,b==c的结果为真,c!=d的结果为真。
逻辑运算符
有&&(与),||(或),!(非)三种
分别对应与、或、非三种逻辑。
劳技课认真上的同学应该对这三种最基本的逻辑门不陌生,没认真上的同学也应该对数学中集合的交、并、补这三种运算有了解(笑)。可以说这三种逻辑是人类逻辑的一个原点(也是使现代计算机拥有逻辑能力的唯一实现方法,可参考“现代计算机组成原理”)。
这里本来不打算引入真值表,因为程序设计的逻辑复杂度远没有硬件逻辑门这么深,还是放一下,以便大家参考。
与:
0 0 0
0 1 0
1 0 0
1 1 1
或:
0 0 0
0 1 1
1 0 1
1 1 1
非:
0 1
1 0
布尔型
C++中为布尔(逻辑)运算提供了专门的布尔数据类型
1 | bool a=true; |
类型名为bool(布尔Boolean的缩写),只有两个值true(真)和false(假),占一个字节。
C++中的布尔量可以进行逻辑运算:
1 | bool a=true,b=false; |
输出:
0
可以发现,布尔量a,b之间可以进行逻辑运算。而false/true只是0/1的一个别名。
在C中没有bool类型,一般用整型赋值为0和1来实现。
赋值运算符
是将运算和赋值合并的一种运算。在程序编写中,这一类运算特别常用,C/C++语言也提供了支持:
+=,-=,*=,/=,%=
以下每行等价:
1 | a+=b;a=a+b; |
自增运算符
特别的,如果要对一个变量自增、自减1,有以下运算:
++,--
以下每行等价:
1 | a++;a+=1;a=a+1; |
另外,区分以下两表达式:
1 | int i=3,x; |
我们发现,自增运算的前缀模式是先加再赋值,后缀模式是先赋值再加。虽然C/C++语言提供了这种灵活性,我们在初学时只需掌握++的后缀形式即可。
运算符的优先级
正如“先乘除、后加减”的运算法则,只有确定了优先级,程序的编写才没有二义性。
从高到低:
!
*、/、%
+、-
>、<、>=、<=
==、!=
&&、||
以上的每一行中的运算符优先级相同。
虽然C/C++语言还提供了如位运算、三目运算等其他运算符,我们在初学阶段不作要求。
表达式
有了运算符,我可以就可以组成各种表达式。其中,算术运算符组成的表达式称为算术表达式,关系运算符与逻辑运算符组成的叫逻辑表达式。在这里,有同学会有疑问:既有算术又有逻辑的是什么呢,答:看具体结果。
如:
1 | a+b//算术 |
(具体涉及原理性的内容可自习:表达式树)
可以发现,逻辑表达式的结果是一个布尔量,如:
1 | 1>0 //结果为true |
正如算术表达式/整型(或实型)变量/常数在代码中可以混合计算,逻辑表达式/布尔变量/布尔常量(true/false)也是一样:
1 | int a=10,b=20,c; |
可以自行计算上式中c和f的值,练习对表达式的理解。
(答案:c=305,f=true)
分支结构
是用计算机帮你思考的第一步。从此以后,程序就不是按照顺序按部就班的执行了,而是依照编写出的一定的规则执行。
if语句
if语句有两种形式:
1 | //1 |
其中的条件指的是一个逻辑表达式。
第一种:如果条件成立,执行语句1,否则不执行(即跳过语句1)。
第二种:如果条件成立,执行语句1,否则执行语句2。
if语句的嵌套
嵌套也是信息学中的重要概念,接下来的很多语句都可以嵌套。
1 | if(条件1) |
我们分析一下这段程序:
这段程序有两个if语句,其中的else中的语句又是一个if语句。整个程序的意思为:如果条件1成立,执行语句1,否则(“否则”中又是一个if语句){如果条件2成立,执行语句2,否则执行语句3}。
这样我们理论上是可以无限嵌套的,程序的逻辑也开始复杂起来。细心的同学会发现上面的代码不同的语句前面有长度不一的空格,这里我们引进概念:缩进。
缩进
缩进是一种让代码更让人一目了然的技巧。比如上面if嵌套的例子:我们把跟在if后面的语句往后推几个空格(一般是4个空格),表示这句语句属于这个if管辖,在else后面的那个if语句也往后几个空格(但要与前面的语句1对齐),表示这个if语句属于这个else,最后,语句二和语句3要比第二个if语句再往后推几个空格,表示从属关系。
我们可以发现,这个规则的目的是让同级别的语句落在同一列上,不同级别的语句错开,这种规则被形象地称为锯齿状,为了增加代码的可读性(就是能一眼就能看懂一段代码在说什么)。
事实上,C/C++语言不对代码的格式进行限制,也就是说如果代码不进行缩进操作也一样能编译运行,那为什么一定要养成缩进的好习惯呢?请看:
C(C++自行改cout):
1 | if(a>b) |
这是输出三个数大小顺序的代码片段,但是就这么几行,你能很快的读懂他想干什么吗?能很快地答出他编得是否正确?还是已经看晕了?
如果使用缩进:
1 | if(a>b) |
将会一目了然。
在初学阶段,程序简单,对格式的重视往往不够,但这对以后的进阶是不利的,我们还是要坚持缩进,多关注教程中其他代码的缩进规范。
语句块
我们又会遇到一个问题:一句if里面要执行多句语句怎么办呢?这里我们引出语句块的使用:
1 | if(条件1){ |
用一个大括号表示,大括号中的所有语句都将从属于一个if(或一个else)。
没错,int main(void){}的大括号也是语句块,表示里面编写的所有语句从属于这个main函数。事实上,C/C++语言中几乎任何用一句语句的场合都可以用语句块代替,实现在同一个条件下执行若干语句的功能。
有了分支结构,我们就可以解决有一定难度的问题了。
作业
思考:
1、什么是运算符?运算符起什么作用?我们为什么要运算符?
2、什么是表达式?什么是布尔量?什么是逻辑运算?
3、什么是分支结构?它实现了哪种功能?
4、什么是嵌套?在自然界/生活中,哪里体现了类似嵌套的思想?
5、什么是缩进?我们为什么要坚持缩进?
习题:
1、键盘输入一个正整数,判断是否能被3整除,能输出YES,不能输出NO
2、水仙花数是指一个三位正整数的各位数字的立方和等于它本身的数。输入一个正整数,判断是否为水仙花数,是输出YES,不是输出NO
3、键盘输入三个正整数,按从大到小顺序输出这三个数。
*4、输入正整数m,n,输出2019年的m月n日是星期几,用0到6表示(0为星期日)。
*5、小玉家的电费