自学C语言-4

第4章 运算符与表达式

了解了程序中常用的数据类型后,还应该懂得如何操作这些数据。因此,掌握C语言中各种运算符与表达式是必不可少的。本章致力于使读者了解表达式的概念,掌握运算符及相关表达式的使用方法,其中包括赋值运算符、算术运算符、关系运算符、逻辑运算符、位逻辑运算符、逗号运算符和复合赋值运算符,并且通过实例进行相应的练习,加深印象。
本章的知识架构及重难点如下:
在这里插入图片描述

4.1 表达式

C语言中,表达式由操作符和操作数组成。简单的表达式只包含一个操作符,复杂的表达式包含两个或两个以上操作符。例如:

25+25
num+29
iBase+(iPay*iDay)
	表达式可出现在赋值语句的右侧或函数的参数中。表达式可返回一个结果,其数据类型取决于组成表达式的变量和常量的类型。说明:表达式的返回值具有逻辑特性:如果返回值非零,那么返回的是真值,否则返回的是假值。因此,可以将表达式放在流程控制语句中,形成条件表达式。【例4.1】编程中的数学计算  本实例定义了3个整型变量,首先对两个变量赋值并输出,然后通过3次计算,将3个表达式的结果依次赋值给第3个变量,最后将变量的值显示在屏幕上。![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/18d034b34ad14c78a4ca4cdad4b75c3a.png#pic_center)

在这里插入图片描述(1)主函数main中首先定义3个变量,然后为变量赋值。“iNumber1=3;”表示将3赋值给iNumber1,"iNumber2=7;"表示将7赋值给iNumber2,然后通过输出语句printf显示这两个变量的值。
(2)语句“iNumber3=iNumber1+10;"中,表达式将变量iNumber1与常量10相加,然后将返回的值赋给iNumber3变量,之后使用输出函数printf将iNumber3变量的值进行显示。接下来将变量iNumber2与常量10相加,进行相同的操作。
(3)语句”iNumber3=iNumber1+iNumber2;"中,iNumber1和iNumber2两个变量相加,将返回的和赋给变量iNumber3,最后输出显示结果。
运行程序,显示效果如上图所示。
编程训练
训练1:计算两个数的和 定义两个整型变量,分别赋值为520和1314,然后输出两数相加的结果。输出结果如下:

加数一是:520
加数二是:1314
相加的和是:1834

在这里插入图片描述
训练2:求三角形第三边的长度范围 三角形中,任何一边的长度都大于其他两边之差,小于其他两边之和。一个三角形的两边分别是13、16,求第三边的取值范围。输出结果如下:

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3c9f1fceaadf45eb93b735260fbbeb0c.png#pic_center)

在这里插入图片描述

4.2 赋值运算符与赋值表达式

程序中常常遇到的赋值符号"="就是赋值运算符,其作用就是将一个数据赋给一个变量。例如:

iAge = 520;

这就是一 次赋值操作,将常量520赋给变量iAge。也可以将一个表达式的值赋给一个变量,例如:

Total = Counter*3;

4.2.1 变量赋初值

在声明变量时,可以为其赋一 个初值,就是将一个常数或者一个表达式的结果赋值给一个变量,变量中保存的内容就是这个常量或者赋值语句中表达式的值。这就是为变量赋初值。

1.将常数赋值给变量

先来看一下将常数赋值给变量的标识符。例如:

char cChar='A';
int iFirst=100;
float fPlace=1450.78f;

2.通过赋值表达式为变量赋初值
通过赋值语句,可把一个表达式的结果值赋给一个变量。一般形式如下:

类型	变量名 = 表达式;

可以看到,与常数赋值的一般形式是相似的。例如:

int iAmount = 12+26;
float fPrice = fBase + Day * 3;

在上面的代码中,得到赋值的变量iAmount和fPrice称为左值,因为它出现在赋值语句的左侧。产生值的表达式称为右值,因为它出现在表达式的右侧。在定义变量的同时直接为其赋值的操作称为赋初值,也就是变量的初始化。先定义变量,再进行变量的赋值操作也是可以的。例如:

int iMonth;								/*定义变量*/
iMonth = 212;							/*为变量赋值*/

【例4.2】计算乘坐出租车的费用 出租车每千米路程需要3元,李女士要到10千米远的地方,后来发现走错了,之后又坐出租车返回3千米,计算她需要花多少钱才能到达目的地。代码如下:
在这里插入图片描述
(1)出租车费用的计算公式是“每千米路程的费用x路程”。因路线错误,需要返回3千米,因此需要定义4个变量来计算乘出租车的费用。price表示每千米路程费用,journey1表示距离目的地的路程,journey2表示因走错返回的路程,money表示乘出租车的总费用。
(2)每千米路程的费用是固定的(3元),根据公式计算总车费,并将表达式的结果保存在money变量中。
(3)最后通过输出函数,将计算结果在屏幕上显示。
运行程序,显示效果如上图所示。

4.2.2 自动类型转换

数值类型有多种,如字符型、整型、长整型、实型等,其变量、长度和符号特性都不同,取值范围也不同。3.8节中介绍了C语言中默认存在的一些自动类型转换规则,根据这些规则,不同的数值类型变量之间可以混合运算。除此之外,不同数据类型变量间相互赋值时也会进行自动类型转换。
例如,把较短的数值类型变量的值赋给较长的数值类型变量时,较短的数值类型变量其值会自动升级为较长的数值类型,数据信息不会丢失。但把较长的数值类型变量的值赋给较短的数值类型变量时,数据会降低级别显示。当数据大小超过较短的数值类型的可表示范围时,就会发生数据截断。
有些编译器遇到这种情况时会发出警告信息。例如,把一个实型变量赋值给一个整型变量时:
float i=10.1f;
int j=i;
此时编译器会发出警告,提示实型(float)转换为整型(int)时将发生数据截断,如图4.3所示。
warning c4244:'initializing' : conversion from 'float' to 'int', possible loss of data

图4.3 程序警告
误区警示:C语言中,整数的默认类型是int,浮点数的默认类型是double。如果一个表达式中数字都是int型,则表达式结果也默认为是int型。例如,计算5除以2,如果这么写:
double b=5/2;
计算后发现b的值是2.0,而不是2.5。这是因为5和2都是int型,所以表达式5/2的结果默认也是int型,即2。赋值给b后,因为b是double型,所以得到的结果是2.0. 要想得到正确的结果2.5,应该这样修改:

double b = 5.0/2;     /*将其中一个数改为实型*/

4.2.3 强制类型转换

通过自动类型转换的介绍得知,如果数据类型不同,系统会根据情况自动进行类型转换,但此时编译器会提示警告信息。如果使用强制类型转换告知编译器,就不会出现警告。
强制类型转换的一般形式如下:

(类型名)(表达式)

例如,在上述不同变量类型转换时使用强制类型转换:

float i=10.1f;
int j=(int)i;						/*进行强制类型转换*/

在代码中可以看到,在变量前使用包含要转换类型的括号,就对变量进行了强制类型转换。
【例4.3】计算载货区摆放箱子的数量 一辆货车运输箱子,载货区宽2米,长4米,一个箱子宽1.5米,长1.5米,计算可以运输多少个箱子。注意,箱子数必须为整数,不存在半个箱子。实现代码如下:
在这里插入图片描述
(1)程序中首先定义了3个整型变量,width表示载货区宽度,length表示载货区长度,num表示计算结果。然后定义了一个实型变量,f表示货物箱子的长、宽。最后用强制类型转换计算承载数。
(2)在强制类型转换代码中,用载货区的宽度除以箱子的宽度再强制转换成int类型,载货区的长度除以箱子的长度再强制转换成int类型,两者相乘,即可计算出最大能装载的箱子数量。
(3)最后通过输出函数,将计算的结果在屏幕上显示。
运行程序,显示效果如上图所示。
误区警示:如果某个表达式要进行强制类型转换,需要将该表达式用括号括起来,否则将只对表达式中的第一个变量或常量进行强制类型转换。例如:

float x=2.5f,y=4.7f;				/*定义2个实型变量并赋初值*/
int z=(int)(x+y);					/*将表达式x+y的结果强制转换为整型*/
int g =(int)x+y;						/*将x强制转换为整型,再与实型y相加*/

编程训练:
训练3:模拟超市抹零 购物时,如果买的东西总价多出1角、2角,收银员会抹掉,只收取整钱。模拟超市抹零结账场景,输出结果如下:

实际应付313.04元
抹零之后支付313

在这里插入图片描述
训练4:换季买鞋 买鞋时,如果37码鞋小,38码鞋大,则说明脚的尺寸是37.5码。因为没有37.5码的鞋码,所以我们一般买38码的鞋子。利用强制类型转换来模拟此场景,输出结果如下:

您的脚是37.5码的尺寸
您应该买38码的鞋子

在这里插入图片描述

4.3 算术运算符与算术表达式

C语言中,运算符分为单目运算符(使用一个操作数)和双目运算符(使用两个操作数)两种。其中,算术运算符用于实现正、负、加、减、乘、除、求余等运算。单目正和单目负运算符的优先级最高。双目运算符中,乘法、除法和取模运算符的优先级比加法和减法运算符高。

4.3.1 算术运算符

算术运算符包括两个单目运算符(正和负)和5个双目运算符(即乘法、除法、取模、加法和减法)。具体符号和对应的功能如表4.1所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/414f8993252f436393fdd27b0c65a816.png#pic_center)

在这里插入图片描述
其中,取模运算符“%”用于计算两个整数相除得到的余数,运算符的两侧均为整数,如7%4的结果是3。“—”作为减法运算符用时为双目运算符,如5-3;作负值运算符用时为单目运算符,如-5等。
说明:单目正运算符是冗余的,只是为了与单目负运算符构成一对才存在。单目正运算符不会改变任何数值,更不会将一个负值表达式改为正值。

4.3.2 算术表达式

使用算术运算符的表达式称为算术表达式,例如:

Number=(3+5)/Rate;
Height = Top-Bottom+1;
Area = Height * Width;

需要说明的是,两个整数相除的结果为整数,如7/4的结果为1,舍去的是小数部分。但是,如果其中的一个数是负数时会出现什么情况呢?此时机器会采取“向零取整”的方法,即为-1,取整后向0靠拢。
注意:参与算术运算的两个数中只要有一 个为实型,整个表达式的结果就是double型,这是因为所有实数都是按double型进行设定的。
【例4.4】使用算术表达式计算加速度 平均加速度,即速度的变化量除以这个变化所用的时间。现有一辆轿车用了8.7秒从每小时0千米加速到每小时100千米,计算并输出这辆轿车的平均加速度。
在本实例中,在表达式中使用算术运算符完成加速度计算,然后显示结果。
在这里插入图片描述
(1)在主函数main中定义两个整型变量,V1表示起始速度,V2表示加速度到最后的速度,并将单位km/h转换成m/s。
(2)再定义单精度类型变量t表示所用时间,双精度类型变量a表示加速度。
(3)利用公式“加速度=速度的变化量/所用的时间”计算加速度,将计算结果赋给变量a。
(4)利用printf函数将最后的计算结果显示在控制台上。
运行程序,显示效果如上图所示。

4.3.3 优先级与结合性

C语言中规定了各种运算符的优先级和结合性,首先来看一下有关算术运算符的优先级。

1.算术运算符的优先级

表达式求值时,通常会按照运算符的优先级别从高到低依次执行。算术运算符中,“" “/” “%“的优先级别高于”+”“-”。如果同时出现“”和“+”,应先运算乘法(这和数学中是一样的)。例如:R=x+y*z;上述表达式中,先进行y*z的运算,最后再加上x。使用括号将表达式改为(a+b)*c,可将“+”的运算级别提高,使其先进行运算。注意,括号在所有运算符中优先级别最高。

2.算术运算符的结合性

当算术运算符的优先级相同时,结合方向为“自左向右”。例如:

a-b+c

这里,b先与减号相结合,执行a-b的操作,然后执行加c的操作。这样的操作过程称为自左向右的结合性。

4.3.4 自增/自减运算符

C语言中还有两个特殊的运算符,即自增运算符“++”和自减运算符“—“。自增、自减运算符对变量的操作效果分别是使变量增加1和减少1。自增、自减运算符可以放在变量的前面或者后面,放在变量前面称为前缀,放在后面称为后缀。使用的一般方法如下:

--Counter;									/*自减前缀符号*/
Grade-;										/*自减后缀符号*/
++Age;											/*自增前缀符号*/
Height++;										/*自增后缀符号*/

上述代码比较简单,只有自增、自减,没有其他的表达式运算,因此,运算符是前缀还是后缀不重要,得到的结果是一样的,自减就是变量减1,自增就是变量加1。
注意:当自增、自减运算符出现在表达式内部,作为运算的一部分时,前缀和后缀对运算结果的影响是不一样的。如果运算符放在变量前,那么变量将先完成自增或自减运算,再以增减后的结果参与表达式运算;如果运算符放在变量后,那么变量将先参加表达式运算,之后再进行自增或者自减。
【例4.5】千变万化的自增、自减运算 在本 实例中定义一些变量,为变量赋相同的值,然后观察表达式中自增、自减运算符作为前缀和后缀时的不同结果。
在这里插入图片描述(1)在程序代码中,定义iNumber1和iNumber2两个变量用来进行自增、自减运算。
(2)进行自增运算,分为前缀自增和后缀自增。通过程序最终的显示结果可以看到,自增变量iNumber1和iNumber2的结果同为4,但是得到表达式结果的两个变量iResultPreA和iResultLastA却不一样。iResultPreA的值为4,iResultLastA的值为3,因为前缀自增使得iResultPreA变量先进行自增操作,然后进行赋值操作;后缀自增操作是先进行赋值操作,然后进行自增操作。因此两个变量得到表达式的结果值是不一样的。
(3)在自减运算中,前缀自减和后缀自减与自增运算方式是相同的,前缀自减是先进行减1操作,然后赋值操作;而后缀自减是先进行赋值操作,再进行自减操作。
运行程序,显示效果如上图所示。
注意:自增、自减运算符是单目运算符,因此表达式和常量不可以进行自增、自减运算。例如,5++,(a+5)++都是不合法的。
编程训练:
训练5:统计得票数 利用自增运算符模拟统计综艺节目《演员的诞生》中丫头的得票数。每个导师投一票,得票数就会增加。输出的结果如下:

观众投票之后丫头得156票
导师一投给丫头之后得157票
导师二投给丫头之后得158票
导师三投给丫头之后得159

训练6:统计剩余车位数量 一个新建小区内有70个停车位。现有一批新进住户购买车位,使用自减运算符在控制台中计算剩余的车位数。输出结果如下:

剩余停车位数:69
剩余停车位数:68
剩余停车位数:67

4.4 关系运算符与关系表达式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/416148.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

合适的索引顺序

一.前言 正确的顺序依赖于使用索引的查询,并且同时需要考虑如何更好地满足排序和分组的需要。因为哈希或者其他类型的索引并不会像 B-Tree索引一样顺序存储数据,所以这里只针对B-Tree展开讨论。 二.合适的索引顺序 1. 概念 对于如何选择索引顺序有一个经验法则: 将选择性最…

Java医院信息管理系统

技术框架: springboot shiro layui jquery thymeleaf nginx 有需要的可以联系我。 运行环境: jdk8 mysql IntelliJ IDEA maven项目功能: 本项目是用springbootlayuishiro写的医院管理系统,系统的业务比较复杂&#x…

机器学习周刊第五期:一个离谱的数据可视化Python库、可交互式动画学概率统计、机器学习最全文档、快速部署机器学习应用的开源项目、Redis 之父的最新文章

date: 2024/01/08 这个网站用可视化的方式讲解概率和统计基础知识,很多内容还是可交互的,非常生动形象。 大家好,欢迎收看第五期机器学习周刊 本期介绍7个内容,涉及Python、概率统计、机器学习、大模型等,目录如下: 一个离谱的Python库看见概率,看见统计2024机器学习最…

BGP最通俗易懂的讲解——路由反射器

路由反射器 点赞关注,持续更新 路由反射器RR (Route Reflector) : 允许把从IBGP 对等体学到的路由反射到其他BGP对等体的BGP设备。客户机 (Client) : 与RR形成反射邻居关系的IBGP设备。在AS内部客户机只需要与RR建立邻居关系。非客户机 (Non-Client) …

【linux】Debian10.0配置vsftpd

一、基本步骤 在 Debian 10 (Buster) 上要配置 vsftpd (Very Secure FTP Daemon),请按照以下步骤操作: 1. 安装 vsftpd: sudo apt update sudo apt install vsftpd 2. 在启动配置之前,建议备份原始的配置文件: sudo cp /etc/vsftpd.con…

论文阅读 Vision Transformer - VIT

文章目录 1 摘要1.1 核心 2 模型架构2.1 概览2.2 对应CV的特定修改和相关理解 3 代码4 总结 1 摘要 1.1 核心 通过将图像切成patch线形层编码成token特征编码的方法,用transformer的encoder来做图像分类 2 模型架构 2.1 概览 2.2 对应CV的特定修改和相关理解 解…

【算法Hot100系列】跳跃游戏

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

为什么说在java中万物皆方法?

为什么说在java中万物皆方法? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&am…

SwitchyOmega插件管理海外動態IP代理設置教程

SwitchyOmega插件很好解決了管理多個代理並在它們之間切換的問題,通過本文來全面瞭解SwitchyOmega,比如SwitchyOmega插件的用途、它的主要功能和應用、怎麼下載和使用,如何管理海外動態IP代理。 SwitchyOmega插件有什麼用途? Swit…

关于Windows 10的操作中心 ,看这篇文章就可以了

这篇文章介绍了Windows 10操作中心,也称为通知中心,以及如何使用它。操作中心会在需要你注意的事情时发送警报。 如何在操作中心中访问和解决通知 Windows操作中心显示为Windows任务栏右下角的发言气泡。图标下的数字表示你有未解析的通知。 通知会在…

取代房子,中国又一种资本在崛起(深度)

我一直有一个观点:经济形势好的时候,只要不是夕阳行业,做什么都能过得不错。经济形势差的时候,对于个人来说,拼的就是学习能力。 10年前,在市场上很吃香的是MBA,那时候企业需要高速发展&#x…

maven多个module打包

common是父组件,servicebase依赖于commonutils,如下图 1.打servicebase包时出现问题:找不到commonutils的jar包,但是commonutils包可以正常打,并且可以install到本地maven仓库。 解决方式: servicebase 的…