1、高级语言程序设计,第二章 数据类型、运算符与表达式信息学院自动化仪表研究所,一、 数据与数据类型,数据程序加工处理的对象及其结果。 数据类型数据在计算机内部的存储形式(占用的内存单元数量、编码方式、取值范围等)。 常量在程序运行过程中不允许改变的量。 变量在程序运行过程中允许改变的量。,1、基本概念,2、C语言的数据类型,基本类型,字符型 char 整型 int 浮点型,单精度 float 双精度 double,指针类型,构造类型,数组 结构 struct 联合 union 枚举 enum,无值类型,本章,数组,结构,指针类型,函数,一、 数据与数据类型(续),字符型(char) 1字节整型短
2、整型(short int ) 2字节基本型(int) 2字节(-3276832767)长整型(long int ) 4字节(21亿)实型单精度(float) 4字节 67位有效数字长单精度(long float) 8字节 1516位有效数字双精度(double) 8字节 1516位有效数字长双精度(long double)10字节 20位有效数字,可知对不同数据类型占用的存储空间:charshort=intlong =floatdouble,求某一类型数据所占存储字节数,可用运算符: sizeof(类型关键字),Example:main( ) printf(“char:%d字节n”,sizeo
3、f(char);printf(“float:%d字节n”,sizeof(float); ,结果显示: char:1字节float:4字节,Lets try,3、C语言的基本数据类型,注意事项,整型整数 int 的范围: 3276832767 Example:#include #include main()int a ;clrscr( ); printf(“Input :”);scanf(“%d”,运行结果:Input:12345a=12345Input:1234567a= -10617,Why?!,Because: 12345的补码是 00110000001110011234567的补码是 1
4、00101101011010000111 截去多余部份(超过2个字节的左边部分)后其原码为 1010100101111001(-10617) 参见教材P44“整型数据的溢出”。,注意事项,数据存储形式 字符型按ASCII码存储,其余以补码存储,复习: 二进制数的定点和浮点表示,定点表示法小数点位置是“固定的”定点数可用于表示整数。整数在机器中用补码表示。对于 int a=8,b=-8;,0 0000000 00001000,符号位: 0正数 1负数,1 0000000 00001000,1 1111111 11110111,正数的原码=正数的补码负数的原码和补码按以下规则相互转换:符号位不变,
5、数值位各位取反,未位加1。,0 0000000 00001000,原码,补码,符号位,数值位,a=810=10002,b=- 810=-10002,真值,1 1111111 11111000,浮点表示法小数点位置是“浮动的”。在计算机中一个浮点数由两部分组成:阶码和尾数,阶码是指数,尾数是纯小数。浮点表示法可用于表示带小数的数。(110.011)B=1.100112+10=11001.1 2-10 =0.110011 2+11即: N=数符尾数2阶符阶码尾数的位数决定数的精度阶码的位数决定数的范围,0 110011 0 11,阶符和数符: 0正数 1负数,注意事项,整型和字符型均可为unsig
6、ned (无符号型)P43图3.4 即将符号位亦作为数值位(默认为signed)此时 int 的范围 065535 char 的范围 0 255Lets try,?,在C程序中,字符型可与整型(255)互相通用 P50-51,输出结果: a,b,输出结果: 97,98,不变,d,b 100,98,Example: (参见P50例3.6, ASCII值见P374)main() main() char c1,c2; char c1,c2;c1=97;c2=98; c1=97;c2=98;printf(“%c,%cn”,c1,c2); printf(“%d,%dn”,c1,c2); ,思 考 如果将
7、例中char改成int,结果如何? 如果将c1=97改为c1=97+3,结果如何?lets try!,二、常量,整型常量 P41十进制数 12 -12l 或 -12L 700000ul八进制数 012 -012l十六进制数 0x12 -0x12l 实型常量 P45十进制形式 123.45 2.0 ( 必有小数点)指数形式 2.45e-4 1.13E3 (e或E前为数,后为整数)实型常量本身无单或双精度,其机内精度取决于赋给那类变量(影响有效数字位数,见P48示例) 字符常量/字符串常量,字符常量 P48,普通字符(可显示字符)A ? (只能单字符单引号)错误:ABC “A” ” 转义字符如回车
8、符、单引号、反斜杠等在程序中这些符号用表3.3所示的“转义字符”表示。 字符串(用双引号括起)“A” “?” (以0为字符串结束标志) 注意:用char定义的字符变量只能接受字符常量,而不能接受字符串常量(C语言中无字符串变量)char a=U ; char b=“U”; (b被置为某随机值),Example: main() char c1=a ,c2; c2=98; printf(“%d,%dn”,c1,c2); ,结果:97,98,Example: main() char c1=“a” ,c2; c2=98; printf(“%d,%dn”,c1,c2); ,结果:-108,98 若让c1
9、分别等于“U”、“ABC”、“A”结果不变,随机值,转义字符例题分析,Example: main()char ch;ch=362;printf(“%c,%d”,ch,ch); 运行结果: ,14 ch = 3628=24210=111100102 111100102 化为原码为 10001110= 1410,Example: #include main()printf(“an”x41”);printf(“n%dn”,strlen(“an”x41”); 运行结果: a “A 4 注:strlen为求字符串字节数函数(不计结束标志0)。,Example: P49例3.5 main()printf(
10、 “_ _ a b _ c t _ d e r f t g n ”);printf( “h t I b b j _ _ _ k” ); 运行结果:,_ _ a b _ c,_ _ a b _ c _ _ _ d e,f _ a b _ c _ _ _ d e,f _ _ _ _ _ _ _ g d e,h,h _ _ _ _ _ _ _ l,h _ _ _ _ _ _ _,h _ _ _ _ _ _,h _ _ _ _ _ _ j _ _ _ k,什么时候要使用转义字符?,转义字符只在特殊情况下才使用: C程序中需要实现某些特写打印或显示动作时如 printf(“123t56n”); C程序中
11、需要打印或显示以下三个字符时 (斜杠) “ (双引号) (单引号)如 printf(“Youre a ”a bad egg!” ” ); C程序中需要打印或显示ASCII表中非键盘字符时如 printf(“ Look 16 and x80 !”);,注意:使用转义字符时,后的八进制或十六进制数不应大于char类型所允许的范围(十进制值256)。,字符串常量有关问题,与“”的区别问题(判断正误):char c=“China”;char c=China; “China”占几个字节?141占几个字节?,等于十进制数97 即字符a,三、变量,赋值 P53例: b=(a=3+5) a=b=c=d=3+5
12、 (结果均为8)例:int a=b=c=d=3+5 (语法错误,除非b,c,d定义过)正确:int a, b=a=3+5;例: c=3+(a=5)*6 结果:c=33,a=5(一个语句可以有几个赋值运算) 变量必须先定义后使用 变量名必须符合标识符命名规则 P40,命名规则: 变量名由标识符表示,只能由字母、 数字和下划线三种字符组成,且第一个字符必须 为字母或下划线。 例如:下列标识符中,合法的变量名有:M.D.John 12%gf 1add _ce36 age&5thclass lotus-1-2-3 cd*ef,标识符应该“见名知意”,如 total , max 标识符应该“不宜混淆”,
13、如 l与1 , o与0,四、数据间的转换(混合运算),数据的类型级别 P54图3.10 基本规则 不同类型运算量参加运算,遵守“向高看齐”的类型一致化规则:将长度较短的运算量转换为长度较长的运算量,以保证不丢失信息。 将实型常量赋给整型变量,将被自动取整int a=7.999999 ; 等效于 int a=7; float型只要参加运算,均自动转为double。main()float i=3,j=4;printf(“%dn”,sizeof(i+j) ); /*结果为8(双精度)*/ 两个整型数相除,其值也一定是整型数(取商之整数部分)。 3/2的值为1而非1.5,强制类型转换 P56,例一:(
14、int)3.5 的值是多少?,例二:main() int x=5; float y=3.5;clrscr(); /*clear screen(清屏)*/ printf(“%d”, (int)y+x);结果是什么?,8,一般形式:(类型名)(表达式) 转换后表达式的数据类型为新的类型,但表达式中变量本身类型不变。,3,程序执行后y的类型是什么?,五、运算符和表达式,C语言运算符(13类) P55 1、算术运算 算术运算符 + * / % + + 例: 14%(-4)=2 -14%(-4)=-2 20.4%2(出错)例:若int a=7;float x=2.5,y=4.7; 则表达式x+a%3*(
15、int)(x+y)%2/4 的值是什么?2.500000 (1/4为0)例: float x,y; x%y; (出错),%两边必须是整型,五、运算符和表达式(续),自反算术赋值运算符(复合的赋值运算符) P62+= -= *= /= 等解法:将b*=看作b=b*(),其余类推例: c=b*=a+3 相当于(1)a+3 (2)b=b*(a+3) (3)c=b 例:若 i 、j 的初值分别为3和4,则执行 j+=i- =1 后i 、j 的值为多少?,解题步骤:i=i-1=3-1=2j=j+i=4+2=6 结果:i=2, j=6,关于优先级和结合方向: P56C语言规定了运算符的优先级和结合性。在表
16、达式求值时,先按运算符的优先级别高低次序执行。如果在一个运算对象两侧的运算符的优先级别相同,则按规定的结合方向处理。(各种运算符的优先级和结合性见P375附录) 【例】若x=7;则x+=x-=x+x的值是多少?,五、运算符和表达式(续),(-14),解法:从右到左,先做x=x-(x+x)=-7,再做x=x+x=-14,五、运算符和表达式(续),自加、自减运算符 P57+(自加运算符)-(自减运算符)用法: +1 -1 运算a、前缀形式int i=5; x = + i ; y= i ; (x=6, i =6, y=6)int i =5; + i ; x=y= i ; (x=6, i =6, y=
17、6)b、后缀形式int i =5; x = i +; y= i ; (x=5, i =6, y=6)int i =5; i +; x=y= i ; (x=6, i =6, y=6),若对某变量自加/自减而不赋值,结果都是使该变量自身1; 若某变量自加/自减的同时还要参加其他运算,则前缀运算是先变化后运算,后缀运算是先运算后变化。 注意:运算对象只能是整型变量, 5+或(x+y)+均为错,例一: main() int a=100; printf(“%dn”,a); printf(“%dn”,+a); printf(“%dn”,a+); printf(“%dn”,a); 运算结果:100 101
18、101 102,例二: 若 int x=3,y; 求下列运算后y和x的值y=x+ -1; (2 4) y=+x -1; (3 4) y=x - - +1; (4 2) 分析思路:先对右边的表达式进行扫描,如果x+,先取x值完成表达式运算后再让x自加1,如果+x,则先将x自加1后再代入表达式进行其他运算,例三: 若 int i=3 求下列运算后y和z的值y=(i+)+ (i+)+ (i+); y=9 (3+3+3) z=(+i )+ (+i )+ (+i ); z=18 (6+6+6) 分析思路:先对右边的表达式进行扫描,看是否需要先自加,如需要,就作若干次自加,然后再进行表达式的其他运算。 思
19、考:y=(+ i)+ (i+)+ (+ i);,y=15 (5+5+5),五、运算符和表达式(续),逗号运算 P63-64C语言中逗号可作分隔符使用,将若干变量隔开如 int a,b,c;又可作运算符使用,将若干独立的表达式隔开,并依次计算各表达式的值。其一般形式表达式1,表达式2,表达式n;逗号表达式的求解过程:先求表达式1的值,再求表达式2的值,最后求表达式n的值。整个逗号表达式的值是最后一个表达式n的值。在C语言所有运算符中,逗号表达式的优先级最低。,五、运算符和表达式(续),【例一】 main( ) int x,a; x=(a=3*5,a*4,a+5); printf(“x=%d,a=
20、%dn”,x,a); ,【例二】 main( ) int x,a; x=(a=3*5,a*4),a+5; printf(“x=%d,a=%dn”,x,a); ,运算结果:x=20,a=15,运算结果:x=60,a=15,【例三】main() int a,b,x;x=(a=8,b=15,b+,a+b);printf(“a=%d,b=%d,x=%dn”,a,b,x);,运算结果:a=8,b=16,x=24,关系运算(比较运算) P87关系运算符: = = = !=关系表达式: 含有关系运算符的表达式特别注意 aXb 之类算式的正确写法 : a=x & x=b(错误写法:a=X=b),【例】若x=1
21、000,则printf(“%d”,2x3)的结果是什么?,(不管x为何值,结果恒为1),Why?,【注意】关系表达式的值: 真1 假0;C语言中还规定:非0真 0假优先级:算术关系赋值逗号,讨论: if (1x2) 的条件为什么恒为真,五、运算符和表达式(续),五、运算符和表达式(续),【例一】 main( ) int m=5;if (m+5)printf(“m5”);else printf(“m=%d,”,m-);printf(“m=%d”,m-); ,运算结果: m=6,m=5,【例二】 main( ) int m=5;if (+m5)printf(“m5”);else printf(“m
22、=%d,”,m-);printf(“m=%d”,m-); ,运算结果: m5,五、运算符和表达式(续),逻辑运算 P88逻辑运算符: &(与运算符) 运算符两边均为真时,结果为真 |(或运算符) 运算符两边均为假时,结果为假!(非运算符) 将运算符右边真假倒置逻辑运算符的任一端如果为非0数,则视为“真”,为0则视为假。【例】printf(“%d”, !3+5) 结果为5printf(“%d”, !0+5) 结果为6注意:! 优先于关系运算符,与+、-同级。 常用优先级:!、+、- - 算术运算符 关系运算符 & 、| 赋值逗号,五、运算符和表达式(续),【例一】main( ) int a=1,
23、b=2,m=2,n=2; (m=ab),【例二】main( ) int a=1,b=2,m=2,n=2; (m=ba),运行结果:n=2,运行结果:n=3,原因:在&和|的左边如果能判断出结果,则右边不再作运算。 结论:在逻辑表达式的求解中,并不是所有的逻辑运算符都会被执行。只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。 (P90),五、运算符和表达式(续),【例三】有以下程序段:int a,b,c;a=b=c=1;+a|+b问执行后a、b、c的值各是多少?,a=2,b=1,c=1,五、运算符和表达式(续),【例四】编程判断任一给定年份是否闰年。符合以下条件的年份为闰年:
24、 P91能被4整除但不能被100整除;能被4整除又能被400整除(只需考虑能被400整除的情况) main() int year;clrscr();printf(“Input year=“);scanf(“%d“, ,五、运算符和表达式(续),条件运算 P96 条件运算符: ? : (三元运算符,即需连接三个运算量) 一般形式: e1?e2:e3 (e1为条件表达式,e2,e3为任意类型表达式) 功能:如果e10(为真),运算结果为e2的值。如果e1=0(为假),则取e3的值。,【例】分别令x=3,x=0,x= -5,求运行结果。本程序功能? main( ) int x,y;printf(“I
25、nput x=”);scanf(“%d”, ,结果: x=3,y=1 x=0,y=0 x=-5,y=-1,sizeof运算符,sizeof运算符是一个单目运算符,用以计算操作数在内存中占用的字节数。它的操作数可以是以下两种情况:类型标识符;一个表达式,五、运算符和表达式(续),main() int a=4, b;b=a+sizeof(double)+sizeof(a+3.14);printf(“b=%dn“,b); ,结果:20,五、运算符和表达式(续),C程序中的算术表达式 【例】编程求以下数学表达式的值(设x=15),#include main( ) int x=15;double y;
26、y=sqrt(pow(sin(15*3.14/180),2.5)/8/log10(2*3.14)+fabs(exp(2.5)-x);printf(“y=%f“,y); ,六、数据的输入和输出,一、数据输出 1、字符输出函数 P71格式: putchar(c)其中 c为字符型或整型的常量、变量及其表达式 功能:每次向屏幕输出一个字符供显示。,【例】求以下程序运行结果 #include main()char x=a;clrscr();putchar(x);putchar(b);putchar(x+2);putchar(b+2);,结果:abcd,六、数据的输入和输出,2格式输出函数 printf(
27、 ) P72 格式:printf( “”,输出项1,输出项2, ,输出项n );例:printf( “x=%d,y=%fn” , x , x+3 );,格式控制 (转换控制字符串),输出表列 (用逗号分隔的数据组,可选项),格式控制分为两个部分: 格式说明%+格式字符 (替换输出) 普通字符原样输出(转义字符按表3.3输出),格式说明的一般形式:% - 0 m.n l(或h) 格式字符 - 左对齐输出0 数字前的空位填0m 输出域宽(长度,包括小数点)如数据的位数小于m,则左端补以空格如数据的位数大于m,则按实际位数输出n 输出精度(小数位数)l 或 h 长度修正符l 长整型及双精度注:lon
28、g型的数据宜用%ld,double型宜用%lfh 表示短整型 如 %hd %hx,六、数据的输入和输出,格式字符(规定了输出的数据形式):%d 输出十进制整数 %x 以十六进制无符号形式输出整数 %o 以八进制无符号形式输出整数%u 以无符号十进制数形式输出整数%f 输出小数形式浮点数(double型用%lf )%s 输出字符串%c 输出单字符,六、数据的输入和输出,【例一】求运行结果。 main() int a=30;printf(“%d,%o,%x,%u,%c“,a,a,a,a,a); ,结果: 30,36,1e,30,,【例二】求运行结果。 main() int a= -30;print
29、f(“%d,%o,%x,%u,%c“,a,a,a,a,a); ,结果: -30,177742,ffe2,65506,,结论:格式字符与对应输出项类型要一致,否则正确的运算结果不能得到正确的显示结果。,六、数据的输入和输出,【例】若float y=1234.9999;printf(“%d”,y);则输出结果为何?,0,实际上本例中实数y为任意值(如1234或1)结果都是0!,【例】求以下程序段运行结果。printf(“|%-15s|%2.2f|n”,”ZHANG WEI”,165.1256);printf(“|%s|%012f|n”,”LI CHANG”,234.45);,运行结果: |ZHAN
30、G WEI |165.13| (注意:WEI后面补了六个空格) |LI CHANG|00234.450000| (注意:数字部分连小数点共12位),如果将程序段作些修改:printf(“|%-15s|%2.2f|n”,”ZHANG WEI”,165.1256);printf(“|%15s|%012f|n”,”LI CHANG”,234.45);,运行结果: |ZHANG WEI |165.13| | LI CHANG|00234.450000|,二、数据输入 1格式输入函数scanf() P79格式:scanf( “”,,六、数据的输入和输出,格式控制 (转换控制字符串),地址表列 (简单变量
31、要用&开头),格式说明的一般形式:% * m l (或h) 格式字符 & 求地址的运算符 &a 表示该变量所占空间的首地址* 抑制字符(“虚读”,即读入数据后不送给任何变量),【例】对于 scanf(“%3d%*4d%f”, 如果输入 1234567890.1234567890结果 i =123, f=890.123474,注意: scanf( )函数没有输出功能(即不会向屏幕显示任何字符) 也不能规定小数位数(m.n) 典型错误: scanf( “ %5.2f “,六、数据的输入和输出,正确语句: scanf( “%5f “, ,【说明】对于scanf(“%d%d%f”,之类格式字符相接 的
32、语句,应注意数据项值分隔处如何识别: 变类型时自动识别 按指定域宽自动分隔 用分隔符号(空格键,tab键,回车键) 用指定字符(如逗号等) 分隔(用户输入时也必须按该字符分隔) 注意没有精度规定(m.n)为了便于使用,应尽量采用某种习惯的分隔格式。,2字符输入函数 P71 格式: getchar( ) getche( )getch( )功能: 从键盘上读入一个字符,但后两个函数输入后无需回车。getch( )还有一个功能,即不把读入的字符回显到屏幕上,常用于密码输入或菜单选择。getchar( )包含在stdio.h中,getche( )和getch( )包含在conio.h中。,六、数据的输
33、入和输出,【例一】 #include main() char a,b;a=getchar(),b=getchar(); printf(“a=%c,b=%cn”,a,b); 运行时,如果输入:Student 输出结果为 a=S,b=t,【例二】 #include main() char i=y;while (i=y|i=Y)printf(“您好!是否继续?(y/n)n”);i=getche(); /*见注*/printf(“再见!”); 注: 不能用getchar(),否则会把回车符作为第二次读入值,【例三】 /*一个设置密码输入程序*/ #include main( ) char passwo
34、rd10,c=*;int i =0;printf(“npassword:“);while (i=9) passwordi=getch();putchar(c);if (passwordi=r) break;i+;/*此处加入密码验证语句*/printf(“n欢迎使用本程序!”); ,第二章作业,一、编程题 1、编写一个程序,从键盘输入任意一个五位数,把这个数值分解为单个数字,然后打印出每一个数字(每个数字之间用三个空格分开)。例如用户输入了42339,屏幕输出结果为: 4 2 3 3 9【提示】巧妙使用 / 和 % 两种运算符。2、已知三角形的三边长为a,b,c,计算三角形面积的公式为: ar
35、ea = , s= 求编写程序,从键盘输入a,b,c的值,计算并输出三角形的面积。3、 编程从键盘输入圆的半径r,计算并输出圆的周长和面积。,二、填空 C程序都是从 函数开始执行。 C程序的语句都是用 结束。 用来在屏幕上显示信息的库函数是 。 用来从键盘读取数据的库函数是 。 C程序中 用来提高程序的可读性。 若x和n均是int型变量,且x和n的初值均为5,则计算表达式x=n后,x的值为 ,n的值为 。 若有定义:int b=7; float a=2.5,c=4.7;则以下表达式的值为 。a+(int)(b/3*(int)(a+c)/2)%4 若a是int型变量,且a=6,则计算表达式a+=a-=a*a后,a的值为 。 假设所有变量均为整型,则表达式(a=2,b=5,a+,b+,a+b)的值为 。 判断char型变量c1是否为小写字母的正确表达式是 。A) a=a)&(c1=c1)|(z=a)&(c1=z),ASCII字符表,