c2第二章基本数据类型及其运算.ppt_第1页
c2第二章基本数据类型及其运算.ppt_第2页
c2第二章基本数据类型及其运算.ppt_第3页
c2第二章基本数据类型及其运算.ppt_第4页
c2第二章基本数据类型及其运算.ppt_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

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

文档简介

第2章 数据类型及其运算,程序由算法和数据构成。 数据是算法的处理对象。 要学习程序设计,首先要了解处理对象数据的特点。本章中我们讨论C语言中基本数据及其类型和基本的运算方法。,2.1 数据类型 通过对上一章的学习,我们知道: 不同的数据在计算机中的表示方法是不同的(如:定点数、浮点数、字符数据等不同类型),这是由计算机的二进制存储特性所决定的。 在程序中要指定数据的类型,以便编译系统能够按指定类型确定其表示方法、字节个数、以及运算方式。,图 2-1 C语言的数据类型,表2-1中,给出了Turbo C的基本类型名和长度以及取值范围。 234页的附录表-12中,给出了VC+的基本类型名和长度以及 取值范围。 需要指出的是:,(1)在各种 C的版本中: char、signed char、un signed char型数据的长度都是1个字节。,(2)在VC+中int与long型数据在长度、取值范围是一致的: -21亿 +21亿。 在Turbo C中int与short型数据在长度、取值范围是一致的:-32768 +32767。,(3)需要指出的是: char型与signed char型或unsigned char型二者之一相同。 int型与short型或long型二者之一相同。 具体如何,视不同编译系统而定。,(4)在C语言中,字符型数据存放的是字符的ASCII码值。有符字符型数据用一个字节的最高位作为符号位,低七位表示字符的ASCII码值。无符字符型用一字节的全部八位表示字符的ASCII码值。利用这个存储特点,C语言允许字符型数据以其ASCII码值(整型数)参加数值运算。,(5)在VC+和Turbo C中, float型数据的存储格式为: 阶码占8位,尾数占23位,1位符号位,共32位; double型数据的存储格式为: 阶码占11位,尾数占52位,1位符号位,共64位。 Turbo C采用IEEE标准的浮点数据存贮格式。 详见(美国)电子和电气工程师协会网站 The Institute of Electrical and Electronics Engineers,从表中可以看出:C语言中基本数据类型很多,短的、长的、有符的、无符的,变化丰富。初学者可能感到比较困难,其实从数据的存储形式上来看,归纳起来实质上只有两大类型的数据 整型数据和实型数据,即定点整数和浮点数。,2.2 常量与变量 2.2.1 常量 所谓“常量”是指在程序运行过程中,其值不能被改变的量。 C语言中常量有整型常量、实型常量、字符型常量、字符串常量、符号常量和枚举常量。 本节将介绍上述除枚举常量外的所有常量,枚举常量在第九章中介绍。,1. 整型常量 整型常量又简称整数,它有三种形式: 十进制整数、八进制整数、十六进制整数。 十进制整数 十进制整数由09十个数字、正号、负号组成,正负号只能出现在最左边,表示一个整数时,正号可以省略,多位数时,最左边的数字不能为0。例如: 123 597 425 0 0 是合法的整数。而0932是非法的整数表示方法。,八进制整数 八进制整数必须以0(零)开头并由07八个数字、正号、负号组成,正负号只能出现在最左边。例如: 0123 0404 0453 00 是合法的八进制整数,而0128是非法的。,十六进制整数 十六进制整数必须以0x或0X开头,由09, a,b,c,d,e,f(或A,B,C,D,E,F)这十六个符号和正负号组成,正负号只能出现在最左边。例如: 0x123 0Xfa1 0x9a12 0x0 是合法的十六进制数。 0x12g x897a 25b 是非法的十六进制数。,整型常量的后缀U和L U和L分别是unsigned 和long的第一个字母,可以跟在整型常量的后面,以指明该整数为长整型常数(long型)、无符整型常数(unsigned型)以及无符长整型整数(unsigned long型)。使用时U和L可以小写。例如: 长整型数: 32768l 0761L 0xd1dL 无符整型数: 32768u 0x2a7U 0277U 无符长整型数: 555ul 0xabcLU 0722ul * 对于TC编辑器:当一个整型常数的值是在3276832767之间,则该整型常量为int型,当它的值超过3276832767而在21亿21亿之间时,则该整型常量为long 型。通过使用L和U后缀,可以使在3276832767之间的int型常量成为long型常量或使有符常量成为无符常量。,2. 实型常量 实型常量又称浮点型常量,它有两种表示方法:十进制小数形式和指数形式。 十进制小数形式 十进制小数由09十个数字、小数点、正号、负号组成,正负号只能出现在最左边。例如: 123.5 032.45 .0 0. 是合法的实型常量。,指数形式 指数的一般形式如下: 整数部分 .小数部分en 其中 中内容为可选,但“整数部分”和“小数部分”二者至少选其一,不可全无。en为指数部分,e可大写,n是一个13位的十进制整数(第一位可为0),2e2表示2102,。例如: 123.5E3 0.45e4 1E012 0e5 是合法的指数形式。 -E5 -1E2.05 .e5 0.8Ek 是非法的指数形式。,实型常量的后缀F和L 因为实型常量缺省的类型为双精度实型,为了达到存储、精度、类型转换的需要,可用后缀F和L。F和L分别是float 和long double的第一个字母,可以跟在实型常量的后面,以指明该实数为单精度实数(float型)或长双精度实数(long double型)。使用时F和L可以小写。例如: 单精度实数: 32.768f 1F 1.2e3F 长双精度实数: 1.2e309l 0.1L 5L,3. 字符型常量 字符型常量是用一对单引号括起来的一个字符,如: a , A , $ ,等。空字符也是字符,它包含0个字符,它的值是0,可以表示为 ,也可以表示为 0 ,程序中总是用 0 表示空字符。 在C语言中还有另外一种字符常量,称为转义字符(Escape Sequences),它是以反斜线()开头的字符串,通常也把它们称为控制字符,因为它们中的大多数具有控制功能,如 n 代表换行符,在printf函数中使用它可以实现换行的功能。C语言中的转义字符见表2-2。,Using Escape Sequences 转义字符的应用,Escape Sequence a combination of two characters that produces a special effect within a text string. The 1st character is always a backslash() . 转义字符是两个字符构成字符串组合,用于实现一种特殊效果。 转义字符的第一个字符总是反杠 。,Escape Sequence List,Escape char. Meaning 0 null 空字符 a alarm 响铃 b back 退格,从当前位置向前移动一格 f feed 换页,从当前位置换到下一页开头 n new line 换行,从当前位置换到下一行开头 r return 回车,从当前位置换到本行的开头 t tab key 水平制表,水平换到下一tab位置 back slash 反斜线字符 single quote 单引号字符 double quote 双引号字符 ddd 000377范围里1到3位8进制数字对应的ASCII字符 xhh 0x000xff范围里1到2位16进制数字对应的ASCII字符,在C语言中,字符型常量是一个整数,其值是它所对应的ASCII码的值(见第222页附录), 字符型数据可以与数值型数据通用,即可以进行算术运算。,如: a 的值是97, A 的值是65, 的值是39。也可以用ddd或xhh来表示一个字符。以下都是表示水平制表符 t : t 011 11 x09 x9 而 a 也可以写成以下形式: 141 x61 例2.1,main() printf(Hello,Cn); printf(1101451541541575410312); printf(12/4=3tis a stringn); getch(); 运行结果: Hello,C Hello,C 12/4=3 is a string,4. 字符串常量 字符串常量是由双引号括起来的一串字符。如: 1234 、中国,北京 等。 值得注意的是:字符是用单引号括起来的,而字符串是用双引号括起来的。a 是字符,而a是字符串。字符串可以为空串即包含0个字符的串,表示为 。C语言规定:在每一个字符串后,系统自动加一个 0,作为字符串的结束标志符,以便判字符串的长度。由于这个原因,字符串的长度比实际长度大1。空串的长度为1,而不是0。,在使用字符串时,应当注意以下情况: (1) 单引号作为字符串的组成字符时,可以直接使用。 例如: printf( It s my book n ); 执行后输出为:It s my book (2)一个字符串不能分写在两行或多行上,如果非要写在两行上,则可在前一行的字符串尾部加一个反斜线 或者把不同行上的字符串分别用双引号括起来。 例如: printf( C programming language is powerfuln ); 或者: printf( C programming language is powerfuln );,5. 符号常量 符号常量是代表一个字符序列的标识符(又称宏名)。一旦定义了一个符号常量,则它就与该字符序列是等价的。 在C语言中,定义符号常量的方法有三种: 一是使用编译预处理的宏替换功能 #define ; 二是使用类型限定符 const 说明并初始化。 三是使用枚举类型来定义。,宏替换功能 #define定义符号常量,格式如下: #define 标识符 字符序列 其中:字符序列可以由任意字符组成,还可以是已经定义过的符号常量。 符号常量应先定义后使用,可以出现在程序中的任何位置,习惯上尽量放在程序的前面且符号常量(宏名)用大写字母书写,以示与其它标识符的区别。 需要指出的是:当一个标识符被定义成符号常量,则在编译时,编译预处理首先将程序中所有该标识符用相应的字符序列来替换,然后再进行后续处理。 例如: #define PI 3.14159 #define SPACE 等。 例2.2,#define STR1 “This is a “ main() #define STR2 “joke“ #define M STR1 STR2 printf(M); getch(); 运行结果: This is a joke,用 #undef 取消已定义了的符号常量。例如:#undef M 取消定义后,该符号常量(宏名)还可再定义并使用。,在实际应用中,#define常用来(临时)替换程序中的一些变量名或函数名,以避免对源程序的多处修改。,(补充) Named Constants 常变量,诸如50, 3.1416等在C+中称为literal constants, 即字面常量 literal constants在使用中存在两方面问题: 读者常难以理解常量的(物理)含义; 当改变常量的值时,必须逐一的变更 在定义变量时,如果加上关键字const, 则变量的值在程序运行期间不能改变,这种变量称为常变量(也称为定义符号常量)。定义常变量的一般格式为: const 类型说明符 常变量名 常量值; 例如:const int PASS_MARK=50; It is standard practice in C/C+ to use upper case when naming constants. This helps distinguish them from variables. 常变量名应使用大写字母,以便与变量名区别,使用常变量的例子: const int PASS_MARK=50; main() printf(“%d“,PASS_MARK+1); getch(); ,2.2.2 变量 所谓“变量”是指在程序运行过程中,其值可以被改变的量。 变量用变量名来表示,当程序运行时,系统为每一个变量分配一个内存单元并在变量名和该内存单元地址间建立一一对应的关系,引用该变量名时,实际上就是引用该变量名所对应地址单元的内容。 如图2-2所示:,数据是有不同类型的,它们的长度、表示方法也各不相同,因此变量也应有不同的类型,用以存放各种类型的数据。 常量的类型是通过书写形式确定的,是隐式说明的。 变量的类型则需要预先定义,是显式说明的。 在程序执行时,系统为已经定义的不同类型的变量分配单元,如为一个char型变量分配一个1字节的存储单元,为一个float型变量分配一个4字节的存储单元等,并确定了数据在其中的存储形式。,变量定义的格式如下: 类型定义符 变量名表; 例如: int student_num ; float student_score , aver ; 其中,类型定义符(见表2-1)定义变量名表中所列变量的类型,变量名表由一个或多个变量名组成,其间用逗号分隔,变量名的命名应符合C语言标识符的规定。,定义变量时,可以在定义的同时对变量进行初始化(赋初值),其格式如下: 类型定义符 变量名 = 表达式, ; 例如: long distance = 700000,height; double area = 9.6e7; float s = 3*distance; 其中,变量名=表达式中的“=”称为赋值号,其含义是将“=”右边表达式的值赋给其左边的变量。,在定义变量时,应注意以下几点: (1)在使用变量时,应注意“先定义,后使用”的原则。C语言程序中,使用的任何变量必须在使用前已经定义过,否则编译会给出错误信息 undeclared identifier。 (2)一般在一个函数中,变量名不能重复定义,如果重复定义,则编译会给出错误信息 redefinition。 (3)除非有特定的需要,通常把定义变量的语句集中放在函数的开始处,在C语言程序中,将变量定义语句放在不同的位置,其含义有所不同,随意放置可能引起不必要的错误。,建议:初学者加强对不同类型数据之表示方法以及存储方式的理解 。 如: int a; 语句定义了一个什么类型的变量,变量名是什么?该变量所对应的内存单元有几个字节?是有符还是无符的?数据范围是多少? float a; 或 double a; 或 long a; 呢? 注意:计算机内部是以二进制处理数据的,因此会产生误差: main() float x=3.1; printf(“%.8f“,x); getch(); 显示的是:3.0999999 ,指针的概念,指针是C语言最具特色的语言成分。也是C语言最具争论的语言成分。 简单地说,指针就是地址。 地址是计算机内存管理中的重要概念。计算机内存中的变量,指令的存取均是通过地址来进行的。 例如,在程序中对变量的访问是通过变量名进行的,而实际上系统是通过变量的地址来访问变量的。,定义存放3的整型变量a可以用:int a=3; 而定义存放变量a所在内存的地址2006, 就要用指针变量了:int *p;,也就是说:int *p 定义了一个可以存放任何整型变量地址的指针变量p。 要想让上边的a的地址2006存入到p里面,可以用赋值的方式:p=,main() /显示a的内存地址 int a=3; int *p; p= ,指针变量,定义指针变量的一般形式是: 类型标识符 *指针变量名 例如:int *p; 定义了一个指向整形变量的指针变量 p。 通常,将指针和被指变量一起定义: int x,*p= 指针变量是一种特殊的变量,它里面存储的数是另一个变量的内存(首)地址。 指针变量必须先定义,并且指向了指定类型的变量(获得实际地址值)后才能使用。否则其值为随机数,获取其引用变量的值时出现运行错。 指针变量的类型是它指向的那个变量的类型。 在一个指针变量中只能存放同一类型变量的地址。否则造成数据提取的错误。,指针变量的引用,在表达式中,可以使用&和*两个运算符: & 取地址运算符 以变量名为操作数,以该变量的地址为值。 如:p=&a; 将a的地址送入p &实现了指针变量的赋值。指针只有被赋值才有了意义。 * 取指针指向对象运算符(指针运算符) 以变量的地址为操作数,以该变量的值为值。 如: *p 就是 指针变量p所指向的变量,也就是a。 因此,p=&a将a的地址送入p, b=*p就将a的值赋给了b 即 printf(“%d“,a)与printf(“%d“,*p)是一样的。,&和*互为逆运算:*(&a)a &(*p)p 下边程序验证了&和*的运算互逆性质,main() int x=3,*p= ,从下边的例子可以进一步了解指针运算符*的作用,main() int a,b,*p1= ,运行结果:102,11 11,11,在一个指针变量中只能存放同一类型变量的地址,否则造成数据提取的错误。 下边这个程序验证了指向类型不一致的错误结果: main() int x=3,*p; float *q; p= ,运行结果: 0013FF7C 3 0013FF7C 0,由于p为整型指针,q为实型指针,在提取指向对象x的值时候就造成了不一致(应当都是3)。,2.3 运算符与表达式 C语言的的特点之一就是运算符(Operator)多,涉及的运算范围广,使用时变化非常丰富。可以根据运算符的功能进行分类(见表2-3),也可以根据运算符所需操作对象操作数(Operand)的个数分类。如:单目运算符(一个操作数)、双目运算符(两个操作数)、三目运算符(三个操作数)等。 用运算符将若干个操作数连接起来构成的式子称为表达式。 单个的常量、变量、有返回值的函数调用也是表达式(简单表达式)。 表达式运算的结果是一个值,称为表达式的值。 表达式结果值的类型称为表达式的类型。,注意 : (1)运算符对操作数有什么要求(类型、个数等)以及运算结果的数据类型。 (2)运算符的优先级别和运算符的结合方向,它是决定表达式的运算规则的重要因素。运算符的优先级别与结合型见附录。,运算符 名 称 表达式 结果及类型 + 加法运算符或正值运算符(双目) 1+2.6 3.6 实型 减法运算符或负值运算符(双目) 31 2 整型 * 乘法运算符(双目) 4*3 12 整型 / 除法运算符(双目) 4/3 1 整型 % 模运算符或称求余运算符(双目) 8%5 3 整型 + 正号运算符(单目) +2.6 +2.6 实型 负号运算符(单目) 3 3 整型 表2-4,2.3.1 算术运算符和算术表达式 算术运算符如表2-4所示:,1. 说明: (1)算术运算符是双目运算符,要求有两个运算对象,其中,+ 和 运算符还可作单目运算符。用算术运算符将运算对象(操作数)连接起来的式子称为算术表达式。 (2)算术运算符优先级别的由高到低的顺序是:单目运算符 + 和 、 *、/、% 、双目运算符 + 和 。同级运算符的运算顺序是从左至右。 (3)单目运算符 + 和 的结合方向为从右至左,其它双目运算符的结合方向是从左至右。例如(3),(4)求余运算符 % 只能用于整型量之间,且以被除数的符号作为余数的符号。 例如(4) (5)Turbo C提供了丰富的包括数学函数在内的库函数(见附录),以供编程使用。使用数学库函数时应在程序中加上编译预处理命令#include。在使用库函数时,应遵守函数对参数的要求,如:参数个数,参数类型以及参数的单位等。例如(5) 另外,可以使用一对或多对( )运算符,()的优先级别最高,其中的表达式优先运算。 思考:5*2+8/2+2 与 5*2+8/(2+2)的值各为多少? go,例如(3) 表达式5*2+8/2的值为6,先算5(右结合,负号运算),再乘以2,然后处理8除以2,最后完成加法。 例如(4) 表达式5 % 2的值为1,而表达式5 % 2的值为1。 例如(5) #include 运行后结果为: main() 3.000000 float r=9.0; printf(“%fn”,sqrt(r); ,2. 算术表达式的类型转换规则如下: (1) 算术表达式中,当操作数的类型相同时,其结果类型不变。 例如(1) (2)在C语言中,字符型操作数可以以其ASCII码值参加算术运算。 例如(2) (3)在C语言中,不同类型的操作数是可以进行混合运算的,其结果类型将按照规则发生变化。具体规则参见2.3.7节。 go,例如(1) 5/2的结果不是2.5而是2,就是因为这个原因。 例如(2) a +3的结果是整型数100,因为 a 的ASCII码值为97。,2.3.2 赋值运算符和赋值表达式 赋值运算符以及复合赋值运算符如表2-5所示: 算符 名 称 表达式 等 价 于 = 赋值运算符(双目) a=6+2 += 加赋值运算符(双目) a+=3 a=a+3 = 减赋值运算符(双目) a=4 a=a4 *= 乘赋值运算符(双目) a*=9 a=a*9 /= 除赋值运算符(双目) a/=5 a=a/5 %= 运算符(双目) a%=6 a=a%6 表2-5,1. 说明: (1)赋值运算符“=”的作用是将其右边表达式的值赋给其左边的一个变量,用赋值运算符将变量和表达式连接起来组成赋值表达式。例如(1) (2)一个变量可以被多次赋值,变量仅保存最后一次赋给的值。赋值运算符“=”的右边可以是表达式,而左边只能是变量。 (3)赋值运算符不同于数学上的“等号”,a=b和b=a再数学上是等价的,但在C语言中,前者表示将变量b的值赋给变量a,而后者正好相反。 (4)赋值表达式的值是赋给变量的值。 (5)赋值运算符是双目运算符,赋值运算符的优先级别相同,其结合方向为从右至左。算术运算符的优先级高于赋值运算符。 例如(5) go,例如(1) a=5 是一个赋值表达式,它表示将5赋给变量a。 例如(5) a=3+2 先算+,因为+的优先级高。然后将5赋给a。运算完成后,变量a的值为5,表达式的值为5。 a=b=7 先算b=7,因为=的结合方向为右结合。赋值表达式b=7的值为7,再将7赋给a。运算完成后,变量a和b的值为7,整个表达式的值为7。 a=(b=5)/(c=2) 先算b=5,再算c=2,然后进行除法运算结果为2,最终将2赋给a。运算完成后,b的值为5,c的值为2,a的值为2,整个表达式的值为2。,思考:若变量a已经有值且为9,那么表达式b=(a=4)/(b=a)的值是1还是0?回答是1,为什么? 2. 赋值表达式的类型转换规则如下: (1)将整型数据赋给实型变量时,数据以浮点数形式存储到实型变量中去,但值的大小不变。 例如:若已经定义float a,如果a=19,则将19转换成19.00000(单精度实型有7位有效数字),然后赋给变量a。 若已经定义double b,如果b=19,则赋给b的值是19.00000000000000(双精度实型有16位有效数字)。,(2)将实型数据赋给整型变量时,舍去小数部分后,再赋给整型变量。这里要注意变量的类型(short、int、long)以及相应的数值范围,避免赋值后数据的溢出。例如:若已经定义 float f=65538.0和short i,如果i=f,那么就会出现数据溢出的错误,表现为显示错误的数字。 main() float f=65538.0; short i; i=f; printf(“%d %fn“,i,f); getch(); ,2 65538.000000,(3)将float型数据赋给double型变量时,数值不变,有效位数扩展至16位(小数点后补0)。 main() float f=65538.0; double i; i=f; printf(“i=%lf f=%fn“,i,f); getch(); 反之,将double型数据赋给float型变量时,则截取double型数据的前7位有效数字,再赋给float型变量。这里,同样要注意数据溢出问题。 main() double f=22000000000.0; float i; i=f; printf(“i=%f y=%lfn“,i,f); getch(); ,(4)将整型数据赋给整型变量时,要格外关注两者间长度(char、short、int、long)和符号类型(singned、unsigned)上的差异,正是由于这些差异使得赋值完成后,变量里的值有所变化。具体如下: 将“长的”(字节数多的)整型数据赋给“短的”(字节数少的)整型变量时,采取截断的方法即按照“短的”字节数截取“长的”数据相应的低字节并按位赋给短的整型变量,截断时不考虑符号类型(见图2-3)。 to ,例如: int i=345; char c=a; c=i; printf(%dn,c); 运行后,输出: 89,将“短的”(字节数少的)整型数据赋给“长的”(字节数多的)整型变量时,存在着“符号扩展”的问题,具体分两种情况即算术扩展和逻辑扩展。,有符“短的”整型数据(signed)赋给“长的”整型

温馨提示

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

评论

0/150

提交评论