第2章 数据类型和表达式_第1页
第2章 数据类型和表达式_第2页
第2章 数据类型和表达式_第3页
第2章 数据类型和表达式_第4页
第2章 数据类型和表达式_第5页
已阅读5页,还剩107页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章数据类型和表达式2.1标识符、常量和变量2.2基本数据类型2.3运算符和表达式习题22.1标识符、常量和变量 2.1.1标识符 1.标识符的定义 编写程序,需要使用相应的计算机语言,而语言主要是由它所限定的符号表示一些字、词、命令、变量及数据等。这些符号组成了语言,标识符指的就是用来标识变量名、符号常量名、函数名、文件名以及一些具有专门含义的有效字符序列。通俗地说,标识符就是一个名字。 2.标识符的规定 在C语言中使用标识符有如下规定。 (1)合法的标识符只能由字母、数字和下划线组成,并且第一个字符必须为字母或下划线。 (2)大写字母和小写字母被视为两个不同的字符。如sum、SUM被认为是两个不同的标识符。 (3)标识符的长度(即一个标识符允许的字符个数)一般规定取前8个字符为有效字符,多余的将不被识别。如student_name、student_num被认为是相同的标识符student_。 例如:sum、area、aver.PI、_above、L_1_2_3、S12是合法的标识符;而A.B.C、A.123、13、3area、a+b是不合法的标识符。 3.标识符的分类 在C语言中,标识符分为3类,即关键字标识符、预定义标识符和用户自定义标识符。 1)关键字标识符 关键字又称为命令符,在程序中具有特定的含义,不能另作它用,其他字符又无法直接替代。例如,程序中用来说明变量类型的标识符int、char及选择结构中的if、else等,都是关键字标识符。

C语言中的关键字标识符包括: auto break case char const continue default do doubleelse enum extern float for goto if int longregister return short signed sizeof static struct switch typedefunion unsignedvoid volatile while 2)预定义标识符 在C语言中,预定义标识符一般是指C语言提供的库函数名和预编译处理命令(如printf、scanf、define)等。C语言允许这类标识符(函数名)另作它用,但这将使这些标识符失去系统规定的原意。为了编程时方便、可靠、避免误解,一般把这些标识符固定使用。 3)用户自定义标识符 用户在进行编程时,需要自己对变量、函数、数组、文件和常量等进行命名,命名规则前面已有说明,这类由用户根据需要自己定义的标识符称为用户自定义标识符。在使用用户自定义标识符时应注意以下3点: (1)最好根据其含义选用英文缩写及汉语拼音作标识符,这样便于阅读程序。 (2)决不能与关键字相同,否则编译时给出错误信息。 (3)如果与预定义标识符相同,系统并不报错,则程序仍能运行,只是预定义标识符失去原来的含义,代之以用户确认的含义,这样会造成编程混乱现象,应避免发生。 2)符号常量 使用常量可以提高程序运行速度,提高程序执行的效率,而使用标识符常量则可提高程序的易读性、可修改性,便于调试程序,减少出错机会。 如果在程序中多次出现一些很大的数字或很长的字符串,为了改进代码的可读性和可维护性,则可以给某一特定的值赋予一个名字,以后用到这个值时就用名字代表,这样便于程序修改和阅读,这个名字就是符号常量。符号常量有点像变量,但不能像对变量那样修改符号常量,也不能对符号常量赋以新值。 下面看一个符号常量的例子。 【例2-1】定义一个符号常量PI,表示圆周率,然后使用符号常量PI计算圆的面积。 #include"stdio.h" #definePI3.1415926 /*定义符号常量PI,其值为3.1415926*/ main() { floatradius; /*radius圆的半径*/ floatarea; /*area圆的面积*/

printf("Pleaseinputradius:"); scanf("%f",&radius);/*输入圆的半径*/ area=PI*radius*radius;/*计算圆的面积*/ printf("area=%f",area);} 从该例中可以看出,程序用#define命令行定义PI代表常量3.1415926,程序在编译时将用3.1415926替代PI,有关#define命令的用法将在后面的章节中进行详细介绍。

