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

下载本文档

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

文档简介

1、第2章 数据类型、运算符与表达式,内容提要,基本数据类型; 常量和变量; 标识符命名; 常用运算符和表达式; 运算符的优先级与结合性,Hello, World,#include main() printf(hello, worldn); 超级无敌考考你:如何把“hello”和“world” 分别打印在两行?,hello.c,例2.1:一个简单的C程序例子,#include /*函数功能:计算两个整数相加之和 入口参数:整型数据a和b 返回值: 整型数a和b之和 */ int Add(int a, int b) return (a + b); /*主函数*/ main() int x, y, s

2、um = 0; printf(Input two integers:); scanf(%d%d, /*输出x和y相加之和*/ ,并列的两个函数 其中一个是 程序的入口,程序注释,C程序常见符号分类,关键字(Keyword) 又称为保留字,C语言中预先规定的具有固定含义的一些单词 数据类型修饰符int,控制语句return等 标识符(Identifier) 系统预定义标识符,main,printf 等 用户自定义标识符,Add, x, y 等 运算符(Operator) 34种,详见附录2 分隔符(Separator) 空格、回车/换行、逗号等 其它符号 大花括号“”和“”通常用于标识函数体或者

3、一个语句块 “/*”和“*/”是程序注释所需的定界符 数据(Data) 变量(Variable) 常量(Constant),标识符命名,作用 是用来给变量、函数、类型等起名字的,以便于区分。 定义 是以字母或下划线开头,后跟若干字母、下划线或数字。大小写敏感 正确:abc _abc a11 a12 _a12 ABC _23 Abc A_2 不正确:23 2A No. A-2,标识符命名,直观,见名知意,便于记忆和阅读 SUM、MAX、NODE 最好使用英文单词或其组合 切忌使用汉语拼音 下划线和大小写通常用来增强可读性 variablename variable_name variableNa

4、me 不允许使用关键字作为标识符的名字 int, float, for, while, if等 某些功能的变量采用习惯命名 如:for语句所采用的循环变量习惯用i, j, k,Windows 风格,UNIX 风格,P43, 2.1,基本数据类型,数据为什么有类型之分?,在程序中要处理大量的数 据,对于数据来说,它们有着 某些相同的属性,处理规律相 同,存储格式、取值范围也相 同。我们将具有相同属性的数 据称为一类,即数据类型,符 合计算机中数据的存储方式。,学习任何语言,首先要学习其数据类型.,C语言有丰富的数据类型,可以表达复杂的数据结构,数据类型(Data Type),b, B, KB,

5、MB, GB, TB,如何衡量数据类型所占空间大小? bit,中文叫法:位 Byte,中文叫法:字节 Kilobyte(KB),中文叫法: K Megabyte(MB),中文叫法:兆 Gigabyte(GB),中文叫法:G Terabyte(TB),中文叫法:T,1 TB = 1,024 GB,1 GB = 1,024 MB,1 MB = 1,024 KB,1 KB = 1,024 B,1 B = 8 b,b, B, KB, MB, GB, TB,一个位有多大? 只能是“0”或者“1”,这叫二进制 一个字节有多大? 保存一个字符(英文字母、数字、符号) ASCII(美国标准信息交换码)编码 见

6、P427附录D,常用字符与ASCII码对照表 两个字节保存一个汉字 GB编码 可以表示0255之间的整数,基本数据类型,int 整数,在目前绝大多数机器上占4个字节。 TC2中是2个字节 VC中是4个字节 float 单精度浮点数,一般是4个字节长 double 双精度浮点数,一般是8个字节长 char 字符,一般是1个字节长 用来表示256个ASCII字符,或者0255的整数,数据类型修饰符,short short int,短整数,一般2个字节长。通常简写为short long long int,长整数,一般是4个字节长。通常简写为long long double,长双精度(高精度)浮点数,

7、一般是10个字节长。 signed 用来修饰char、int、short和long,说明他们是有符号的整数(正整数、0和负整数)。一般缺省都是有符号的,所以这个修饰符通常省略 unsigned 用来修饰char、int、short和long,说明他们是无符号的整数(正整数和0),何谓类型溢出(Overflow)?,C语言直接提供的任何类型都有取值范围。当向其赋超过此范围的数值,就会产生数值溢出,得到一个不正确的结果。 vc中int的范围是-231231-1 如果超出取值范围,给它一个小于-231或者大于231的数会如何呢?,小蛇能吞下大象吗?,P29 2-7.c,溢出(Overflow)造成的

8、危害,一台安装了Windows 95/98的机器,如果连续运行49.7天没有重新启动,可能死机 原因: Windows自启动时刻起,有一个计数器,记录系统已经运行了多少毫秒。这个计数器是个unsigned long 类型的变量 unsigned long的最大值是:4294967295 一天有 24*60*60*1000 = 86400000毫秒 4294967295 / 86400000 = 49.71026961805 当49.7天的时候,此计数器会溢出,引起死机,何谓类型溢出(Overflow)?,生活中的例子: 身份证号码中的出生年 阿利亚娜号火箭发射失败 现象与危害: 溢出后的数值是

9、可预料的,但不同平台会有所不同。当程序从高位计算机向低位计算机移植(比如从64位系统移植到32位系统)时,以前从不出现的溢出问题可能出现。,类型溢出的解决方案?,解决方案: 预先估算运算结果的可能范围,采用取值范围更大的类型。 1+2+3+ 1!+2!+3!+ 13+23+33+ 如果不需要处理负数,则采用无符号类型。 在运算还没开始之前就判断运算数是否在合理的取值范围内。如果超出,则停止运算,转错误处理。,基本数据类型,常量,变量,在计算机中存储的数据,按存储的性质 分,可分为:,常量(Constant),整型常量 18、-31 long int型常量 123l、123L、123456l、1

10、23456L unsigned int型常量 123u、 123U 浮点常量 十进制小数形式 123.45、456.78 指数形式 1e-2、4.5e3 float型常量 123.45f、 456.78F、1e-2f、4.5e3F long double型常量 123.45l、 456.78L、4.5e3L 缺省为double 因为字母l和数字1容易混淆,所以当用l做后缀时,常使用大写形式,八进制与十六进制常量,以数字“0”开始的整型常数是八进制数 022、-037 010和10大小不一样 因为八进制并不常用,所以此种表示法比较少见 以“0 x”或者“0X”开始的整型常数是十六进制 AF和af

11、用来表示十进制的1015 十六进制的形式比较常用 0 x12、-0 x1F, -0 x1f,TC.EXE中的一段16进制代码,字符(Character)常量,字符常量的表示方法 a,A,5,%,$ 单引号内只能有一个字符,除非用“”开头 就是一个普通整数,也可以参与各种数学运算 每个字符具有一个0255之间的数值,可从ASCII表查出 注意:5和整数5的区别 字符的数学运算在密码学内用得比较多 用“”开头的字符为转义字符 例如,n,代表1个字符,The ASCII letter codes,字符常量,转义字符 一些特殊字符(无法从键盘输入或者另有它用)用转义字符表示,字符串(String)常量

12、,用双引号括住的由0个或多个字符组成的字符序列 I am a string 表示空字符串 转义字符也可以在字符串中使用 引号只作为字符串开始和结束的标志 C语言内部用0表示字符串的结束 除注释外,是唯一可以出现中文的地方 x和x是不同的 里定义了一系列专门的字符串处理函数,字符串在内存中的存放方式,在内存中每个字符按顺序存放 字符串结尾有一个空字符(ASCII=0, 0)作为字符串结束标志 字符串结束标志0是不能显示的,在字符串常量中,也不用显式写出来 举例 TEST a,由系统在字符串的末尾自动加一个0作为字符串的结束标志,字符常量与字符串常量的区别,字符常量和字符串常量是不同类型的数据 定

13、界符不同:字符常量使用单引号,而字符串常量使用双引号 a与a是不同的 字符常量只能是单个字符,字符串常量则可以含一个或多个字符 不能把一个字符串赋值给一个字符型变量 char a,c; a = A ; c= “A” ; /* 语句非法*/,a,宏常量,宏常量 也称符号常量 一般采用全大写字母表示 #define 标识符 字符串 不是语句,而是一种编译预处理命令 宏替换(Macro Substitulition) P22 2.2,为什么需要常量?,要避免使用幻数 直接使用的常数叫幻数。 现象与危害: 当常数需要改变时,要修改所有使用它的代码,工作量巨大,还可能有遗漏。 解决方案: 把幻数定义为宏

14、、const常量,或者枚举常量。 建议使用后两者。,#define ARRAY_SIZE 10 const int ARRAY_SIZE = 10; enum ARRAY_SIZE = 10;,例2.2 :计算圆的周长和面积,#include #define PI 3.14159 #define R 5.3 main() printf(area = %fn, PI * R * R); printf(circumference = %fn, 2 * PI * R); ,area = 88.247263 circumference = 33.300854,相当于执行 #include main()

15、 printf(area = %fn, 3.14159 * 5.3 * 5.3); printf(circumference = %fn, 2 * 3.14159 * 5.3); ,例2.2 :计算圆的周长和面积,#include #define PI 3.14159; #define R 5.3; main() printf(area = %fn, PI * R * R); printf(circumference = %fn, 2 * PI * R); ,相当于执行 #include main() printf(area = %fn, 3.14159;*5.3;*5.3;); printf

16、(circumference = %fn, 2*3.14159;*5.3;); ,语法错误,const常量,用const修饰定义的变量为常量 const float pi = 3.1425926; const常量与宏常量相比的优点是什么? const常量有数据类型 某些集成化调试工具可以对const常量进行调试,枚举(Enumeration)常量,一个被遗忘的角色 从程序来窥其一斑 enum weeks SUN, MON, TUE, WED, THU, FRI, SAT; enum weeks today; enum response no, yes, none; enum response

17、answer; today = TUE; answer = yes; if (answer = yes) printf(Today is Tuesday.n); else printf(Today is NOT Tuesday.n);,变量,变量,在程序中对变量的访问(存入,读取) 都是通过变量名进行的。变量在内存占据 存储空间,因此对变量也可以通过它在内存 中的地址,即指向变量的指针进行。,7,a,b,c,d,e,c=7,x=c,变量类型,原因,变量类型,类型说明,变量类型,注明,变量必需先定义,后使用。,变量分类,整形变量,浮点变量,字符变量,变量声明,使用变量的基本原则 变量必须先定义,

18、后使用 所有变量必须在第一条可执行语句前定义 声明的顺序无关紧要 一条声明语句可声明若干个同类型的变量 声明变量,是初始化变量的最好时机 不被初始化的变量,其值为危险的随机数 char esc = a; int i = 1; int sum = 0; float eps = 1.0e-5;,定义变量的两个主要作用,变量名标明数据在内存中的地址,在对程序进行编译连接时系统为每个变量名分配一个内存地址。 声明类型的目的是告诉系统变量需要占用的存储单元数据,以便系统为变量分配存储单元。,Defining the integer variable named total,变量的值可以在定义变量时获得,

19、也可以在程序执行的过程中获得 变量赋值的一般格式如下: 变量名=表达式 例如: y=x+6.9; 注意: “=”并非指两侧相等,而是包含了计算和赋值两个过程。,若没有定义变量直接在程序中使用变量: student_num=30; 则编译时会指出未定义错误。,若程序中有: int student_num; /*变量定义*/ : : student_num=30; /*给变量赋值*/ 则student_num变量是合法的。,说 明,整形变量,存储形式,符号位,数值部分,整形变量分类,标准整形(int),短整形(short),长整形(long) (与int相同),无符号整形(unsigned),整形

20、(=长整形),定义格式,定义举例,int 变量名表; long int 变量名表;,long int i, j, k; long n;,整形(=长整形),取值范围,当n=5时:,当n=-5时:,32位:,-231231-1,int i=2147483647;,实型变量,定义格式,定义举例,变量性质,float 变量名表; double变量名表;,float c1, c2, c3; double c4;,浮点数据的机内表示:,阶码是整数,阶符和阶码的位数合起来反映浮点数的表数范 围表数范围,小数点的实际位置;尾数是小数,其位数反 映了浮点数的精度表数精度, 尾数的符号代表浮点数的正负。 N= S

21、*10j,浮点数分类,单精度浮点数,双精度浮点数,实型数据提供的有效数字位数p28 例2.6,#include main() float a; double b; a = 123456.789e4; b = 123456.789e4; printf(%fn%fn, a, b); ,1234567936.000000 1234567890.000000,float型数据提供 7位有效数字,double型数据提供 16位有效数字,使用不当导致舍入误差,结论: 由于实数存在舍入误差,使用时要注意: 不要试图用一个实数精确表示一个大整数,记住:浮点数是不精确的。 实数一般不判断“相等”,而是判断接近或

22、近似。 避免直接将一个很大的实数与一个很小的实数相加、相减,否则会“丢失”小的数。 根据要求选择单精度、双精度。,字符变量,定义格式,定义举例,变量性质,char 变量名表;,char c1, c2, c3; char c4;,一个字符变量在内存中占一个字节。字符变量 只能存放一个字符。字符在内存中以ASCII码 值的形式存储,因此可以象整数一样运算。,注明,不能把字符串常量赋给字符变量。,char c1=a; char c1=abcd;,char型与int型之间的关系,例2.5:小写字母转换为大写字母,#include main() char ch = b; printf(%c, %dn,

23、ch, ch); ch = b - 32; printf(%c, %dn, ch, ch); ,#include main() char ch = b; printf(%c, %dn, ch, ch); ch = b - (a - A) ; printf(%c, %dn, ch, ch); ,b, 98 B, 66,b, 98 B, 66,使用变量要注意,不要对变量所占的内存空间字节数想当然 用sizeof获得变量或者数据类型的长度,注意!,sizeof到底是什么?,它是一个C语言的关键字,并不是函数 可以用两种形式使用 sizeof(表达式) 一般都使用sizeof(变量名) sizeof(

