![C语言从入门到精通(微视频精编版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/269/27563269/b_27563269.jpg)
第3章 表达式与运算符
(视频讲解:37分钟)
了解程序中会用的数据类型后,还要懂得如何操作这些数据,那么掌握C语言中各种运算符及其表达式的应用是必不可少的。
本章致力于使读者了解表达式的概念,掌握运算符及相关的表达式的使用,其中包括赋值运算符、算术运算符、关系运算符、逻辑运算符、位逻辑运算符和逗号运算符。每节都有对应实例进行相应的练习,可以及时地加深印象。
学习摘要:
表达式的使用
赋值运算符
算术运算符
关系运算符
逻辑和位逻辑运算符
逗号运算符
3.1 表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P67_10564.jpg?sign=1738883122-Q3NhmPOJ7KO1UkJ8gpOYc8MbQbXFvzk9-0-006909b3541f713d02a013d9872b9923)
视频讲解
表达式是C语句的主体。在C语言中,表达式由操作符和操作数组成。最简单的表达式可以只含有一个操作数。根据表达式含有的操作符的个数,可以把表达式分为简单表达式和复杂表达式两种。简单表达式是只含有一个操作符的表达式,而复杂表达式是含有两个或两个以上操作符的表达式。
下面通过几个表达式先进行观察一下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P67_74003.jpg?sign=1738883122-rK36U1XrTYuFNcXriBaQoP647W8yTQVH-0-1c1b3e7dcb7498a51b4a21b207f6b03b)
表达式本身什么事情也不做,只是返回结果值。在程序不对返回的结果值做任何操作的情况下,返回的结果值不起任何作用,也就是说忽略返回的值。
表达式产生作用有以下两种情况:
放在赋值语句的右侧。
作函数的参数。
表达式返回的结果值是有类型的。表达式隐含的数据类型取决于组成表达式的变量和常量的类型。
说明
每个表达式的返回值都具有逻辑特性。如果返回值是非零的,那么该表达式返回为真值,否则返回为假值。通过这个特点,可以将表达式放在用于控制程序流程的语句中,这样就构建了条件表达式。
【例3.1】 掌握表达式的使用。(实例位置:资源包\源码\03\3.1)
在实例中,声明了3个整型变量,其中有的变量被赋值为常数,有的变量被赋值为表达式的结果,最后将变量的值显示在屏幕上。
运行程序,显示效果如图3.1所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P67_10559.jpg?sign=1738883122-emDsXibtf5EQVSuXJ7Bur5VOPwUiTxRh-0-3c745015a9a93fcd689cbf421684e94d)
图3.1 掌握表达式的使用
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P67_74004.jpg?sign=1738883122-k6K92dN4K20vjmqfsBqKEYZFpt0SrmNA-0-a89622b0bbe3598db107e08709ce97ed)
代码分析:
(1)在程序中,主函数main中的第1行代码是声明变量的表达式,可以看到,我们可使用逗号通过一个表达式声明3个变量。
说明
在C语言中,逗号既可以作为分隔符,又可以用在表达式中。
① 逗号作为分隔符使用时,可以间隔说明语句中的变量或函数中的参数。例如上面程序中声明变量时,就属于在语句中使用逗号,将变量iNumber1、iNumber2和iNumber3进行分隔声明。使用代码来举例看一下这两种情况如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P68_74011.jpg?sign=1738883122-adokTciDCWyGzMjX8RQFG26Sl5DPFzrl-0-93176425d62bb776a35fe9711b0738b2)
② 逗号用在表达式中:可以将若干个独立的表达式联结在一起。其一般的表现形式如下:
表达式1,表达式2,表达式3,…
其运算过程就是先计算表达式1,然后计算表达式2,一直这样的计算下去。在后面的章节中会介绍循环语句,其中逗号就可以在for语句中使用,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P68_74012.jpg?sign=1738883122-go2LmSRmnY4Jj0LN3bW0uQHTep8WD8GW-0-5ba778b722bd5aa4d8f40789c4c58457)
(2)接下来的语句是使用常量为变量赋值的表达式,其中“iNumber1=3;”语句是将常量3赋值给iNumber1,“iNumber2=7;”语句是将7赋值给iNumber2。然后通过输出语句printf进行显示这两个变量的值。
(3)在语句“iNumber3=iNumber1+10;”中,表达式将变量iNumber1与常量10相加,然后将返回的值赋值给iNumber3变量,之后使用输出函数printf将iNumber3变量的值进行显示。接下来将变量iNumber2与常量10相加,进行相同的操作。
(4)在语句“iNumber3=iNumber1+iNumber2;”中,可以看到表达式中是两个变量相加,同样返回相加的结果,将其值赋给变量iNumber3,最后输出显示结果。
3.2 赋值运算符与表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P69_10731.jpg?sign=1738883122-9PTeBCMq7YHJQCCqFKsglqox5nF8T86G-0-412fc2768ac57eb510ef7ee0d5e3b156)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P69_10744.jpg?sign=1738883122-oeLGFI9ToJFPDN00x1Gkov8u4HD5mY6H-0-ac94a4d8c77100f079f62b4490292260)
动图演示
在程序中常常遇到的赋值符号“=”就是赋值运算符,赋值运算符的作用就是将一个数据赋给一个变量。例如:
iAge=20;
这就是一次赋值操作,是将常量20赋给变量iAge。同样也可以将一个表达式的值赋给一个变量。例如:
Total=Counter*3;
下面将进行详细地讲解。
3.2.1 变量赋初值
在声明变量时,可以为其赋一个初值,就是将一个常数或者一个表达式的结果赋值给一个变量。变量中保存的内容就是这个常量或者赋值语句中表达式的值。这就是为变量赋初值。
先来看一下有关为变量赋值为常数的情况。一般形式如下:
类型 变量名 = 常数;
其中的变量名,也称为变量的标识符。以下是变量赋初值的一般形式的代码实例:
char cChar ='A'; int iFirst=100; float fPlace=1450.78f;
赋值语句把一个表达式的结果值赋给一个变量。一般形式如下:
类型 变量名 = 表达式;
可以看到,其一般形式与常数赋值的一般形式是相似的,例如:
int iAmount= 1+2; float fPrice= fBase+Day*3;
在上面的举例中,得到赋值的变量iAmount和fPrice称为左值,因为出现的位置在赋值语句的左侧。产生值的表达式称为右值,因为出现的位置在表达式的右侧。
注意
这是一个重要的区别,因为并不是所有的表达式都可以作为左值,如常数,只可以作为右值。
在声明变量时,直接为其赋值称为赋初值,也就是变量的初始化。如果先将变量声明,再进行变量的赋值操作也是可以的。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P70_74026.jpg?sign=1738883122-6iMRYiwQHsJullnXTZfBo8VkKH2XbCUO-0-03db7ceb85869f35b83183519d48b24d)
【例3.2】 为变量赋初值。(实例位置:资源包\源码\ 03\3.2)
为变量赋初值这样的操作是程序中的常见操作,在本实例中,模拟钟点工的计费情况,使用赋值语句和表达式得出钟点工8个小时后所得的薪水。
运行程序,显示效果如图3.2所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P70_10870.jpg?sign=1738883122-84Cc4fIp3yA3Huz4Xn8XOoVvMRAJm4wY-0-545edbb77d5879f07236ecd4d3fdcb0b)
图3.2 为变量赋初值
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P70_74027.jpg?sign=1738883122-1JF3aTet83WqPx2D686eUUBpbbao63OM-0-0624a159a84537d25219a762f4aacaa1)
代码分析:
(1)钟点工的薪水是一个小时的工薪×工作的小时数量。所以在程序中需要3个变量来表示这个钟点工薪水的计算过程。iHoursWorded表示工作的时间,一般的工作时间都是固定的,在这里为其赋初值为8,表示8个小时。iHourlyRate表示一个小时的工薪。iGrossPay表示这个员工工作8个小时后,应该得到的工资。
(2)工资是可以变化的,iHourlyRate变量声明之后,为其设定工资为一个小时13。根据第一步中计算钟点工薪水的公式,得到总工薪的表达式,将表达式的结果保存在iGrossPay变量中。
(3)最后通过输出函数将变量的值和计算的结果都在屏幕上进行显示。
3.2.2 自动类型转换
数值类型有很多种,如字符型、整型、长整型和实型等,因为这些不同类型的变量有不同的长度和符号特性,所以取值范围也不同。在第2章中已经对此有所介绍,那么混合使用这些类型时会出现什么情况呢?
C语言中有一些特定的转换规则。根据这些转换规则,数值类型变量可以混合使用。如果把比较短的数值类型变量的值赋给比较长的数值类型变量,那么比较短的数值类型变量中的值会升级表示为比较长的数值类型,数据信息不会丢失。但是,如果把较长的数值类型变量的值赋给比较短的数值类型变量,那么数据就会降低表示级别,并且当数据大小超过比较短的数值类型的可表示范围时,就会发生数据截断。
有些编译器遇到这种情况时就会发出警告表示信息,例如:
float i=10.1f; int j=i;
此时编译器会发出警告,如图3.3所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P71_10892.jpg?sign=1738883122-32lbRWiCf4kuhRXYiOPOzry0lg2IP2lo-0-4a9ed7330e1f94d75c39d3e78337de18)
图3.3 程序警告
3.2.3 强制类型转换
在自动类型转换的介绍中得知,如果数据类型不同时,可以根据不同情况自动进行类型转换,但是这个时候编译器会提示警告信息。这个时候如果使用强制类型转换告诉编译器,那么编译器就不会出现警告。
强制类型转换的一般形式如下:
(类型名) (表达式);
例如,在上面的不同变量类型转换时使用强制类型转换的方法:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P71_74029.jpg?sign=1738883122-v5H4ZL9pktABK8DYrECY9GyjdZcQYdvz-0-9a6c6b96eb0f1dab72422fd7b119914d)
在代码中可以看到,在变量前使用包含要转换类型的括号,这样就对变量进行了强制类型转换。
【例3.3】 显示类型转换的结果。(实例位置:资源包\源码\03\3.3)
在本实例中,通过不同类型变量之间的赋值,将赋值操作后的结果进行输出,观察类型转换后的结果。
运行程序,显示效果如图3.4所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P71_10954.jpg?sign=1738883122-mBigEZKAKViJP939MdPnaQMxjZ5JSyoR-0-651f128b62adbac066693099ae3583c3)
图3.4 显示类型转换的结果
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P71_74030.jpg?sign=1738883122-e1pZlAxPr8WbUWx6QbvXfkuwCEZiqwzW-0-bb7655a976cdc720617c3be812a151f6)
在程序中定义一个单精度浮点型变量,然后通过强制转换将其赋给不同类型的变量。像这样由高的级别向低的级别转换,可能会出现数据的丢失,所以在使用强制转换时要注意此问题。
3.3 算术运算符与表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P72_11118.jpg?sign=1738883122-d7vPdLJxjw7B9esNkFBxYfZzTtK2YXOc-0-37cda9fd4e7e17503e5416ee2d8c9dcd)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P72_11107.jpg?sign=1738883122-8Ynn0Zd1N0j37wf6PN84py6WKAUTiNO3-0-52c7f5b5c7870ac564eab42e6c052e36)
动图演示
C语言中有两个单目算术运算符、5个双目算术运算符。在双目运算符中,乘法、除法和取模运算符比加法和减法运算符的优先级高,而单目正和单目负运算符的优先级最高。在下面对此进行详细介绍。
3.3.1 算术运算符
算术运算符包括两个单目运算符(正和负)、5个双目运算符(乘法、除法、取模、加法和减法)。具体符号和对应的功能如表3.1所示。
表3.1 算术运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T72_74034.jpg?sign=1738883122-1BWBGlK54mIYkpPIuTIcohph0Wntk0j9-0-a52a38a9e8a2b4087ea1e8b120666628)
在上述的算术运算符中,取模运算符“%”用于计算两个整数相除得到的余数,并且取模运算符的两侧均为整数,例如,7%4的结果是3。
说明
其中的单目正运算符是冗余的,也就是为了与单目负运算符构成一对而存在的。单目正运算符不会改变任何事情,例如,不会将一个负值表达式改为正。
注意
运算符“-”作为减法运算符,此时为双目运算符,例如“5-3”。“-”也可作负值运算符,此时为单目运算,例如-5等。
3.3.2 算术表达式
在表达式中使用了算术运算符,则将表达式称为算术表达式。下面是一些算术表达式的例子,其中使用的运算符就是表3.1中所列出的算术运算符。
Number=(3+5)/Rate; Height= Top-Bottom+1; Area=Height * Width;
需要说明的是,两个整数相除的结果为整数,例如7/4的结果为1,舍去的是小数部分。但是,如果其中的一个数是负数时会出现什么情况呢?此时机器会采取“向零取整”的方法,即为-1,取整后向零靠拢。
注意
如果参与加、减、乘、除运算的两个数中有一个为实数,那么结果是double型,因为所有实数都是按double型进行运算。
【例3.4】 使用算术表达式计算摄氏温度。(实例位置:资源包\源码\03\3.4)
在本实例中,通过在表达式中使用上面介绍的算术运算符,完成计算摄氏温度,把用户输入的华氏温度换算为摄氏温度,然后显示出来。
运行程序,显示效果如图3.5所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P73_11239.jpg?sign=1738883122-ZaXxEPiYiSOr6u6DTAk2auec2xaPPBAl-0-e5bbd86460abae792ad7d89e9321eb64)
图3.5 使用算术表达式计算摄氏温度
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P73_74039.jpg?sign=1738883122-6ZZPERHOtoq77XJtoZKF06kVzxScXmmW-0-865f11c93b5572b5b06e4a70ccd96051)
代码分析:
(1)在主函数main中声明两个整型变量,iCelsius表示摄氏温度,iFahrenheit表示华氏温度。
(2)使用printf函数进行显示提示信息。之后使用格式输入函数scanf获得在键盘上输入的数据,其中%d是格式字符,用来表示输入有符号的十进制整数,在这里输入为80。
(3)利用算术表达式,将获得华氏温度转换成摄氏温度。最后将转换的结果进行输出,可以看到80是用户输入的华氏温度,而26是计算后输出的摄氏温度。
3.3.3 优先级与结合性
C语言中规定了各种运算符的优先级和结合性,首先来看一下有关算术运算的优先级。
算术运算符的优先级
在表达式求值时,先按照运算符的优先级别次序由高到低执行,算术运算符中*、/、%的优先级别高于+、-的级别。例如,如果在表达式中同时出现*和+,那么先运算乘法。
R=x+y*z;
在表达式中,因为*比+的优先级高,所以会先进行y*z的运算,最后再加上x。
说明
在表达式中常会出现这样的情况,例如要进行a+b然后将结果再与c相乘,将表达式写成a+b*c。可是因为*的优先级高于+,这样的话就会先执行乘法运算,这不是期望得到的结果,这时应该怎么办呢?此时可以使用括号“( )”将级别提高,先进行运算,这样就可以得到预期的结果了。例如解决上面的方法是(a+b)*c。括号可以使其中的表达式先进行运算的原因在于,括号在运算符中的优先级别是最高的。
算术运算符的结合性
当算术运算符的优先级相同时,结合方向为“自左向右”。例如:
a-b+c
因为减法和加法的优先级是相同的,所以b先与减号相结合,执行a-b的操作,之后再执行加c的操作。这样的操作过程就称为“自左向右的结合性”,在后面的介绍中还可以看到“自右向左的结合性”。表3.2中列出了C语言中运算符的优先级和结合性。
表3.2 运算符的优先级和结合性
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T74_74050.jpg?sign=1738883122-clvqswWp1Rr8QDM489KTjM8QKfiPvGRV-0-dc33471412e4faf3948cbf2c87c041f1)
【例3.5】 算术运算符优先级和结合性。(实例位置:资源包\源码\03\3.5)
在本实例中,通过不同的运算符的优先级和结合性,使用printf函数显示最终的计算结果,根据结果可以体会优先级和结合性的概念。
运行程序,显示效果如图3.6所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P75_11577.jpg?sign=1738883122-hFjDAZAXArzabXETrzFnkWHfdxxDUH5D-0-718f2a0333d3a151bcce3e66fccd24c9)
图3.6 优先级和结合性
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P75_74053.jpg?sign=1738883122-oXptd0EzdA1hoV4bqVfwiHSmkb44LsW6-0-8e5f33626605fd80b7fbc075ca27775d)
代码分析:
(1)在程序中先进行声明要用到的变量,其中iResult的作用为存储计算结果。接下来为其他的变量进行赋值。
(2)使用算术运算符完成不同的操作,根据这些不同的操作输出的结果来观察优先级与结合性。
根据语句“iResult=iNumber1+iNumber2-iNumber3;”与“iResult=iNumber1-iNumber2+iNumber3;”的结果,表示相同优先级别的运算根据结合性由左向右进行运算。
语句“iResult=iNumber1+iNumber2*iNumber3;”与上面的语句进行比较,可以看出不同级别的运算符按照优先级进行运算。
语句“iResult=iNumber1/iNumber2*iNumber3;”又体现出同优先级的运算符按照结合性进行运算。
语句“iResult=(iNumber1+iNumber2)*iNumber3;”中使用括号提高优先级,使括号中的表达式先进行运算。表现出括号在运算符中具有最高优先级。
3.3.4 自增自减运算符
在C语言中还有两个特殊的运算符,即自增运算符“++”和自减运算符“--”。自增运算符和自减运算符对变量操作分别是增加1和减少1,如表3.3所示。
表3.3 自增运算符和自减运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T76_74060.jpg?sign=1738883122-OHZZWw3hZop9zpCpRfyEyfROiIobSCcb-0-47f158e3c4a21354e58c365bcc50c547)
自增运算符和自减运算符可以放在变量的前面或者后面,放在变量前面称为前缀,放在后面称为后缀,使用的一般方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P76_74057.jpg?sign=1738883122-LVmBVh08LCt234K9JOq1fnPiQEflgO2t-0-ad422a89d9a41810ca4e3b396ad4adf3)
在上面这些例子中,运算符的前后位置不重要,因为所得到的结果是一样的,自减就是减1,自增就是加1。
注意
但是在表达式内部,作为运算的一部分,那么两者的用法可能有所不同。如果运算符放在变量前面,那么变量在参加表达式运算之前完成自增或者自减运算;如果运算符放在变量后面,那么变量的自增或者自减运算在变量参加了表达式运算之后完成。
【例3.6】 比较自增自减运算符前缀与后缀的不同。(实例位置:资源包\源码\03\3.6)
在本实例中定义一些变量,为变量赋相同的值,然后通过前缀和后缀的操作来观察在表达式中前缀和后缀的不同结果。
运行程序,显示效果如图3.7所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P77_11853.jpg?sign=1738883122-izR5QjWFmGoarFd6QmqS0i30iZh77okd-0-0095b622a4b07657be4f2ae5ec22b207)
图3.7 比较自增自减运算符前缀与后缀的不同
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P77_74062.jpg?sign=1738883122-HS0AHKuCImLM07BDEpnek7QGcbUIDOcf-0-31ed56a4c1fa427ef5c90b65f3b4c458)
代码分析:
(1)在程序代码中,定义的iNumber1和iNumber2两个变量用来进行自增、自减运算。
(2)进行自增运算,分为前缀自增和后缀自增。通过程序最终的显示结果可以看到,自增变量iNumber1和iNumber2的结果都是4,但是得到表达式结果的两个变量iResultPreA和iResultLastA却不一样。iResultPreA的值为4,iResultLastA的值为3,因为前缀自增使得iResultPreA变量先进行自增操作,然后进行赋值操作;后缀自增操作是先进行赋值操作,后进行自增操作。所以两个变量得到表达式的结果值是不一样的。
(3)在自减运算中,前缀自减和后缀自减与自增运算方式是相同的,前缀自减先进行减1操作,然后再赋值操作;而后缀自减先进行赋值操作,再进行自减操作。
3.4 关系运算符与表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P78_11952.jpg?sign=1738883122-UxRR3sldImk4xOA1frbViCIDD1n20BVn-0-4e8c64d7e082e93fd4e5d6624550110f)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P78_11941.jpg?sign=1738883122-d95lZ5uSFi8MX49PE3VgOEYB140mMXrh-0-8068d67018f4ca961262c31f0279a385)
动图演示
在数学运算中,经常会看到对两个数进行比较大小关系或者是否相等。在C语言中,关系运算符的作用就是用来判断两个操作数的大小关系。
3.4.1 关系运算符
关系运算符包括大于运算符、大于等于运算符、小于运算符、小于等于运算符、等于运算符、不等于运算符。在表3.4中列出了这6种关系运算符所对应的符号。
表3.4 关系运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T78_74064.jpg?sign=1738883122-KruzDRFGRpSYzVs1JI0ZJvXSQsnHXkc8-0-fe7445ceb733f5b92421eb74a6ea67a2)
注意
符号“>=”与“<=”的意思分别是大于或等于,小于或等于。
3.4.2 关系表达式
关系运算符对两个表达式的值进行比较,返回一个真值或者假值。返回真值还是假值取决于表达式中的值和所用的运算符。其中真值为1,假值为0,真值表示指定的关系成立,而假值则表示指定的关系不成立。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P78_74065.jpg?sign=1738883122-YBG0Lz6vdLnNDXcCd6WNwhYwwK79RYiw-0-b1810a12d8d2b1057113da8a18fe7adc)
关系运算符通常用来构造条件表达式,用在程序流程控制语句中,例如if语句是根据判断条件而执行语句块的,在其中使用关系表达式作为判断条件,如果关系表达式返回的是真值,那么执行下面的语句块;如果为假值就不去执行,代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P79_74068.jpg?sign=1738883122-AqlCRPmRLDPkMa0ITjXVoVUoj7mjjgNl-0-ef82ce7ead96bedc811b001c27dac4d4)
其中,if(iCount<10)就是判断iCount小于10这个关系是否成立,如果成立则为真,如果不成立则为假。
注意
在进行判断时,一定要注意等号运算符的使用“==”,千万不要与赋值运算符“=”弄混。例如在if语句中进行判断,使用的是“=”时:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P79_74072.jpg?sign=1738883122-CANMaYDV1XcNFxOq2nn4URIVXzM4Qozw-0-82b5c364efc68824962e83e16c4732ad)
上面的代码看上去是在检验变量Amount是否等于常量100,但是事实上没有起到这个效果。因为表达式使用的是赋值运算符“=”而不是等于运算符“==”。赋值表达式Amount=100,本身也是表达式,其返回值是100。既然是100,说明是非零值也就是为真值,这样的话该表达式的值始终为真值,没有起到判断的作用。如果赋值表达式右侧不是常量100,而是变量,则赋值表达式的真值或假值就由这个变量的值决定。
因为这两个运算符在语言上的差别,使得在使用它们构造条件表达式时很容易出现错误,新手在编写程序时一定要注意。
3.4.3 优先级与结合性
关系运算符的结合性都是自左向右的。使用关系运算符时常常会判断两个表达式的关系,但是由于运算符存在着优先级的问题,所以如果不小心处理会出现错误。例如要进行这样的判断操作:先对一个变量进行赋值,然后判断这个赋值的变量是否不等于一个常数,代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P79_74069.jpg?sign=1738883122-ODVpBRsZzc3mjXAWvEZChAqpYbBRRDwY-0-ce7b5ed760aaa97ad2b0ffc73eed79cd)
因为“!=”运算符比“=”的优先级要高,所以NewNum!=10的判断操作会在赋值之前实现计算,变量Number得到的就是关系表达式的真值或者假值,这样并不会按照预想的意愿执行。
曾经介绍过有关括号运算符的使用,括号运算符的优先级具有最高性,所以使用括号来表示要优先计算的表达式,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P80_74073.jpg?sign=1738883122-EyOccgZA3J9QFtgllbS8dS5XlOo606GB-0-0410f88ec91376cd0a4ee10fdd8a7a68)
这种写法比较清楚,不会产生混淆,也不会对代码的含义产生误解。由于这种写法格式比较精确简洁,所以被多数的程序员所喜爱。
【例3.7】 关系运算符的使用。(实例位置:资源包\源码\03\3.7)
在本实例中,定义两个变量表示两个学科的分数,使用if语句进行判断两个学科的分数大小,通过使用printf输出函数显示信息得到比较的结果。
运行程序,显示效果如图3.8所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P80_12220.jpg?sign=1738883122-1G3Lj9acA6JcPVE7jXXB8z3o2zXeeOaA-0-287b8e1b3c832ba3e0df97c7437dfe73)
图3.8 关系运算符的使用
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P80_74074.jpg?sign=1738883122-ewF0aSQ5p0Oxtlca8SHRHv7Ekqxz1qoh-0-0df57066816db76b1b29c9e340b28bc9)
为了可以在键盘上得到两个学科的分数,定义变量iChinese和iEnglish。之后利用if语句进行判断,在判断条件中使用了关系表达式,判断分数是否使得表达式成立。如果成立返回真值,如果不成立返回假值。最后根据真值和假值选择执行语句。
3.5 逻辑运算符与表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P81_12304.jpg?sign=1738883122-95LyShXe4a9cjRpeWy0xCvxZOfaBr6c8-0-3f568f4ac41cf8a057c591500f2164ab)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P81_12317.jpg?sign=1738883122-lAitJQL3M7wnYTnNGFPLrh3kb4h4LJT5-0-2e563e97c1913cf5c021c7cf4376b19d)
动图演示
逻辑运算符根据表达式的真或者假属性返回真值或假值。在C语言中,表达式的值非零,那么其值为真。非零的值用于逻辑运算,则等价于1;假值等价于0。
3.5.1 逻辑运算符
逻辑运算符有3种,如表3.5所示。
表3.5 逻辑运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T81_74076.jpg?sign=1738883122-V8eYS1Fosd8LoVReT5HeYpQjslmCoGMy-0-5a0735fcac7b7344980499c2449b9887)
注意
逻辑与运算符“&&”和逻辑或运算符“||”都是双目运算符。
3.5.2 逻辑表达式
之前了解到关系运算符可对两个操作数进行比较,使用逻辑运算符可以将多个关系表达式的结果合并在一起进行判断。其一般形式如下:
表达式 逻辑运算符 表达式
例如下面使用逻辑运算符:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P81_74077.jpg?sign=1738883122-UkVWTVJZPa23U6NusonCoDFCy7nEecfO-0-2450b8b9f896a217574d7f1fa1a7402d)
注意不要把逻辑与运算符“&&”和逻辑或运算符“||”与下面要讲的位与运算符“&”和位或运算符“|”混淆。
逻辑与运算符和逻辑或运算符可以用于相当复杂的表达式中。一般来说,这些运算符用来构造条件表达式,用在控制程序的流程语句中,例如在后面章节中要介绍的if、for、while语句等。
在程序中,通常使用单目逻辑非运算符“!”把一个变量的数值转换为相应的逻辑真值或者假值,也就是1或者0。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P82_74078.jpg?sign=1738883122-AVnO7j915u07EPZbJtlAkGXlomnnQIcJ-0-5b507406434338346779c6d3cd7048d0)
3.5.3 优先级与结合性
“&&”和“||”是双目运算符,它要求有两个操作数,结合方向自左至右;“!”是单目运算符,要求有一个操作数,结合方向自左向右。
逻辑运算符的优先级从高到低依次为单目逻辑非运算符“!”、逻辑与运算符“&&”、逻辑或运算符“||”。
【例3.8】 逻辑运算符的应用。(实例位置:资源包\源码\ 03\3.8)
在本实例中,使用逻辑运算符构造表达式,通过输出显示表达式的结果,根据结果分析表达式中逻辑运算符的计算过程。
运行程序,显示效果如图3.9所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P82_12430.jpg?sign=1738883122-RqwOK7CJUNs0aG7J0SnF63MmbezJdvcz-0-086a3aac6f6d3875f422d07bdb968c71)
图3.9 逻辑运算符的应用
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P82_74079.jpg?sign=1738883122-4txRvXIsoTfsh2m9A2WJRaAuJIkfQbyr-0-bc5a565f0dfc279dae40c0de19a6029b)
代码分析:
(1)在程序中,先声明两个变量用来进行下面的计算。为变量赋值,iNumber1的值为10,iNumber2的值为0。
(2)先进行输出信息,说明显示为1表示真值,0表示假值。在printf函数中,进行表达式的运算,最后将结果输出。分析一下表达式“5<iNumber1&&iNumber2”,因为“<”运算符的优先级高于“&&”运算符,所以先执行关系判断,之后再进行与运算。iNumber1的值为10,数值5小于iNumber1成立,为真,也就是1,而iNumber2的值为0,“真&&假”的值为假,返回结果为0。表达式“5<iNumber1||iNumber2”中,数值5小于iNumber1的值不成立,为假,也就是0,而iNumber2的值为0,“真||假”的值为真,返回结果为1。
(3)将iNumber1进行两次单目逻辑非运算,得到逻辑值,因为iNumber1的数值是10,所以逻辑值为1。
3.6 位逻辑运算符与表达式
位运算是C语言中一个比较有特色的地方。位逻辑运算符实现位的设置、清零、取反和取补操作。利用位运算可以实现很多汇编语言才能实现的功能。
3.6.1 位逻辑运算符
位运算符包括位逻辑与、位逻辑或、位逻辑异或、取补,如表3.6所示。
表3.6 位逻辑运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T83_74082.jpg?sign=1738883122-moQPWuZyfHMGZ51KBEBICbR9BA7cLyGC-0-96b92fdc9408d5d5553e7a59561656f4)
在表3.6中除了最后一个运算符是单目运算符外,其他的都是双目运算符。该表中列出的运算符只能用于整型表达式。位逻辑运算符通常用于对整型变量进行位的设置、清零和取反,以及对某些选定的位进行检测。
3.6.2 位逻辑表达式
在程序中,位逻辑运算符一般被程序员用来作为开关标志。较低层次的硬件设备驱动程序,经常需要对输入/输出设备进行位操作。
例如位逻辑与运算符的典型应用,对某个与的位设置进行检查:
if(Field & BITMASK)
语句含义的是,if语句对后面括号中的表达式进行检测。如果表达式返回的是真值,则执行下面的语句块,否则不执行该语句块。其中运算符用来对BITMASK变量的位进行检测,检测是否与Field变量的位有相吻合之处。
3.7 逗号运算符与表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P83_12492.jpg?sign=1738883122-X0G6Jx9XRJvSk7wUt60516FB5Meb73aY-0-d6c4e1c43ac708d9385f3ac330825369)
视频讲解
在C语言中,可以用逗号将多个表达式分隔开来。其中用逗号分隔的表达式被分别计算,并且整个表达式的值是最后一个表达式的值。
逗号表达式后称为顺序求值运算符。逗号表达式的一般形式如下:
表达式1,表达式2,…,表达式n
逗号表达式的求解过程是:先求解表达式1,再求解表达式2,一直求解到表达式n。整个逗号表达式的值是表达式n的值。
观察下面使用逗号运算符的代码:
Value=2+5,1+2,5+7;
上面语句中Value所得到的值为7,并非为12。整个逗号表达式的值不应该是最后一个表达式的值,为什么不等于12呢?答案在于优先级的问题,由于赋值运算符的优先级比逗号运算符的优先级高,所以先执行的赋值运算。那么如果先执行逗号运算,可以使用括号运算符,代码如下:
Value=(2+5,1+2,5+7);
使用括号之后,此时Value的值为12。
【例3.9】 用逗号分隔的表达式。(实例位置:资源包\源码\03\3.9)
本实例中,通过逗号运算符将其他运算符结合在一起形成表达式,再将表达式的最终结果赋值给变量。由显示变量的值,分析逗号运算符的计算过程。
运行程序,显示效果如图3.10所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P84_12638.jpg?sign=1738883122-3LGff746qQFlOzOtzuU4mLFzubn8VkeL-0-b94de3115bd1e5b60de1e85e1fe9741e)
图3.10 用逗号分隔的表达式
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P84_74086.jpg?sign=1738883122-bfOA2jmQYjQMKBsLP8NKFeK9OO5utRRf-0-a4f98cf10940c7d93e0a0cf3cf849df2)
代码分析:
(1)在程序代码的开始处,声明变量时就使用了逗号运算符进行分隔声明变量。在本小节之前,就已经对此有所讲述。
(2)之后,将前面使用逗号分隔声明的变量进行赋值。在逗号表达式中,赋值的变量进行各自的计算,变量iResult得到表达式的结果。这里需要注意的是,通过输出可以看到iResult的值为10,从前面的讲解知道因为逗号表达式没有使用括号运算符,所以iResult得到第一个表达式的值。在第一个表达式中,iValue1变量进行的是后缀自加操作,于是iResult先得到iValue1的值,iValue1再进行自加操作。
(3)在第二个表达式中,由于使用了括号运算符,所以iResult变量得到的是第三个表达式iValue3+4的值,iResult变量赋值为30。
3.8 复合赋值运算符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P85_12725.jpg?sign=1738883122-MemDz8LNc10o7Uunk2ArF7uA0eONKJrG-0-670ded06fe0cf5fecf44a53e88ef9b49)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P85_12734.jpg?sign=1738883122-4EK0mFHs3EVhs9S9nB01eF3VV9Yze4gE-0-54ca00ad8b0783a6d091e8282323767c)
动图演示
复合赋值运算符是C语言中独有的,这种操作实际是一种缩写形式,使得变量更为简洁。例如在程序中为一个变量赋值:
Value=Value+3;
这个语句是对一个变量进行赋值操作,值为这个变量本身与一个整数常量3相加的结果值。使用复合赋值运算符可以实现同样的操作。例如上面的语句可以改写成:
Value+=3;
这种操作使得语句更为简洁,关于上面两种实现相同操作的语句,复合赋值运算符相比赋值运算符的优点在于:
简化程序,使程序精炼。
提高编译效率。
对于简单赋值运算符,如“Func=Func+1”中,表达式Func计算两次,对于复合赋值运算符,如“Func+=1”中,表达式Func仅计算一次。一般来说,这种区别对于程序的运行没有太大的影响。但是,如果表达式中存在某个函数的返回值,那么函数被调用两次。
【例3.10】 使用复合赋值运算符简化赋值运算。(实例位置:资源包\源码\03\3.10)
运行程序,显示效果如图3.11所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P85_12720.jpg?sign=1738883122-MIzdYlp2aqFuRbjQUVhm5q8RporcQn8Y-0-c3d0473fc1241a4dd8439f64d7a01bd8)
图3.11 使用复合赋值运算符简化赋值运算
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P85_74093.jpg?sign=1738883122-fQ3l92uZiQaYNG2NX2tx9IkHdzaOXv8j-0-6589f66eafa9d1027fbe2b28674b9c49)
在程序代码中,可以看到语句“iValue*=iDetail”中使用了复合赋值运算符,表示的意思是iValue的值等于iValue*iDetail的结果。而“iTotal+=iValue”表示的是iTotal的值等于iTotal+iValue的结果。最后将结果显示输出。
3.9 实战
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P86_12794.jpg?sign=1738883122-HMXdrS4kwDIdnypfwkGMfE6JNGtaQwls-0-86ddd5cc35bf9ef5944b7a4430bc857f)
视频讲解
3.9.1 求1~10的累加和
利用加法运算符计算1~10的累加和,运行效果如图3.12所示。(实例位置:资源包\源码\03\实战\01)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P86_12782.jpg?sign=1738883122-fjVyufYsdCASs97Tbtu1IW3WqN7HUVKU-0-84c695116fd78423a5dd69cf016dd066)
图3.12 求1~10的累加和
3.9.2 计算学生平均身高
输入3个学生的身高,并用空格分隔开来。运行结果如图3.13所示。(实例位置:资源包\源码\03\实战\02)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P86_12787.jpg?sign=1738883122-eLATm4HZ9gZuTTwwpZMiHQIgQfh3wJyj-0-69876197a0e31f765b1df6209128b8db)
图3.13 计算学生的平均身高
3.9.3 求一元二次方程ax2+bx+c=0的根
求解一元二次方程的根,由键盘输入系数,输出方程的根。这种问题类似于给出公式计算求解,可以按照输入数据、计算、输出3步方案来设计运行程序。(实例位置:资源包\源码\03\实战\03)
问题中已知的数据为a、b、c,待求的数据为方程的根,设为x1、x2,数据的类型为double类型。已知的数据可以输入(赋值)取得。
已知一元二次方程的求根公式为和
,可以根据公式直接求得方程的根。为了使求解的过程更简单,可以考虑使用中间变量来存放判别式b2-4ac的值。最后使用标准输出函数把求得的结果输出。
运行程序,输入方程的系数,计算出表达式的根,效果如图3.14所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P87_12823.jpg?sign=1738883122-SH2ZGbZ4qwrPGfzYX7CyZBVO7ncLbQiK-0-4483c20ef8d1b46a25c9ee4e7b863af5)
图3.14 求一元二次方程的根
3.9.4 求字符串中字符的个数
输入一个字符串,计算出该字符串共含有多少个字符。运行结果如图3.15所示。(实例位置:资源包\源码\03\实战\04)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P87_12828.jpg?sign=1738883122-fjdAXz8o1H4XRYD7kf9OCPsKXXzbKDcv-0-68ebdb06fc9e71ca7029a716aa824c46)
图3.15 求字符串中字符个数
3.9.5 计算a+=a*=a/=a-6
实现运用复合运算符计算表达式a+=a*=a/=a-6的值,设置a的值为12,运行程序,效果如图3.16所示。(实例位置:资源包\源码\03\实战\05)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P87_12833.jpg?sign=1738883122-olfP0oK7GFT89LpevATsSJClRedYTO8o-0-c50c63d4477c901ac70b489fd9b66684)
图3.16 复合运算符计算表达式