使用符号常量时,应注意以下几项: (1)符号常量不同于变量,它的值在其作用域(本例中为主函数)内不能改变,也不能再被赋值,例如在程序中出现下面的语句就是错误的。 PI=3.14; (2)习惯上,符号常量名用大写,变量名用小写。 (3)使用符号常量的好处有两个。一是含义清楚,如在本例中,可以看出PI代表圆周率。二是在需要修改常量值时比较方便,例如可以用#definePI3.14替代原有命令行以达到修改圆周率的目的。 2.变量 1)变量的定义 程序运行过程中,其值可以改变的量叫变量。程序中使用的变量,属于用户自定义标识符,任何一个变量名必须先定义(即确定变量名和变量的类型)后使用。 一个变量实质上是指计算机内存中某个存储一定类型数据的单元,变量名实质上是这个数据存储单元的符号表示。对变量进行的操作就是对该存储单元进行操作,对变量赋值就是将数据存入该变量所代表的内存单元中。程序中的变量与数学上的变量概念不同:变量中的“变”体现的是这个存储单元可以存放不同的数据,但每一时刻只具有惟一的值,即新放入的数据将覆盖原有的数据。 变量也有类型之分,常用的有整型变量、实型变量和字符型变量等。变量因类型不同在内存中所占的存储空间也不同,系统在编译时能根据所定义的变量类型为其分配相应数量的存储单元。 2)定义变量的一般形式 定义变量的一般形式为 数据类型变量名1,变量名2,变量名3,…;

【例2-2】用price代表商品单价,num代表商品数量,然后计算商品的总价total。注意程序中只是定义了变量total,而没有定义变量price和num。 #include"stdio.h" main() { inttotal; num=5; /*此处变量num没有先定义而使用,编译时会出错*/ price=3;/*此处变量price没有先定义而使用, 编译时会出错*/ total=price*num; printf("total=%d",total); } 从例2-2可以看出,对变量使用前必须先定义,这样可以保证变量在使用中的正确性。 说明: 变量的数据类型决定了变量的取值范围和占用内存空间的字节数,变量名表示具有同一数据类型变量的集合。C语言这样要求的目的有以下3点。 (1)凡是未被事先定义的,不能作为变量名,这样做能保证程序中变量名的正确使用。例如,在定义部分写成intst; 而在语句中错写成stu,在编译时会检查出stu未被定义,不能作为变量名,这样便于用户发现错误,避免变量名在使用时出错。 (2)每个变量被定义为一个确定数据类型,在编译时能为其分配相应的存储空间。例如定义x为int型,则编译程序将为变量x分配两个字节的存储空间,并按照整型方式存储。 (3)每个变量属于一定的数据类型,便于编译时据此检查该变量所进行运算的合法性。例如,整型变量x和y可以进行求模运算:x%y,%是求模运算符,得到x除以y的整余数。如果将x和y定义为浮点型变量,则不允许进行“求模”运算,在编译阶段就会指出有关的出错信息。2.2基本数据类型 在设计一个程序时,首先要确定采用什么类型的数据,对不同的问题,采用的数据类型应不同。例如,在统计全校有多少学生时就应该用整型数据,而不应使用带小数的数据或其他数据。数据是程序的必要组成部分,是程序处理的对象。由于数据类型体现了数据结构的特点,高级语言所提供的数据类型越丰富,由其数据类型所表现的数据结构就越丰富、复杂,因而,这种高级语言的功能和所处理问题的能力就越强。

C语言规定,程序中所用到的任何一个变量和数据都必须指定其数据类型。 C语言中的数据类型如图2.1所示。图中括号内所注是程序中使用的类型名。图2.1C语言中的数据类型 2.2.1整型数据 1.整型常量 整型常量,即整型常数。C语言整型常量可用以下3种形式表示。 1)十进制整型常数 十进制整型常数,如+156,-253,121,0等。 2)八进制整数 八进制整数是以0开头(注:不是英文字母O而是数字零)的数,在数学领域内0123和123表示两个值相同的整数,而在C语言中,0123表示八进制的123,它的十进制值应是 1×82+2×81+3×80=64+16+3=83 使用八进制数时应注意以下几项: (1)在八进制中不允许出现8和9; (2)在程序中出现的八进制数一定要以0开头,但当程序的输出结果为八进制数时,前面的0消失。 3)十六进制整数 十六进制整数是以0x开头的数,如0x123。0x123的十进制数为 0x123=1×162+2×161+3×160=256+32+3=291 使用十六进制数时应注意以下几项: (1)大于9时可依次用a,b,c,d,e,f表示;

