1、第3章 程序的基本单位语句,语句和表达式是程序语言的基本组成部分。在程序中,数据处理是通过表达式和语句完成的。掌握语句、运算符是学习程序的基础。本章将讲解语句的构成,运算符和语句块。,3.1 语句的构成,在C+中,语句是数据处理过程中的最小单位。C+语言中的基本语句有表达式语句、空语句、输入/输出语句、复合语句、控制语句、函数调用语句。本节主要讲表达式语句,输出/输入语句,其它语句在后面讲。,3.1.1 表达式语句,表达式语句是由表达式和“;”构成。而表达式是由变量和运算符构成的。具体表达式语句的构成如图3-1所示:,图3-1 语句的构成,此外,语句也可以直接是一个分号,这种语句称为空语句。空
2、语句仅由一个分号组成,不进行任何操作。一般用于语法上要求有一条语句但实际没有任何操作的场合,如for语句中。,3.1.2 输入/输出语句,C+没有提供输入/输出语句,其输入/输出功能由函数(scanf()、printf())或流控制来实现。输入/输出流(I/0流)是输入或输出的一系列字节。C+定义了包含重载运算符“”的iostream类。在这里只介绍如何利用C+的标准输入/输出流实现数据的输入/输出功能。C+的标准输入/输出流如图3-2所示。,图3-2 C+的标准输入/输出流,1输出语句,当程序需要在屏幕上显示输出时,可以使用操作符“”向输出流cout中插入字符和数字,并把它在屏幕上显示输出。
3、,【示例3-1】,该示例给出了最简单的输出语句的实现,其功能是输出字符串“Hello”,使其显示到屏幕上,实现代码及结果如图3-3所示。,图3-3 输出语句,2输入语句,当程序需要执行键盘输入时,可以使用操作符“”从输入流cin中抽取键盘输入的字符和数字,并把它赋给指定的变量。,【示例3-2】,该示例给出了最简单的输入语句的实现。该程序段的功能是接收用户从键盘输入的一个整数,并将其存储到变量a中输出,实现代码及结果如图3-4所示。,图3-4 输入语句,3.2 运算符,运算符是学习C+程序的基础。本节简要介绍运算符的概念及分类。,3.2.1 运算符概述,C+语言中的运算符是可以让C+语言编译器能
4、够识别的具有运算意义的符号。编译器把这些符号及其组成的表达式翻译成相应的机器代码后,就可以由计算机运行得出正确的结果。例如,在日常生活中,冰箱、电视机等分别代表不同功能的电器设备,那么运算符就是代表C+语言中的各个运算功能的名字,这些名字是由制定C+语言规范的人员确定的,如图3-5所示。,图3-5 运算符的概念,C+中包含了C语言中几乎所有的运算符,并且在其基础上又增加了以下几种新的运算符,如图3-6所示。,图3-6 C+新的运算符,3.2.2 运算符的分类,根据运算符需要的操作数的个数,可将其分为三种,如图3-7所示。,图3-7 运算符根据操作数个数的分类,说明:很多时候,单目运算符也被称为
5、一元运算符。同理,双目运算符和三目运算符也被称为二元运算符和三元运算符。,在C+中,三目运算符只有一个,那就是条件运算符“? : ” 。 根据运算符实现的功能进行划分,C+提供的基本运算符有以下几种:赋值运算符、算术运算符、位运算符、关系运算符、逻辑运算符、条件运算符、逗号运算符、sizeof运算符及其他运算符。下面将讲解这些运算符的功能和应用。,3.3 赋值运算符,赋值运算符是C+基本运算符中最常用的。本节将介绍赋值运算符的使用和在赋值时的数据类型转换。,3.3.1 赋值运算符“=”,赋值运算符是C+程序设计中最基本的运算符之一。利用赋值运算符可以给一个变量赋值。C+的基本赋值运算符以“=”
6、来表示,它是一个二元运算符。其说明语句的一般形式如图3-8所示。,图3-8 赋值运算符,例如,表达式a = b的含义是将右操作数b的值赋给左操作数a,即用b的值覆盖a的值。 在进行赋值的时候,需要注意以下问题: (1)在程序中,以关键字const声明的符号常量进行赋值操作是错误的,因为常量是不允许改变其原有值的。 (2)赋值运算符的结合性是自右向左的。例如:思考以下赋值语句的赋值顺序。 int x,y,z=4; x=y=z; 首先,变量z的值赋给y,接下来把y的新值赋给x。由此,赋值运算符的结合性是自右向左的。,3.3.2 数据类型转换隐式转换,类型转换是用来把一个类型的值转换成另一个类型。当
7、用户需要把一个值转换为另一个类型时,就需要使用一些方式进行类型转换。C+中,支持隐式转换和显式转换两种。本小节首先讲解隐式转换。 隐式转换就是系统默认的,不需要加以声明就可以进行的转换。在隐式转换过程中,编译器无须对转换进行详细检查就能够安全地执行转换。比如从int类型转换到long类型就是一种隐式转换。隐式转换一般不会失败,转换过程中也不会导致信息丢失。,【示例3-1】,该示例实现数据类型的隐式转换,将字符型变量转换为整型变量,实现代码及其结果如图3-9所示。,图3-9 隐式转换实例,3.3.3 显式转换,通常,隐式转换意味着编译器认为转换是合理的或者是安全的。因此,隐式转换可能出现意想不到
8、的错误。为了避免隐式转换,C+还支持显式转换,显式转换是用户手动指出需要转换的类型。显式转换意味着编译器能够找到一个转换方式,但是它不保证这个转换是否安全,所以需要程序员额外指出。显示转化有多种方式,下面依次讲解几种常用的方式。,1.旧式转化,旧式转化是类似于C语言的一种转化方式。直接使用数据类型标识符来修饰要转化的变量。语法形式如下: (type) expression 其中,type为转化后的数据类型名称;expression为要转化的变量或者表达式。,【示例3-2】,该示例实现了数据类型之间的显式转换,将字符型变量通过()符显式转换为整型变量,实现代码及其结果如图3-10所示。,图3-1
9、0 显式转换实例,2.静态的转换方式,静态转换方式发生在编译时。它可以显式完成编译器隐式执行的任何类型转换,屏蔽潜在精度损失产生的编译器警告。但不能用于指针类型转换。语法形式如下: static_cast(expression); 其中,static_cast是修饰符,type是转换后的数据类型名称,expression为要转化的变量或者表达式。,【示例3-3】,图3-11中的代码显式的将单精度数a显式的转换为整型变量,并赋给整型变量b。,图3-11 静态转换方式,3. 动态的转换方式,动态的转换方式提供了运行时确定对象类型的方法,支持运行时识别指针或引用所指向的对象。格式如下: dynami
10、c_cast(expression); 此方式用处很少,这里就不详说了。,4.重新解释的转换方式,常用于函数指针类型之间进行的转换,能够在非相关的类型之间转换。其操作结果只是简单的从一个指针到别的指针值的二进制复制,仅仅是重新解释了对象的内存表示,对类型之间指向的内容不做任何的类型检查和转换。格式如下: reinterpret_cast(expression);,【示例3-4】,将一个字符类型的指针重新解释为整型类型的指针。如图3-12所示。,图3-12 重新解释转化方式,5 常量的类型转换,用来转换掉对象的const或volatileness属性。任何修改const或volatileness
11、之外的属性的企图都被拒绝。格式如下: const_cast(expression); 这种用法读者了解下就可以了。,3.4 其他常用运算符,C+中除了赋值运算符外,还有一些常用的运算符,例如,算术运算符、自增自减运算符、关系运算符、逻辑运算符、位运算符、复合赋值运算符、条件运算符、逗号运算符、sizeof运算符等。本节将详细介绍几种运算符的使用及其优先级。,3.4.1 算术运算符,算术运算符包括加、减、乘、除运算符(+、-、*、/)和求模运算符(%)。算术运算符是双目运算符,其操作数一般是整数和浮点数(或者是结果为整数或浮点数的表达式)。C+语言中支持的算术运算符符号、名称、功能及其相关示例,
12、如表3-1所示。已知a=10,b=4。,表3-1 算术运算符,图3-13 算术运算符的优先级,【示例3-3】,已知a=4,b=3,c=5,d=7,e=8,求表达式a+b-c/d+ e%d的值,实现代码及结果如图3-14所示。,图3-14 算术运算符实例,注意:C+中的除法运算与算术中的除法运算一样,除数都不可为0,否则会导致程序崩溃。,3.4.2 自增自减运算符,自增、自减运算符“+”和“-”也可包含在算术运算符的范畴中。他们的表示形式和实现功能如图3-15所示。,图3-15 自增自减运算符的表现形式和功能,自增自减运算符其实是简化变量加(减)1的操作,如图3-16所示。,图3-16 变量加(
13、减)1的简化,自增、自减运算符“+”和“-”,其前缀增量和后缀增量所产生的结果是不同的。前增量表示先使用操作数的值,在对操作数作自增自减运算,后增量则表示先对操作数进行自增自减操作,再使用操作数。 注意:自增自减运算符的操作数必须是可修改的变量,而不能是常量。,【示例3-4】,分别使用前缀和后缀两种形式,仔细观察变量值的变化,其实现代码和输出结果如图3-17所示。,图3-17 自增自减运算符实例,3.4.3 位运算符,C+提供了对数据进行位运算的功能,包含6种位运算符,如表3-2所示。,表3-2 位运算符,图3-18 &、|、的运算规则,左移位的运算规则如表3-3所示。,表3-3 的运算规则,
14、【示例3-7】,下列程序对两个变量进行按位与、按位或、按位异或等几种位运算,将结果赋给变量并输出。其实现代码及结果如图3-19所示。,图3-19 位运算符实例,3.4.4 复合赋值运算符,在程序中经常出现类似于s=s+n这样的赋值语句,C+允许采用更为简洁的形式写为“s+=n”,于是形成了复合赋值运算符。根据C+中算术运算符和比较运算符的种类,复合赋值运算符一共有10种,如表3-4所示。,表3-4 复合赋值运算符,【示例3-8】,下列程序代码实现求自然数1100的算术和。在该示例中,使用到了赋值运算符和复合赋值运算符,实现代码及结果如图3-20所示。,图3-20 复合赋值运算符实例,3.4.5
15、 逗号运算符,C+支持逗号运算符的使用。逗号运算符可以使多个表达式写在一行上,从而大大地简化了程序,其一般形式及结合性如图3-21所示。,图3-21 表达式的形式及结合性,表达式的执行顺序如图3-22所示:,图3-22 表达式的执行顺序,【示例3-10】,下面程序采用了逗号运算符的语句,该语句由三个表达式组成,并将其结果赋给整形变量s,输出s的值。实现代码及结果如图3-23所示。,图3-23 逗号运算符实例,3.4.6 sizeof运算符,由于不同的计算机支持的数据类型长度是不一样的,因此需要一个运算符来测量该机器中的数据类型长度。C+中提供了sizeof运算符,其作用和使用格式如图3-24所
16、示。,图3-24 sizeof运算符的作用和使用格式,该运算符的运算结果是类型名所表示类型的长度或表达式的值所占用的字节数,即这个值所属类型的长度。,【示例3-11】,下面程序输出在当前测试计算机中几种常用数据类型的长度,其实现代码及结果如图3-25所示。,图3-25 sizeof运算符实例,3.4.7 逻辑运算符,逻辑运算符是作用在逻辑型上的运算,有与( 非运算的结果与expr1相反。,说明: 1. 三种逻辑运算的优先级为“非与或”。 2. 短路表达式:在由&和|逻辑运算符组成的逻辑表达式中,C+规定:只对能够确定表达式值所需要的最少数目的表达式进行计算。即:当计算一个子表达式的值后使可确定
17、整个表达式的值时,后面的表达式便不必再计算了,这种表达式叫做短路表达式。,3.4.8 运算符的优先级和结合性,前几小节简要介绍了运算符的优先级,本节将着重介绍C+的各种运算符之间及同一种类运算符的优先级顺序。 运算符优先级决定了在表达式中各个运算符执行的先后顺序。同一优先级的优先级别相同,运算次序由结合方向决定,使用括号可以改变运算符的顺序。例如,表达式1*2/3,*和/的优先级别相同,其结合方向自左向右,则该表达式等价于(1*2)/3。 C+中,运算符的优先级一般分为15级,其优先级中包含的运算符、功能说明和同一优先级的运算符结合性,具体如表3-5所示。,表3-5 运算符优先级,图3-26
18、运算符优先级,针对上述表达式编写代码进行验证。,3.5 语句块,语句块是一个程序片段,它包含了多条语句。该片段可以是为了共同完成一个复杂功能而放在一起的,也可以是为了程序的可读性而组织在一起的。本节将介绍语句块的构成及作用域的范围使用。,3.5.1 语句块的构成,在C+程序中,多个连续的语句组成语句块(复合语句)。语句块一般以一对大括号“”为标志。如图3-28所示为一个main()函数内的语句块。,图3-28 语句块的构成,语句块可以嵌套,如图3-29所示。,图3-29 语句块的嵌套,说明:当语句块只含有一条语句时,常常可以省去大括号,如果块内包含多条语句,就必须保留大括号,否则意思就完全不一
19、样了。此外,一个好的习惯是先写好一对大括号,再填充语句。,3.5.2 作用域变量的作用范围,在C+语言源文件中,变量的作用域是指变量的有效范围。根据变量是在一对“”之中还是在程序的所有的“”之外来确定变量的作用域。根据作用域的不同,变量分为全局变量和局部变量,具体说明事项如图3-30所示。,图3-30 作用域说明,【示例3-13】,该示例通过声明变量语句的位置,来确定全局变量和局部的作用域。其实现代码及结果如图3-31所示。,图3-31 作用域实例,3.7 小结,本章主要介绍了C+程序的基本单位语句,语句的构成及语句块。重点讲述了C+中基本运算符的使用及其优先级。并对数据转换和变量的作用域做了简单的介绍。,