24、类型) 求出的结果为表达式值所属类型或者类型占用的字节数 现场演示程序例2.3,P25, 例2.3,例2.3,#include main() printf(Data type Number of bytesn); printf(- -n); printf(char %dn, sizeof(char); printf(int %dn, sizeof(int); printf(short int %dn, sizeof(short); printf(long int %dn, sizeof(long); printf(float %dn, sizeof(float); printf(double

25、%dn, sizeof(double); ,P25, 例2.3,为什么要用sizeof获得类型或变量的字长?,因为 同种类型在不同的平台其占字节数不尽相同。比如int在16位、32位和64位系统分别占2、4和8个字节。 现象与危害: 在平台间移植时会出现问题,导致数据丢失或者溢出。 解决方案: 用,并且只用sizeof获得字长。,C语言中的运算,计算机只会计算 任何事物都要被表示成数字和公式的形式后,才能被计算机计算(被计算机处理) 事物到数字和公式的转换过程叫数学建模 因为:事物在计算机内的处理都是一种计算 又因为:计算就要有操作数、运算法则和计算结果 所以:事物在计算机内的处理都有操作数、

26、运算法则和计算结果 计算结果你可以留用,也可以忽略,算术运算符,+,-,*,/ 加、减、乘、除运算 四则混合运算中,先算乘除,后算加减,按从左向右的顺序计算,左结合 % 求余运算,常用的标准数学函数,以下函数的返回值均为双精度类型。,算术运算的运算规则(),0.负值运算符优先级高,结合性从右往左 1.运算的优先顺序为先*、/、%,后+、-, 同等优先级从左到右运算。,举例: 18*5/95/9*18 2.5*8.0,2.两个类型相同的操作数,运算结果类型 也相同。类型匹配的原则!,算术运算的运算规则(2),3.两个类型不同的操作数,运算结果类型 与其中类型较高的类型相同。,举例:5.0/9 *