(2)在程序中出现的十六进制数一定要以0x开头,但当程序输出结果为十六进制时,前面的0x消失。 十进制与二进制、八进制、十六进制的转换见表2-1。表2-1数制转换表表2-1数制转换表 2.整型变量 1)整型变量的分类 整型变量可分为以下4种整型类型: (1)基本型,以int表示; (2)短整型,以short表示; (3)长整型,以long表示; (4)无符号整型,以unsigned表示。unsigned可以加在int、short和long的前面,分别表示无符号整型、无符号短整型和无符号长整型。 在IBM-PC机及兼容机中,以上整型类型的数据所占的字节数和所表示的范围见表2-2。表2-2各种整型变量数据的存储长度及表示范围 2)整型变量的定义和使用 变量必须先定义,后使用。对于变量的定义,一般放在一个函数开头的声明部分。 整型变量定义的格式如下: 类型标识符变量名1,变量名2,变量名3,…; 类型标识符可以是int、short、long、unsigned,或是它们的组合,例如: intx,y; . /*指定变量x,y为整型变量*/ longc,d; /*指定变量c,d为长整型变量*/

unsignedage,weight; /*指定变量age,weight为无符号整型变量*/ inta=3,b=4; /*定义a,b为整型变量同时将3和4分别赋予a和b*/ 3.整型数据在内存中的存放形式 任何数据在计算机内部都以二进制形式存放。一般情况下,8位二进制数组合在一起称为一个字节(byte),大量的字节按序组合在一起构成存储器。 在C语言中,一个整型数通常占用2个字节,低位在前一个字节,高位在后一个字节。 下面举例说明。 1)整数9在存储单元中的存储形式 (1)整数9作为有符号正数时(即int型),最高位用0表示正数,而不表示数值。 0 0000000 00001001 (2)整数9作为无符号数时(即unsigned型),所有二进制位都有确定的值。 00000000 00001001 注意:无符号数最大值为65535,其存储形式为 11111111 11111111 2)负整数在存储单元中的存储形式 负整数在存储单元中是以补码形式存放的。以-1为例,-1的补码应为其原码除符号位不变外,其余各位求反后加1,即对1000000000000001求反再加1。故-1在存储单元中的存放形式为 1 1111111 11111111 注意: (1)负整数在存储单元中的存放形式与它的真值有极大差别。 (2)负整数不能用无符号数表示。 (3)存储单元中,若最高位为0,即为正数,该数可理解为无符号数,也可理解为有符号数,其值是相等的。 (4)内存储单元中,最高位为1时,若理解为有符号数,则必为负数,并且该负数是以补码形式存放的。若理解为无符号数,则最高位代表一定的数值,如16位二进制数最高位为1时,代表216-1,即表示32768。 【例2-3】整型变量的定义与输出。 #include"stdio.h" main() { inta; /*指定a为整型常数*/ unsignedb; /*指定b为无符号整型常数*/ a=-1; /*将a赋值为-1*/ b=a; printf("a=%d\n",a); /*输出a的值*/ printf("b=%u\n",b); /*输出无符号数b的值*/ } 运行结果: a=-1 b=65535 4.整型变量的赋值 可以将一个整型常量或整型变量赋值给整型变量,例如: intx=560; 但是要注意任何一个整型变量占用一定的存储空间,因此其存储的数据取值范围也就是一定的,详细情况见表2-2。如果将一个大于32767或小于-32768的数据赋值给一个int型变量就会产生溢出。 产生的结果和我们的想象不同,原因是32768被接收为1000000000000000,它是-32768的补码;32769被接收为1000000000000001,它是-32767的补码,如图2.2所示。图2.2整型数据在内存中的溢出-32768-32767 整型数据的溢出在编译时不会出错,但在程序运行中会出现错误,因此应该避免。 平时应注意不同类型数据的取值范围,如果整型变量不能处理问题,则可以考虑用长整型变量。 可以将一个整型常量后面加一个字母l或L,则认为此常量为长整型常量,也可以将此长整型常量赋值给一个长整型变量。例如: longx=560L; 长整型常量往往用于函数调用中。如果函数的形参为longint型,则要求实参也要是长整型。 2.2.2实型数据 1.实型常量 在C语言中实型表示实数的集合,实型常量又称实数。实型常量有两种表现形式。 1)十进制数形式 十进制数形式和数学中的实数形式类同,由数字和小数点组成,小数点是实数的标志。 例如:0.168,168,1680,3.168,168.3,0.0都是实数。

