1 / 41

C 语言程序设计

C 语言程序设计. 第二讲 数据类型、运算符与表达式 绍兴文理学院 自动化教研室 2010 年 7 月. 可知对不同数据类型占用的存储空间 : char<short<=int<long <=float<double. 一、 C 语言的数据类型. Let’s try …. C 语言的数据类型 P37 基本类型 字符型 ( char ) 1 字节 整型 — 短整型( short int ) 2 字节

lucas
Download Presentation

C 语言程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C语言程序设计 第二讲 数据类型、运算符与表达式 绍兴文理学院 自动化教研室 2010年7月

  2. 可知对不同数据类型占用的存储空间: char<short<=int<long <=float<double 一、C语言的数据类型 Let’s try… • C语言的数据类型P37 • 基本类型 字符型(char) 1字节 整型—短整型(shortint) 2字节 基本型(int) 2字节(-32768~32767) 长整型(long int) 4字节(±21亿) 实型—单精度(float) 4字节 6~7位有效数字 长单精度(long float)8字节 15~16位有效数字 双精度(double) 8字节 15~16位有效数字 长双精度(long double)10字节20位有效数字

  3. 求某一类型数据所占存储字节数,可用运算符: sizeof(类型关键字) Example: main( ) { printf(“char:%d字节\n”,sizeof(char)); printf(“float:%d字节\n”,sizeof(float)); } 结果显示: char:1字节 float:4字节

  4. 注意事项 Why?! 运行结果: Input:12345 a=12345 Input:1234567 a= -10617 • 整型≠整数 int 的范围: - 32768~+32767 Example: #include <stdio.h> #include <conio.h> main() { int a ; clrscr( ); printf(“Input :”); scanf(“%d”,&a); printf(“a=%d\n”,a); } Because:12345的补码是0011000000111001 1234567的补码是100101101011010000111 截去多余部份(超过2个字节的左边部分)后 其原码为1010100101111001(-10617) 参见教材P44“整型数据的溢出”。

  5. 示意图 字符型 (字符'a') 用一个字节存放该字符的ASCII值(ASCII值表见P364) 整 型 (十进制数25037) 用两个字节存放该数值的补码 实 型 尾数(补码) 指数(阶码) 注:第一位均为符号位 01100001 01100001 11001101 01100001……10100010101010 11100110 注意事项 • 数据存储形式 字符型按ASCII码存储,其余以补码存储

  6. 思 考 • 如果将例中char改成int,结果如何? • 如果将c1=97改为c1=97+3,结果如何? • Let’s try… ? 注意事项 不变 • 整型和字符型均可为unsigned (无符号型)P43图3.4 即将符号位亦作为数值位(默认为signed) 此时 int 的范围 0~65535 char 的范围 0 ~255 Let’s try… • 在C程序中,字符型可与整型(≤255)互相通用P50-51 Example: (参见P50例3.6,ACII值见P374) main() main() { { char c1,c2; char c1,c2; c1=97;c2=98; c1=97;c2=98; printf(“%c,%c\n”,c1,c2); printf(“%d,%d\n”,c1,c2); } } d,b 100,98 输出结果: a,b 输出结果: 97,98

  7. 二、常量 • 整型常量 P40 十进制数 12 -12l或 -12L 700000ul 八进制数 012 -012l 十六进制数 0x12 -0x12l • 实型常量 P47 十进制形式 123.45 2.0 ( 必有小数点) 指数形式 2.45e-4 1.13E3 (e或E前为数,后为整数) 实型常量本身无单或双精度,其机内精度取决于赋给那类变量(影响有效数字位数,见P15示例) • 字符常量/字符串常量

  8. Example: main() { char c1=‘a’ ,c2; c2=98; printf(“%d,%d\n”,c1,c2); } 字符常量 P52 结果: 97,98 • 普通字符(可显示字符) ‘A’ ‘?’(只能单字符单引号) 错误:‘ABC’ “A” ‘’’ ‘”’ ‘\’ • 转义字符(在单引号或双引号中以\开头) 如回车符、单引号、反斜杠等 在程序中这些符号用表3.3所示的“转义字符”表示。 • 字符串(用双引号括起) “A” “?” (以‘\0’为字符串结束标志) • 注意:用char定义的字符变量只能接受字符常量,而不能接受字符串常量(C语言中无字符串变量) char a=‘U’ ; char b=“U”; (b被置为某随机值) 随机值 Example:main() { char c1=“a” ,c2; c2=98; printf(“%d,%d\n”,c1,c2); } 结果: -108,98 若让c1分别等于“U”、“ABC”、“A”…结果不变

  9. 转义字符例题分析 Example: main(){ char ch; ch=‘\362’; printf(“%c,%d”,ch,ch); } 运行结果:≥,-14 ch = 3628=24210=111100102 111100102 化为原码为10001110= -1410

  10. 转义字符例题分析 Example: #include <string.h>main(){ printf(“a\n\”\x41”); printf(“%d\n”,strlen(“a\n\”\x41”)); } 运行结果:a “A 4注:strlen为求字符串字节数函数(不计结束标志‘\0‘)。

  11. 8列 8列 8列 转义字符例题分析 Example: P49例3.5 main(){ printf( “_ _ 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 _ _ _ _ _ _ _ g d e f _ a b _ c _ _ _ d e h h _ _ _ _ _ _ _ l h _ _ _ _ _ _ _ h _ _ _ _ _ _ h _ _ _ _ _ _ j _ _ _ k

  12. 什么时候要使用转义字符? 转义字符只在特殊情况下才使用: • C程序中需要实现某些特定打印或显示动作时 如printf(“123\t56\n”); • C程序中需要打印或显示以下三个字符时 \(斜杠)" (双引号) ' (单引号) 如printf(“You’re a \”a bad egg!\” ” ); • C程序中需要打印或显示ASCII表中非键盘字符时 如printf(“ Look\16 and \x80!”); 注意:使用转义字符时,\后的八进制或十六进制数不应大于char类型所允许的范围(十进制值256)。

  13. 字符串常量有关问题 • ‘A’与“A”的区别 • 问题(判断正误): char c=“China”; char c=‘China’; • “China”占几个字节?‘\141’占几个字节? 等于十进制数97 即字符’a’

  14. 三、变量 • 赋值 P53 例: b=(a=3+5) a=b=c=d=3+5 (结果均为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(一个语句可以有几个赋值运算) • 变量必须先定义后使用 • 变量名必须符合标识符命名规则P38

  15. 四、数据间的转换(混合运算) • 数据的类型级别 P54图3.10 • 基本规则 • 不同类型运算量参加运算,遵守“向高看齐”的类型一致化规则:将长度较短的运算量转换为长度较长的运算量,以保证不丢失信息。 • 将实型常量赋给整型变量,将被自动取整 int a=7.999999 ; 等效于 int a=7; • float型只要参加运算,均自动转为double。 main() { float i=3,j=4; printf(“%d\n”,sizeof(i+j) ); } /*结果为8(双精度)*/ • 两个整型数相除,其值也一定是整型数(取商之整数部分)。 3/2的值为1而非1.5

  16. 强制类型转换 P56 一般形式: (类型名)(表达式) 转换后表达式的数据类型为新的类型,但表达式中变量本身类型不变。 例一: (int)3.5 的值是多少? 程序执行后y的类型是什么? 3 例二: main() { int x=5; float y=3.5; clrscr(); /*clear screen(清屏)*/ printf(“%d”, (int)y+x); } 结果是什么? 8

  17. 五、运算符和表达式 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*(int)(x+y)%2/4的值是什么? 2.500000 (1/4为0) 例: float x,y; x%y; (出错)

  18. 五、运算符和表达式(续) ②自反算术赋值运算符(复合的赋值运算符)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=2 j=j+i=4+2=6 结果:i=2, j=6

  19. 五、运算符和算术表达式(续) • 关于优先级和结合方向: P56 C语言规定了运算符的优先级和结合性。在表达式求值时,先按运算符的优先级别高低次序执行。如果在一个运算对象两侧的运算符的优先级别相同,则按规定的结合方向处理。 (各种运算符的优先级和结合性见P365附录C) 【例】设i、j初值分别为3和4,则执行 j+=i-=1;后 i ,j的值为多少? 【例】若x=7;则x+=x-=x+x的值是多少? (i=2,j=6) (-14) 解法:从右到左,先做x=x-(x+x)=-7, 再做x=x+x=-14

  20. 五、运算符和表达式(续) ③自加、自减运算符P57 ++(自加运算符)--(自减运算符) 用法: +1 -1 运算 a、前缀形式 int i=5; x = ++ i ; y= i ;(x=6, i =6, y=6) int i =5; ++ i ; y= i ;( i =6, y=6) b、后缀形式 int i =5; x = i ++; y= i ;(x=5, i =6, y=6) int i =5; i ++; y= i ;( i =6, y=6) 若对某变量自加/自减而不赋值,结果都是使该变量自身±1;若某变量自加/自减的同时还要参加其他运算,则前缀运算是先变化后运算,后缀运算是先运算后变化。注意:运算对象只能是整型变量, 5++或(x+y)++均为错

  21. 五、运算符和表达式(续) 例一: main(){ int a=100; printf(“%d\n”,a); printf(“%d\n”,++a); printf(“%d\n”,a++); printf(“%d\n”,a);} 运算结果:100 101 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)分析思路:先对右边的表达式进行扫描,看是否需要先自加,如需要,就作若干次自加,然后再进行表达式的其他运算。 思考: y=(++ i)+ (i++)+ (++ i); y=15 (5+5+5)

  22. 五、运算符和表达式(续) ④逗号运算P65-66 C语言中逗号可作分隔符使用,将若干变量隔开 如int a,b,c; 又可作运算符使用,将若干独立的表达式隔开,并依次计算各表达式的值。其一般形式 表达式1,表达式2,…,表达式n; 逗号表达式的求解过程:先求表达式1的值,再求表达式2的值…,最后求表达式n的值。整个逗号表达式的值是最后一个表达式n的值。 在C语言所有运算符中,逗号表达式的优先级最低。

  23. 五、运算符和表达式(续) 【例一】 main( ) { int x,a; x=(a=3*5,a*4,a+5); printf(“x=%d,a=%d\n”,x,a); } 【例二】 main( ) { int x,a; x=(a=3*5,a*4),a+5; printf(“x=%d,a=%d\n”,x,a); } 运算结果:x=60,a=15 运算结果:x=20,a=15 运算结果:a=8,b=16,x=24 【例三】main() { int a,b,x; x=(a=8,b=15,b++,a+b); printf(“a=%d,b=%d,x=%d\n”,a,b,x);}

  24. 五、运算符和表达式(续) Why? ⑤关系运算(比较运算)P91 关系运算符: > < >= <= == != 关系表达式: 含有关系运算符的表达式 特别注意 a≤X≤b 之类算式的正确写法 : a<=x && x<=b(错误写法:a<=X<=b) 【例】若x=1000,则printf(“%d”,2<x<3)的结果是什么? (不管x为何值,结果恒为1) 讨论: if (1<x<2) 的条件为什么恒为真 【注意】关系表达式的值: 真—1 假—0; C语言中还规定:非0—真 0—假 优先级:算术>关系>赋值>逗号

  25. 五、运算符和表达式(续) 【例一】 main( ) { int m=5; if (m++>5) printf(“m>5”); else { printf(“m=%d,”,m--); printf(“m=%d”,m--); } } 【例二】 main( ) { int m=5; if (++m>5) printf(“m>5”); else { printf(“m=%d,”,m--); printf(“m=%d”,m--); } } 运算结果:m=6,m=5 运算结果:m>5

  26. 五、运算符和表达式(续) ⑥逻辑运算P92 逻辑运算符: &&(与运算符) 运算符两边均为真时,结果为真 ||(或运算符) 运算符两边均为假时,结果为假 !(非运算符) 将运算符右边真假倒置 逻辑运算符的任一端如果为非0数,则视为“真”,为0则视为假。 【例】printf(“%d”, !3+5) 结果为5 printf(“%d”, !0+5) 结果为6 注意:! 优先于关系运算符,与++、--同级。 常用优先级: !、++、-- >算术运算符 >关系运算符 >&& >|| >赋值>逗号

  27. 五、运算符和表达式(续) 【例一】 main( ) { int a=1,b=2,m=2,n=2; (m=a>b)&&++n; printf("%d\n",n); } 【例二】 main( ) { int a=1,b=2,m=2,n=2; (m=b>a)&&++n; printf("%d\n",n); } 运行结果:n=2 运行结果:n=3 原因: 在&&和||的左边如果能判断出结果,则右边不再作运算。 结论:在逻辑表达式的求解中,并不是所有的逻辑运算符都会被执行。只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。 (P94)

  28. 五、运算符和表达式(续) 【例三】 有以下程序段: int a,b,c; a=b=c=1; ++a||++b&&++c; 问执行后a、b、c的值各是多少? a=2,b=1,c=1

  29. 五、运算符和表达式(续) 【例四】编程判断任一给定年份是否闰年。符合以下条件的年份为闰年: P106 ①能被4整除但不能被100整除; ②能被4整除又能被400整除(只需考虑能被400整除的情况) main() { int year; clrscr(); printf("Input year="); scanf("%d",&year); if ((year%4==0&&year%100!=0)||year%400==0) printf("\n%d is a leap year!",year); else printf("\n%d isn't a leap year!",year); }

  30. 1 (x>0) y= 0 (x=0) -1 (x<0) 五、运算符和表达式(续) ⑦条件运算 P102 条件运算符: … ?… : …(三元运算符,即需连接三个运算量) 一般形式:e1?e2:e3 (e1为条件表达式,e2,e3为任意类型表达式) 功能: 如果e1≠0(为真),运算结果为e2的值。 如果e1=0(为假),则取e3的值。 【例】分别令x=3,x=0,x= -5,求运行结果。本程序功能? main( ) { int x,y; printf(“Input x=”); scanf(“%d”,&x); y=x>0?1:x<0?-1:0; /*结合方向:由右向左*/ printf(“x=%d,y=%d\n”,x,y); } 结果: x=3,y=1 x=0,y=0 x=-5,y=-1

  31. 五、算术运算符和算术表达式(续) ⑧sizeof运算符 sizeof运算符是一个单目运算符,用以计算操作数在内存中占用的字节数。它的操作数可以是以下两种情况: ●类型标识符; ●一个表达式 main() { int a=4, b; b=a+sizeof(double)+sizeof(a+3.14); printf("b=%d\n",b); } 结果:20

  32. 五、运算符和表达式(续) ⑨C程序中的算术表达式 【例】编程求以下数学表达式的值(设x=15) #include <math.h> main( ) { int x=15; double y; y=sqrt(pow(sin(15*3.14/180),2.5))/8/log10(2*3.14) +fabs(exp(2.5)-x); printf("y=%f",y); }

  33. 六、数据的输入和输出 【例】求以下程序运行结果 #include <stdio.h> main() { char x='a'; clrscr(); putchar(x); putchar('b'); putchar(x+2); putchar('b'+2); } 一、数据输出 1、字符输出函数 P73 格式: putchar(c) 其中c为字符型或整型的常量、变量及其表达式 功能: 每次向屏幕输出一个字符供显示。 结果:abcd

  34. 六、数据的输入和输出 2.格式输出函数 printf( )P75 格式: printf( “……”,输出项1,输出项2,…,输出项n ); 例:printf( “x=%d,y=%f\n” , x , x+3 ); 格式控制 (转换控制字符串) 输出表列 (用逗号分隔的数据组,可选项) • 格式控制分为两个部分: • 格式说明—%+格式字符 (替换输出) • 普通字符—原样输出(转义字符按表3.3输出)

  35. 六、数据的输入和输出 格式说明的一般形式: % - 0 m.nl(或h) 格式字符 -左对齐输出 0数字前的空位填0 m输出域宽(长度,包括小数点) 如数据的位数小于m,则左端补以空格 如数据的位数大于m,则按实际位数输出 n输出精度(小数位数) l或 h长度修正符 l 长整型及双精度 注:long型的数据宜用%ld,double型宜用%lf h表示短整型 如 %hd%hx

  36. 六、数据的输入和输出 【例二】求运行结果。 main() { int a= -30; printf("%d,%o,%x,%u,%c",a,a,a,a,a); } 结果: -30,177742,ffe2,65506,Γ 格式字符(规定了输出的数据形式): %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,▲

  37. 六、数据的输入和输出 结论: 格式字符与对应输出项类型要一致,否则正确的运算结果不能得到正确的显示结果。 【例】若float y=1234.9999;printf(“%d”,y);则输出结果为何? 0 实际上本例中实数y为任意值(如1234或1)结果都是0! 如果将程序段作些修改: printf(“|%-15s|%2.2f|\n”,”ZHANG WEI”,165.1256); printf(“|%15s|%012f|\n”,”LI CHANG”,234.45); 【例】求以下程序段运行结果。 printf(“|%-15s|%2.2f|\n”,”ZHANG WEI”,165.1256); printf(“|%s|%012f|\n”,”LI CHANG”,234.45); 运行结果: |ZHANG WEI |165.13| (注意:WEI后面补了六个空格) |LI CHANG|00234.450000| (注意:数字部分连小数点共12位) 运行结果: |ZHANG WEI |165.13| | LI CHANG|00234.450000|

  38. 六、数据的输入和输出 二、数据输入 1.格式输入函数scanf()P82 格式: scanf( “……”,&变量名1,&变量名2,…,&变量名n); 例: scanf( “%d,%d,%d ” ,&a,&b,&c ); 【例】对于 scanf(“%3d%*4d%f”,&i,&f); 如果输入 1234567890.1234567890 结果i =123, f=890.123474 格式控制 (转换控制字符串) 地址表列 (简单变量要用&开头) 格式说明的一般形式: %*m l (或h)格式字符 & —求地址的运算符 &a表示该变量所占空间的首地址 *—抑制字符(“虚读”,即读入数据后不送给任何变量)

  39. 六、数据的输入和输出 注意: scanf( )函数没有输出功能(即不会向屏幕显示任何字符) 也不能规定小数位数(m.n) 典型错误: scanf( “a=%d,b=%d,c=%d \n”,&a,&b,&c); scanf( “ %5.2f “,&x ); 正确语句: printf( “ Input a,b,c=“); scanf( “%d, %d, %d”, &a, &b, &c); printf( “\n” ); /*不必要*/ scanf( “%5f “, &x);

  40. 六、数据的输入和输出 【例一】 #include <stdio.h> main() { char a,b; a=getchar(),b=getchar(); printf(“a=%c,b=%c\n”,a,b); } 运行时,如果—— 输入:Student 输出结果为 a=S,b=t 【例二】 #include <stdio.h> main() { char i=’y’; while (i==’y’||i==’Y’){ printf(“您好!是否继续?(y/n)\n”); i=getche();} /*见注*/ printf(“再见!”); } 注: 不能用getchar(),否则会把回车符作为第二次读入值 【例三】 /*一个设置密码输入程序*/ #include <stdio.h> main( ) { char password[10],c='*'; int i =0; printf("\npassword:"); while (i<=9) { password[i]=getch(); putchar(c); if (password[i]=='\r') break; i++; } /*此处加入密码验证语句*/ printf(“\n欢迎使用本程序!”); } 2.字符输入函数 P74 格式: getchar( ) getche( ) getch( ) 功能: 从键盘上读入一个字符,但后两个函数输入后无需回车。getch( )还有一个功能,即不把读入的字符回显到屏幕上,常用于密码输入或菜单选择。getchar( )包含在stdio.h中,getche( )和getch( )包含在conio.h中。

  41. 第二讲 作业 一、编程题 要求:所有编程题须上机调试通过,源程序及运行结果用作业本上交。 源程序要求按缩进形式书写,文字端正整齐。不合格者退回重做。 1、编写一个程序,从键盘输入任意一个五位数,把这个数值分解为单个数字,然后打印出每一个数字(每个数字之间用三个空格分开)。例如用户输入了42339,屏幕输出结果为: 4 2 3 3 9 【提示】巧妙使用 / 和 % 两种运算符。 2、已知x=15,编程求: 要求输出结果以指数形式表示。 3、编程求任意系数值(a,b,c值由键盘输入)的一元二次方程任意根(实根、复根)的通用程序。要求能循环执行,直到用户选择结束为止。

More Related