27、 182.5*8,4.求余运算的运算结果其值为相除所得余 数,而符号与被除数的符号相同。,举例:-135=-3 13%(-5)=3,算术表达式,定义,用算术运算符将运算对象连接起来的式子。,其中:运算对象包括常量、变量、函数等。,举例,a+b,c+d,a+b/c+d,(a+b)/(c+d),a+b,2c,(a+b)/2c,(a+b)/2*c,(a+b)/(2*c),cos45+2ex,cos(45)+2*exp(x),cos(3.14*45/180) +2*exp(x),算术表达式的举例,1/2*lg(x)-ln(x),1/2*(lg(x)-ln(x),1.0/2*(log10(x)-log(

28、x),0.5*(log10(x)-log(x),(log10(x)-log(x)/2,1.所有表达式 必须以线性 形式写出。 2.只能使用合法的标识符 3.乘号只能用* 4.函数自变量可以是表达式 且其必须写在括号内,三角 函数的参数以弧度表示 5.为指明正确的运算顺序, 可以使用“( )”,不能使用“ ”或“”。,说明:,1.0/2*(lg(x)-ln(x),赋值运算符 (Assignment Operators),赋值运算符 = 把右侧表达式的值赋给左侧的变量 一般情况下,赋值运算符左侧只能是变量 赋值运算符的优先级较低,“自右向左”结合 运算符两侧类型不一致时,要进行类型转换 转换原则是

29、:先将赋值号右边表达式类型转换为左边变量的类型,然后赋值。,赋值运算符 (Assignment Operators),赋值表达式的求解过程: 先计算赋值运算符右侧的表达式的值 将赋值运算符右侧的表达式的值赋给左侧的变量 整个赋值表达式的值就是刚才所赋的值。 赋值的含义:将赋值运算符右边的表达式的值存放到左边变量名标识的存储单元中。 注意“赋值”与“等于”的区别: 赋值符号“=”不同于数学的等号,它没有相等的含义。(“=”相等) 例i=i+2;,赋值运算符:= 赋值表达式一般形式: 变量 = 表达式 例: a=5; /*表达式的值为5*/ a=b=3; /*a=(b=3)*/ a=b=c=1;

30、/*a=(b=(c=1)*/ a=(b=4)+(c=3);/*b=4, c=3, a=7*/,注意:赋值运算符按自右而左的结合顺序,复合赋值运算符,=前加上算术运算符或位运算符 如+=,-=,*=,/=,%= 复合赋值表达式一般形式: =等价于: = 举例,z*=x+y;/* z=z*(x+y); */ n+=1 等价于 n=n+1 x*=y+1 等价于 x=x*(y+1) 注意:赋值运算符、复合赋值运算符的优先级比算术运算符低。,设有:float a=2.; 问:a/=3*5.;等价于a=a/(3*5.); 等价于a=a/3*5.吗?;,P43,2.2(7),main() int a=12,

31、n=5; /*2-10.c */ a+=a; printf(a+=a: a=%dn,a); /* a=24 */ a-=a-2; printf(a-=a-2: a=%dn,a); /* a=2 */ a*=3+2; printf(a*=3+2: a=%dn,a); /* a=10 */ a/=a+a; printf(a/=a+a: a=%dn,a); /* a=0 */ a%=n%=2; printf(a%=n%=2: a=%dn,a); /* a=0 */ a+=a-=a*=a; printf(a+=a-=a*=a: a=%dn,a); /* a=0 */ ,关系运算符,,=,=,=,!=

32、大于,大于等于,小于,小于等于,等于,不等于 关系运算符运算出的结果为0和非0 0,表示假,即该关系不成立 非0,表示真,即该关系成立 在所有涉及到真假判断的地方,0表示假,非0表示真,关系运算符 (Relational Operators),注意:在语言中,“等于”关系运算符是双等号“= =”,而不是单等号“= ”(赋值运算符),找别扭,int a=1;if (a = 0)printf(OK); int a=0;if (a = 0)printf(OK);,int a=1;if (a = 0)printf(OK); int a=0;if (a = 0)printf(OK);,= 和 =,int

33、 a;a = 0;a = 1;,int a;a = 0;a = 1;,一定要分清=和= 下面用法能起点小作用:,int a=0;if (0 = a)printf(OK);,int a=0;if (0 = a)printf(OK);,编译出错,例如,假设num1=3,num2=4,num3=5,则: (1)num1num2的值=0。 (2)(num1num2)!=num3的值=1。 (3)num1num2num3的值=1。 思考题:任意改变num1或num2的值,会影响整个表达式的值吗?为什么? (4)(num1num2)+num3的值=6,因为num1num2的值=1,1+5=6。 再次强调:

34、C语言用整数“1”表示“逻辑真”,用整数“0”表示“逻辑假”。所以,关系表达式的值,还可以参与其它种类的运算,例如算术运算、逻辑运算等。,73,例 若a=0; b=0.5; x=0.3; 则 a=x=b的值为,0,例 5278在C中是允许的, 值为,0,例 int i=1, j=7,a; a=i+(j%4!=0); 则a=,2,例 a0 结果为 A100 结果为,1,0,逻辑运算符,逻辑运算也被称为布尔(Boolean)运算 与运算 j = +i;/* i=i+1, j=i, i=4, j=4 */ j = i+;/* j=i, i=i+1, i=5, j=4 */ j = -i+;/* -(

35、i+), i=6, j=-5 */ j = i+*2;/* (i+)*2, i=7, j=12 */ a = (b+c)+;/* 非法! */ a = 34+;/* 非法! */ j = +i+;/* 非法! */,增一和减一运算符,良好的程序设计风格提倡:在一行语句中,一个变量只能出现一次加1或者减1运算 过多的加1和减1运算混合,不仅可读性差,而且因为编译器实现的方法不同,导致不同编译器产生不同的运行结果,自动类型转换,同种数据类型的运算结果,还是该类型 不同种数据类型的运算结果,是两种类型中取值范围更大的那种 long double double float long int short

36、 char,double,float,long,unsigned,int,char,short,精度低,精度高,自动类型转换,在进行赋值操作时,会发生类型转换 将取值范围小的类型转为取值范围大的类型是安全的 反之是不安全的 如果大类型的值在小类型能容纳的范围之内,则平安无事 但是,浮点数转为整数,会丢失小数部分,非四舍五入 反之,转换后的结果必然是错误的,具体结果与机器和实现方式有关。避免如此使用,好的编译器会发出警告,类型强转(Casting),消除从大到小的警告 l = (long)i; 可以通过“(类型)表达式”的方式把表达式的值转为任意类型 强转时,你必须知道你在做什么 强转与指针,并

37、称C语言两大神器,用好了可以呼风唤雨,用坏了就损兵折将,屠 龙刀,倚 天 剑,例2.7,#include main() int m = 5; printf(m / 2=%dn, m/2); printf(float)(m/2) = %fn, (float)(m/2); printf(float)m/2 = %fn, (float)m/2); printf(m = %dn, m); ,m/2 = 2 (float)(m/2) = 2.000000 (float)m/2 = 2.500000 m = 5,两个整数运算的结果 还是整数,不是浮点数,位运算,数的三种表示形式,位式运算,数的三种表示形式,原码,反码,补码,符号位为0表示正数,符号位为1表示负数,数值位是其值的绝对值。 正数:0000101101110101 负数:1000101101110101,一个数如果值为正数,则它的反码与原码相同;一个数如果值为负,则符号位为1,其余各位是对原码取反。 正数:0000101101110101 负数:1111010010001010,一个数如果值为正数,

温馨提示

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

评论

0/150

提交评论