2)指数形式 实数的指数形式类似于数学中的指数形式。C语言中,它由数字、小数点和字母E或e组成,格式如下: 数字[小数]E[±]整数 ([]内为可省项) 实型常数的表示方法示例见表2-3。表2-3实型数据在C语言中的表示形式 在使用指数形式时应注意以下几项: (1)字母E(或e)前可以是小数或整数,如果是纯小数,则可以将小数点之前的0省略,但是E(e)之前必须有数字。例如E2,e是不合法的指数形式。 (2)字母E(或e)后必须为整数,不能出现小数的情况。例如1e2.5,1.2E8.9是不合法的指数形式。 (3)一个实数有多种指数表示形式,如果字母E(或e)前的小数或整数的范围是1~10,则此时称为“规范化的指数形式”。 2.实型变量 1)实型变量的分类 实型变量分为以下3种类型: (1)单精度型,以float表示。 (2)双精度型,以double表示。 (3)长双精度型,以longdouble表示。 2)实型数据在内存中的存放形式 与整型数据的存储形式不同,实型数据是以指数形式存放的。一般情况下,系统将一个实型数据分为小数部分和指数部分并分别存放。指数部分采用规范化的指数形式,具体存放结构如图2.3所示。图2.3实型数据在内存中的存放形式 数符占用一位,用来表示数据的符号。小数部分占用的位越多,数的有效数字就越多。指数部分占用的位越多,数值范围也就越大。实型数据所占用的字节数、有效数字位数和数值的范围见表2-4。表2-4实型数据 3)实型变量的定义 实型变量定义的格式如下: 类型标识符变量名1,变量名2,变量名3,…; 类型标识符可以是float、double、longdouble等,例如: floatx,y; /*指定变量x,y为单精度实型变量*/ doublelength,high; /*指定变量length,high为双精度实型变量*/ longdoublec,d;/*指定变量c,d为长双精度实型变量*/ 4)实型变量的赋值 可以将实型常量或实型变量赋值给实型变量。注意单精度实型数据的有效位数是6~7位,在进行赋值和计算时会产生误差,在双精度实型数据和长双精度实型数据中也同样存在此问题。例2-5说明实型数据的确存在误差。 【例2-5】将一个有效数字位超过7位的数赋值给实型变量,然后输出实型变量的值,实型变量产生误差。

#include"stdio.h" main() { floatx=123456789; doubley=123456789; printf("\nx=%f,y=%f",x,y); } 运行结果: x=123456792.000000,y=123456789.000000 从运行结果可以看出,单精度实型变量x只接收了前面7位,从第8位开始数据不准确。所以在使用实型数据时一定注意可能产生的误差。应当避免将一个很大的数和一个很小的数直接进行运算,否则将“丢失”这个很小的数。 许多C编译系统将实型常量作为双精度来处理,这样保证计算结果更精确,但是运算速度会降低。可以在数的后面加字母F或f(例如1.23f),这样系统就会按单精度来进行运算,可以提高运行速度,但是会降低运算的精度。 2.2.3字符型数据 1.字符型常量 字符型常量(简称字符常量)是一个字符,在表示时由两个单引号括起来。 在C语言中每一个字符型常量均有其特定的值,也就是一个字符一个编码,通常使用ASCII码(美国标准信息交换码)。例如'A','a','+','?','','1','2'等都是合法的字符常量。 字符型常量在内存中占用一个字节,其取值范围为0~255,存放的是字符的ASCII码值,如字符‘A’的值为65,‘B’的值为66,‘a’的值是97,‘0’的值是48,空格字符的值为32。所有字符常量还可作为整型量进行运算,以及参与相应的各种操作。 例如,'A'+1的值为66,或'A'+1的值为'B'。 2.转义字符 C语言中有一种特殊的字符常量——转义字符,这类字符常量是以反斜杠字符“\”开头的字符序列,它表示某个特定的ASCII码字符。在程序中,转义字符要放在一对单引号内。 转义字符及其作用见表2-5。表2-5转义字符及其作用【例2-6】使用转义字符控制输出实例。#include"stdio.h"main(){printf("\n\t\101"); /*光标到下一行行首,再到下一个制表位,输出A(ASCII编码*//*为八进制的101)*/printf("\n\t\b\b\b\b"); /*光标到下一行的行首,再到下一个制表位,然后退四格*/ printf("\\*hello*\\"); /*输出\*hello*\*/ printf("\n\t\x41"); /*光标到下一行行首,再到下一个制表位,输出A(ASCII编码*/ /*为十六进制的41)*/ } 运行结果: A \*hello*\ A 从上面的例子中可以看出,要想使输出的结果美观大方,可以使用转义字符。例如,若希望输出字符“\”,则使用“\\”;若希望输出双引号“"”,则使用“\"”等。 3.字符变量 字符型变量用来存放字符常量,要注意一个字符变量只能放一个字符,不要以为在一个字符变量中可以放一个字符串(包括若干个字符)。 1)字符变量的定义 字符变量的定义形式如下: char字符变量名1,字符变量名2,字符变量名3,…; 例如,下面定义了两个字符变量c1,c2: charc1,c2;

2)字符数据在内存中的存储形式 将一个字符常量放在一个字符变量中,实际上并不是将字符的点阵信息或矢量信息放在内存中,而是将该字符的ASCII码信息放在相应的内存中。 例如字符“a”的ASCII码为97,字符“b”的ASCII码为98,如果将其分别放在字符变量c1和c2中,十进制存储形式如图2.4(a)所示,实际上是以二进制的形式存储的,如图2.4(b)所示。 3)字符变量的赋值 可以将一个字符常量或字符变量赋值给一个字符变量,也可以将0~255的整型数据赋值给一个字符变量,并且字符变量、字符常量、0~255的整型数据之间可以进行运算。图2.4字符数据在内存中的存储(a)十进制存储形式;(b)二进制存储形式 【例2-7】分别将字符常量和整型常量赋给字符型变量,然后输出字符或者输出字符的ASCII码。 #include"stdio.h" main() { charc1,c2; c1='A'; /*将65赋给c1*/ c2=66; /*将66赋给c2*/ printf("\nc1=%c,c2=%c",c1,c2); /*输出c1,c2存放的字符*/

printf("\nvalueofc1andc2:%d%d",c1,c2); /*输出c1,c2中存放的数据*/ printf("\nnextcharacterofc1:%c",c1+1); /*输出字符A下面的字符*/ } 从该例中可以看出,C语言对字符的这种处理方法为程序设计增大了自由度。如可以对文字进行加密,即可以对字符作各种转换。大写字母A和B的ASCII码为65和66,小写字母a和b的ASCII码为97和98,可以看出小写字母的ASCII码比其大写字母大32,即'A'+32就得到'a',计算非常方便。 【例2-8】将大写字母转换为小写字母,将小写字母转换为大写字母。 #include"stdio.h" main() { charc1,c2; c1='A'; c2='b'; c1=c1+32; /*将大写字母加32得到小写字母*/

c2=c2-32; /*将小写字母减32得到大写字母*/ printf("c1=%c,c2=%c",c1,c2); } 运行结果: c1=a,c2=B 4.字符串常量 1)字符串常量的定义 字符串常量是指用一对双引号括起来的字符序列。如"howareyou!","$123","CHINA","a"都是字符串常量。 注意:C语言中没有字符串变量,字符串存放在字符数组中,例如charc[5]={"CHINA"},详细情况参见后面章节。 2)字符串常量在内存中的存储形式 字符串常量在内存中存储时一个字符占用一个字节,并且在字符串的末尾有一个结束符,C语言规定结束符为字符'\0',字符'\0'是指ASCII码为0的字符。字符串必须有一个结束符。如果没有结束符,则程序在输出时不知到何处停止。例如,字符串"CHINA"在内存中的存储情况如图2.5所示。图2.5字符串在内存中的存储 2.2.4变量赋初值 变量赋初值是指在定义变量的同时对变量进行赋值。例如: inta=5; floatp=3.14; charc1='a'; 可以对被定义的变量的一部分赋初值。例如: inta,b,c=10; 如果对几个变量赋予同一个值,则可以写成 inta=b=c=d=10;

变量的初始化不是在编译阶段完成的,而是在程序运行时进行赋值的,所以初始化语句为 inta=10; 相当于 inta; a=10;2.3运算符和表达式 2.3.1算术运算符和算术表达式 1.基本的算术运算符 基本的算术运算符有5个:+、﹣、*、/、%,其特性见表2-6。表2-6基本运算符列表 这5种运算符均可以作为双目运算符,即在运算符的两边有数据。+和-运算符可以为单目运算符,即运算符的右边有数据,例如+3,-5等。两个整数相除的结果为一个整数,但是,如果除数或被除数中出现一个负数,则结果是不固定的。例如:-5/3有的机器的结果为-1,有的机器的结果为-2,如遇到此类问题应该编写程序测试结果。 注意,求余运算符%两侧的数据要求必须为整数,运算的结果为整数相除的余数。 2.算术表达式 由算术运算符将操作数连接起来的有意义的式子称为算术表达式。例如2+a*b,-3*a%b,a*(b+3)等,其中,“()”也是运算符,在所有运算符中级别最高。 3.算术运算符的优先级与结合性 运算符*、/、%的优先级为3级,高于+、-的4级。这5种运算符的结合性是“自左至右”的。 2.3.2自增、自减运算符及其表达式 自增(自减)运算符有两类,分别为前置和后置运算符。 1.格式与功能 1)前置运算符的格式和功能 前置自增、自减运算符的格式为 ++i--i 功能:变量i先增加(减少)1,即i=i±1,然后再使用i的值。

2)后置运算符的格式和功能 后置自增、自减运算符的格式为

i++i-- 功能:先使用i的值,然后变量i的值增加(减少)1,即i=i±1。 例如: inta=3,b; b=a++; 执行后,b的值为3,a的值为4。 又如: inta=3,b; b=++a; 执行后,b的值为4,a的值为4。 2.自增、自减运算符的运算 自增、自减运算为单目运算,其运算数据为单操作数,且操作数只能是变量,不能是常量或表达式。如7++、(x+y)--均是错误的表示方法。 3.自增、自减运算符的结合性 自增、自减运算符属右结合性。 例如,若有“inti=3;”则对于表达式-i++是理解为(-i)++呢,还是理解为-(i++)?因自增运算符只适用于变量,而-i不是变量,是表达式,显然(-i)++从语法上说是错误的。而-i++的“-”号与“++”号同级,也就是说,变量i两边出现两个级别相同的运算符,由于这种运算符属右结合性,因此i应先与右边的“++”号结合,即-i++等价于-(i++)。 又如:设有语句“inti=3,a;”,则表达式a=-(i++)等价于{a=-i;i=i+1;}。 由于“++”在i之后,故先使用i,然后使I的值增加1。执行该表达式后,a的值为-3,i的值为4。 在使用自增、自减运算符时应注意以下几项: (1)使用++i或i++单独构成语句时,其作用是等价的,均为i=i+1。 (2)运算对象只能是整型变量和实型变量。 (3)对于表达式(i++)+(i++)+(i++),不同的编程环境,其结果不同。若设“i=3;”,本书使用TurboC系统,表达式的值是9,i的值自增3次,结果为6。 【例2-9】自增、自减运算符的运算。 #include"stdio.h" main() { inti,j; i=3; j=i++; /*i赋给j,j=3,i自增1,i=4*/ printf("\nj=%d,i=%d",j,i); i=3; j=++i; /*i自增1,i=4,i赋给j,j=4*/ printf("\nj=%d,i=%d",j,i); i=3; printf("\ni=%d",i++); /*i=3输出i的值,然后i自增1,i=4*/ printf("\ni=%d",++i); /*i=4,i自增1,i=5,输出i的值*/ i=3; printf("\n%d,%d",i++,i++); /*运算由右至左,输出结果为4,3,之后i=5*/

printf("\n%d,%d",++i,++i); /*开始i=5,运算由右至左,输出结果为7,6,最后i=7*/ i=3; j=(i++)+(i++)+(i++); /*i=3,i先参与运算,j=3+3+3,之后i进行3次*/ /*自增1的运算,i=6*/ printf("\nj=%d",j); i=3; j=(++i)+(++i)+(++i); /*i=3,i先进行三次自增1的运算,i=6,j=6+6+6*/ printf("\nj=%d",j); } 运行结果:j=3,i=4j=4,i=4i=3i=54,37,6j=9j=18 2.3.3逗号运算符及其表达式 C语言提供一种特殊的运算符——逗号运算符,即“,”。逗号运算符的优先级别最低,结合性是自左至右。逗号表达式是指用逗号运算符将两个表达式结合起来的表达式。 1.逗号表达式的格式和功能 逗号表达式的格式为 表达式1,表达式2,表达式3,…,表达式n 功能:先计算表达式1,再计算表达式2,最后计算表达式n。最后一个表达式的值即为此逗号表达式的值。 2.逗号运算符的优先级 在所有运算符中,逗号运算符级别是最低的。例如,对于表达式b=a=3,6*b,其作用是将3赋给变量a和b,而逗号表达式的值为18。 利用逗号表达式可实现在一条C语言中对多个变量赋予不同值的功能。因此,在有些情况下,我们并不关心逗号表达式的值,而是关心逗号表达式中各个表达式的功能。 例如,表达式“a=3,b=4,c=5”的功能是将3,4和5分别赋给变量a,b和c;而表达式“a=7+b+c,a++”的功能是将7+b+c的值赋给变量a后,变量a自增加1。 注意,并不是任何地方出现的逗号都作为逗号运算符。例如,函数参数也是用逗号隔开的,如: printf("%d,%d,%d",a,b,c); 上一行“a,b,c”中的逗号不是逗号运算符,它只是起到了隔开参数的目的。 2.3.4赋值运算符及其表达式 1.赋值运算符 赋值运算符,即“=”,它的作用是将一个数据赋给一个变量。数据可以是常量、变量、表达式等。如“a=3”的作用是将常量3赋给变量a。 赋值运算符“=”不同于数学中的等号。因为x=x+1在数学中是绝对不成立的,而在C语言中是将x的值加1再赋给x变量。 2.复合的赋值运算符 在赋值运算符的前面加上其他运算符,可以构成复合的赋值运算符。凡是二目运算符都可以与赋值运算符一起构成复合赋值运算符。C语言规定有10种复合赋值运算符: +=,﹣=,*=,/=,%=,<<=,>>=,&=,^=,|= 复合赋值运算符级别相同,且与赋值运算符同一优先级,都具有右结合性,即结合方向是“自右至左”。 复合赋值运算符的运算比较特殊,例如: a+=3 等价于a=a+3 b-=8+3 等价于b=b-(8+3) x*=x+3 等价于x=x*(x+3) y%=3 等价于y=y%3 C语言中采用复合赋值运算符的目的,一是为了简化程序,二是为了提高编译效率。 3.赋值表达式 用赋值运算符或复合赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式,它的一般形式为变量赋值运算符表达式

每一个表达式都有一个值,赋值表达式的值就是前面变量的值。例如“x=10”是一个赋值表达式,表达式的作用是将10赋给变量x,此表达式的值为10。“a=b=10”也是一个赋值表达式,因为赋值运算符的结合性是“自右至左”,所以表达式先进行b=10的运算,然后再进行a=b的运算。 赋值表达式也可以包括复合的赋值运算符。例如: a+=a-=a*a 也是一个赋值表达式,此表达式运算比较复杂,先进行a=a-a*a运算,得到a的值之后,进行a=a+a运算。如果a的初值为12,最后得到的结果a=-264。 【例2-10】赋值运算符的使用。 #include"stdio.h" main() { inta,b; charc1,c2; a=b=48; /*将字符'0'的ASCII码值48赋给a和b*/ c1=a+3; /*将a+3的值赋给c1,即字符'3'的ASCII码赋给c1*/

c2=b+2; /*将b+2的值赋给c2,即字符'2'的ASCII码赋给c2*/ printf("%c,%c,%c,%c",a,b,c1,c2); } 运行结果: 0,0,3,2 2.3.5不同类型数据间的转换 C语言允许数据从一种类型转换为另一种类型,以适应各种不同的数据类型间的运算。 1.数据类型的自动转换 数据类型的自动转换常发生在以下情况中:(1)进行运算时转换。要求表达式中各操作数具有相同的数据类型,即不同类型数据进行混算时进行转换。 (2)赋值转换。把表达式值赋给与其不同类型的变量时进行转换。 (3)输出转换。其输出值的类型与其指定输出格式的类型不一致时,进行转换。 (4)函数调用转换。在实参与形参类型不一致时,进行转换。 下面仅介绍算术运算转换和赋值转换,其他转换在以后章节分别介绍。 2.不同类型数据间的混合运算图2.6混合运算时不同类型数据间的转换 整型、实型和字符型数据可以进行混合运算。在进行运算时,应先把不同类型的数据转换为同一类型,然后进行运算,转换规则,参见图2.6所示。 图中上、下两个横向向左箭头表示必然转换。也就是说,当浮点型float数据在运算时一定要先转换为double型数据;字符型char数据在运算时,一定要先转换为int整型数据。 图中纵向箭头表示不同类型数据运算时转换的方向。也就是说,按由低到高方向转换为相同类型即可进行运算。例如,int型数据与long型数据进行运算时,int型数据先转换为long型数据,然后运算,结果为long型数据。注意,只要由低向高转换为相同类型数据即可,不能理解为要转换为double型数据。 又如,int型数据、float型数据与double型数据进行运算时,int型和float型都要先转换为double型数据,然后再参加运算,运算结果为double型。例如: 其运算后,d的结果为double型数据。 3.赋值转换 在赋值语句中,如果赋值运算符两边类型不一致,但都是数值型或字符型数据,则C语言允许赋值表达式右边的值的类型自动转换为左边变量的类型,常见的赋值转换如下。 (1)将整型数据赋给实型变量,这时数值不变,但以实型数据形式存到变量中。例如: floatf; f=23; /*将23转换为23.000000,然后存入变量f中*/

(2)将实型数据赋给整型变量,这时舍弃小数部分,取整数部分赋给整型变量。例如: inti; i=2.68; /*i的值为2*/ (3)将int型整型数据赋给无符号型整型变量,int型数据按存储单元中实际二进制位的内容直接赋给unsigned型变量。 若int型数据为正数,即存储单元中最高位为0,赋值后,则int型数据与unsigned型数据的数值相同。 若int型数据为负数,即存储单元中最高位为1,赋值后,unsigned型数据在使用时,最高位将代表一定的数值(16位二进制数,最高位代表216-1)。

【例2-11】输出a和b所对应的无符号型数据。 #include"stdio.h" main() { inta,b; unsignedu1,u2; a=1;b=-1; /*-1以补码形式赋给b*/ u1=a; u2=b; /*-1的补码为1111111111111111,直接赋给u2*/ printf("%d,%d,%u,%u",a,b,u1,u2); } 运行结果: 1,-1,1,65535 说明:执行“a=1;b=-1;”后,有 高8位 低8位 a 00000000 00000001 b 11111111 1111111 执行“u1=a;u2=b;”后,有

高8位 低8位 u1 00000000 00000001 u2 11111111 11111111 在输出u2时,按无符号形式应为65535。 (4)字符型数据赋给整型变量。字符型数据占1个字节,而整型变量占2个字节,因此赋值转换过程中,存在位的扩展。 ①对于unsigned型变量,字符型数据(8位)传送给unsigned变量的低8位,而unsigned变量的高8位只需补0。 ②对于int型变量,若字符型数据最高位为0,则int型变量的高8位补0;若字符型数据最高位为1,则int型变量的高8位补1。这样可以保持数值不变。 【例2-12】输出c1和c2所对应的无符号型数据。 #include"stdio.h" main() { inta,b; charc1,c2; c1='a';c2='\376'; a=c1; b=c2; printf("%d,%d,%d,%d\n",a,b,c1,c2); printf("%u,%u,%u,%u\n",a,b,c1,c2); }运行结果:97,-2,97,-297,65534,97,65534其存储情况如下:高8位低8位c10000000001100001c20000000011111110a0000000001100001b1111111111111110 4.强制类型转换 在C语言中,可以利用强制类型转换符,将表达式的类型转换为所需类型。 强制类型转换的一般形式为 (类型名)表达式 例如:(int)a表示将a转换成int类型; (int)(3.2+5)表示将(3.2+5)转换成int类型,即将8.2 转换成8; (float)(7%3)表示将(7%3)的值转换成float型。 说明: (1)强制类型转换时,表达式要用括号括起来,以防止出现错误。 例如,设x=3.2,y=2.5,则表达式(int)(x+y)表示将x+y的值5.7取整,即值为5;而对于表达式(int)x+y,则表示先对x取整后,再加实型变量y的值,表达式的值为实型,其值为5.5。 (2)强制类型转换是将所需变量或表达式的值转换为可需类型,但并不改变原来变量和表达式的类型属性,也就是说原来变量或表达式的类型未发生任何变化。 (3)强制类型转换运算符要用圆括号括起来,而变量定义时类型名直接书写,在使用时易发生混淆,应特别注意。 【例2-13】强制类型转换。 #include"stdio.h" main() { inta,b,c; /*定义a,b,c为整型变量*/ floatx,y; /*定义x,y为实型变量*/ x=3.6;y=4.2; /*给x,y赋值*/ a=(int)x; /*将x值3.6转为整型并赋给a*/ b=(int)(x+y);/*将x+y的值转为整型并赋给b*/ c=a%b; /*a除以b的余数赋给c*/ x=x+y; /*x,y仍为实型,将其和赋给实型变量x*/ printf("a=%d,b=%d,c=%d,x=%f",a,b,c,x); }

运行结果: a=3,b=7,c=3,x=7.800000 从以上程序可以看出,在执行“a=(int)x;”语句时,把x的值3.6转换为整型数据3赋给a后,变量x的类型仍为实型。 上例也可缩写为下列程序段: #include"stdio.h" main() { intc; floatx=3.6,y=4.2; c=(int)x%(int)(x+y); x=x+y; printf("c=%d,x=%f",c,x); } 运行结果: c=3,x=7.800000习题2 一、选择题 2.1请选出可用作C语言用户标识符的一组标识符()。 A)voidDefineWord B)a3_b3_123IF C)For-abcCase D)2aDosizeof

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论