《第三讲C程序设计初步》由会员分享,可在线阅读,更多相关《第三讲C程序设计初步(67页珍藏版)》请在金锄头文库上搜索。
1、第三讲 C 程序设计初步程序设计初步1主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件参参考考资资料料l 谭浩强,谭浩强,C 程序设计程序设计,第三版第三版 l B.W. Kernighan and D.M. Ritchie,The C Programming Language (C程序设计语言程序设计语言) , 第二版第二版 l H. Schildt,C语言大全语言大全, 第四版第四版 2程序设计语言的发展程序设计语言的发展CPU指令系统,由指令系统,由0、1构成构成的指令码组
2、成;是计算机唯的指令码组成;是计算机唯一能识别并直接执行的语言一能识别并直接执行的语言用助记符号描述的指令系统用助记符号描述的指令系统如如 ADD, SUB;需翻译成机;需翻译成机器语言,符号化的机器语言器语言,符号化的机器语言机器语言机器语言汇编语言汇编语言高级语言高级语言面向过程面向过程面向对象面向对象面向应用面向应用效率高效率高编程难编程难3程序设计语言的发展程序设计语言的发展52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96AdaALGOL60ALGOL68PascalModula-2BCPL BCC
3、+JavaLISPPROLOGCOBOLFORTRAN77FORTRANPL/1Simula 67Smalltalk 80BASICANSI-BASICQBASIC VBFORTRAN90CPL4程序设计语言的发展程序设计语言的发展q FORTRAN:Formula Translation1956年,高级语言产生的标志,简洁高效,是科学计年,高级语言产生的标志,简洁高效,是科学计算的主流语言算的主流语言q BASIC:Beginners All-purpose Symbolic Instruction Code1964年,面向大众,特别是大学生年,面向大众,特别是大学生q Pascal70年代
4、,结构化程序设计,强调语言的可读性年代,结构化程序设计,强调语言的可读性q C70年代,通用的、过程式的编程语言,高效、灵活,年代,通用的、过程式的编程语言,高效、灵活,主流的软件开发语言主流的软件开发语言5C 语言的发展语言的发展q C语言的发展历史语言的发展历史l 19691973,由,由 Dennis M. Ritchie 设计并实现设计并实现l 1973,UNIX的内核正式用的内核正式用C语言改写语言改写l 1978,B. Kernighan 和和 D. RitchieC程序设计语言程序设计语言l 19831989,ANSI C 标准形成标准形成 (C89)l 1999, 发表新的标准
5、发表新的标准 C99 q 常见的常见的 C语言编译器语言编译器l GNU C Comipler (Linux): gccl Microsoft Visual C Comiplerl Borland Turbo C l Intel C Comipler (Linux/Windows)l PGI C Comipler (Linux/Windows)6一个简单的编程实例一个简单的编程实例/* example: calculate the sum of a and b */#include /* the main program */main() int a, b, sum; a=10; b=24;
6、sum=add(a,b); printf(sum=%dn, sum);/* function: sum of two integers */int add(int x,int y) int z; z=x+y; return(z);注解语句注解语句函数函数预处理预处理7C 程序结构特点程序结构特点n 源程序结构源程序结构l 一个一个 C 源程序由一个或多个源文件组成源程序由一个或多个源文件组成l 每个源文件可由一个或多个函数组成每个源文件可由一个或多个函数组成l 一个源程序有且只能有一个一个源程序有且只能有一个main 函数,即主函数函数,即主函数l 程序执行从程序执行从 main 开始,在开始
7、,在 main 中结束中结束l 源程序中可以有预处理命令,通常应放在源文件或源程序中可以有预处理命令,通常应放在源文件或 源程序的最前面源程序的最前面8C 程序分析程序分析l 每个说明和每个语句都必须以分号每个说明和每个语句都必须以分号 “ ; ” 结尾,结尾, 但预处理命令,函数头和花括号但预处理命令,函数头和花括号 “ ” 之后不能加分号之后不能加分号l 标识符,关键字之间必须至少加一个空格以示间隔,标识符,关键字之间必须至少加一个空格以示间隔, 若已有明显的间隔符,也可不再加空格来间隔若已有明显的间隔符,也可不再加空格来间隔l 一行可以写多个语句,一个语句可以分几行书写一行可以写多个语句
8、,一个语句可以分几行书写l 习惯用小写字母,习惯用小写字母,区分大小写区分大小写l 注释:注释:/* */ 为注释符为注释符, 不能嵌套不能嵌套l 不使用行号,无程序行概念不使用行号,无程序行概念l 常用锯齿形书写格式常用锯齿形书写格式n 源程序书写源程序书写书写漂亮的书写漂亮的 C 程序的基本要求:程序的基本要求: 对齐对齐 一行写写一个语句,一个语句写一行一行写写一个语句,一个语句写一行使用使用 TAB 缩进缩进有足够的注释有足够的注释有合适的空行有合适的空行9C 语言语言字符集字符集l 字母(大小写共字母(大小写共 52 个)个)l 数字数字l 空白符(空格符、制表符、换行符)空白符(空
9、格符、制表符、换行符)l 标点和特殊字符标点和特殊字符10C 语言词汇语言词汇n 六类:标识符,关键字,运算符,分隔符,常量,注释符六类:标识符,关键字,运算符,分隔符,常量,注释符l 标识符:标识符:用来标识变量名、函数名等的字符序列用来标识变量名、函数名等的字符序列 由字母、数字、下划线组成,第一个字符必须是字母或下划线由字母、数字、下划线组成,第一个字符必须是字母或下划线 区分大小写,不能用关键字区分大小写,不能用关键字 标准标准 C 不限制标识符的长度,实际长度与编译器有关不限制标识符的长度,实际长度与编译器有关 命名原则:见名知意、不宜混淆命名原则:见名知意、不宜混淆l 关键字关键字
10、 (32个个):具有特定意义的字符串,通常也称为保留字具有特定意义的字符串,通常也称为保留字 类型说明符、语句定义符(控制命令)、预处理命令字类型说明符、语句定义符(控制命令)、预处理命令字l 运算符运算符l 分隔符:分隔符:逗号和空格逗号和空格l 常量:常量:数字、字符、字符串、转义字符、符号常量等数字、字符、字符串、转义字符、符号常量等l 注释符:注释符:以以“ /* ”开头并以开头并以“ */ ”结尾结尾11编辑与运行编辑与运行 (Linux)l 编写源程序,以编写源程序,以 .c 为扩展名(可使用任何文本编辑器)为扩展名(可使用任何文本编辑器)l 编译并连接源文件编译并连接源文件 (可
11、以一步完成)(可以一步完成)l 运行编译生成的可执行文件运行编译生成的可执行文件gcc o 输出文件输出文件 源文件源文件-o :指定输出文件名,缺省为指定输出文件名,缺省为 a.out-c :只编译不链接,即只生产目标文件只编译不链接,即只生产目标文件(.o 文件)文件)-Ipath :指定或增加包含文件(如指定或增加包含文件(如 *.h)的搜索路径)的搜索路径-Lpath :指定(增加)库文件的搜索路径指定(增加)库文件的搜索路径-lname:与库文件与库文件 libname.a 链接链接-O, -O1, -O2, -O3 :优化开关优化开关-g :在目标码中加入更多信息,用于程序调试在目
12、标码中加入更多信息,用于程序调试12算法算法 学习程序设计的目的不只是学习一种特定的语言,而是学习程序设计的目的不只是学习一种特定的语言,而是学习进行程序设计的一般方法学习进行程序设计的一般方法 掌握了算法就是掌握了程序设计的灵魂,再学习有关的掌握了算法就是掌握了程序设计的灵魂,再学习有关的计算机语言,就能顺利编写出程序计算机语言,就能顺利编写出程序 脱离了具体的语言去学习程序设计是困难的,但学习语脱离了具体的语言去学习程序设计是困难的,但学习语言只是为了程序设计,它本身并不是目的言只是为了程序设计,它本身并不是目的程序程序 = 算法算法 + 数据结构数据结构 + 程序设计方法程序设计方法 +
13、 语言工具和环境语言工具和环境 算法:算法:为解决一个问题而采取的方法和步骤为解决一个问题而采取的方法和步骤l 结构化程序设计方法结构化程序设计方法程序结构规范、清晰、模块化程序结构规范、清晰、模块化13主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件14数据结构数据结构指针类型指针类型空类型空类型(void)定义类型定义类型(typedef)整型整型实型实型字符型字符型 (char)整型整型 (int)短整型短整型 (short)长整型长整型 (long)单精度单精度 (flo
14、at)双精度双精度 (double)基本类型基本类型C 数数据据类类型型 数组数组结构体结构体 (struct)枚举型枚举型 (enum)构造类型构造类型无符号无符号 (unsigned)有符号有符号数据类型决定:数据类型决定:1. 数据占内存字节数数据占内存字节数2. 数据取值范围数据取值范围3. 可参与的运算与操作可参与的运算与操作公用体公用体 (union)15基本数据类型基本数据类型类型类型关键字关键字所占字节数所占字节数表示范围表示范围整型整型int2-215 215 -1short2-215 215 -1long4-231 231 -1unsigned int2 0 216 -1u
15、nsigned short2 0 216 -1unsigned long4 0 232 -1实型实型float 4 (6-7) 10-38 1038double 8 (15-16) 10-308 10308long double 16 (18-19) 10-4932 104932字符型字符型char1 例:例:example_datatype.c (long double与系统及编译器有关)与系统及编译器有关)16常量常量l 整型常量:整数,后面加整型常量:整数,后面加 l 或或 L 表示长整型表示长整型l 实型常量:双精度实数,后面加实型常量:双精度实数,后面加 f 或或 F 表示单精度表示
16、单精度l 字符型常量:用单引号括起来的单个字符字符型常量:用单引号括起来的单个字符l 字符串常量:用双引号括起来的字符序列字符串常量:用双引号括起来的字符序列n 在程序运行中值不能改变的量在程序运行中值不能改变的量l 符号常量:符号常量:用标识符代表常量用标识符代表常量#define PRICE 30l 一般使用大写字母一般使用大写字母l 是宏定义预处理命令,不是是宏定义预处理命令,不是 C 语句语句17变量变量l 变量名:变量名:要求与标识符相同要求与标识符相同l 变量类型:变量类型:整型、实型、字符型整型、实型、字符型l 变量必须先声明,后使用变量必须先声明,后使用n 值可以改变的量值可以
17、改变的量n 变量的声明变量的声明类型关键字类型关键字 变量名列表变量名列表int i, j, k=0;double a,b=3.1415,c;char c;l 变量声明时可以进行初始化变量声明时可以进行初始化18类型转换类型转换n 自动转换自动转换n 强制转换强制转换l 不同类型的数据进行运算,需先转换成同一类型不同类型的数据进行运算,需先转换成同一类型l 转换按数据长度增加的方向进行,以保证精度不降低转换按数据长度增加的方向进行,以保证精度不降低l 所有的浮点运算都是以双精度进行的所有的浮点运算都是以双精度进行的l char 型和型和 short 型参与运算时,必须先转换成型参与运算时,必须
18、先转换成 int 型型l 赋值号两边的数据类型不同时,右边的类型将转换为左边的赋值号两边的数据类型不同时,右边的类型将转换为左边的char, short int unsigned long double float(类型说明符类型说明符) 表达式表达式 l 将表达式的将表达式的值转换成指定的类型转换成指定的类型19运算符运算符l 算术运算符:算术运算符:+、-、*、/、%、+ (自增自增)、- (自减自减)l 关系运算符:用于比较运算,关系运算符:用于比较运算,、=、=、!=l 逻辑运算符:用于逻辑运算,逻辑运算符:用于逻辑运算,&、|、!l 位操作运算符:按二进制位进行运算,位操作运算符:按
19、二进制位进行运算, &、|、 (异或异或)、 (右移右移)l 赋值运算符:赋值运算符: =、+=、-=、*=、/=、%= 、&=、|=、=、=、 .! + (type) * & sizeof* / %+ = !=&|&|? := += = *= /= 等等,高高低低21数组变量数组变量n 一维数组的声明一维数组的声明类型关键字类型关键字 数组名数组名常量表达式常量表达式int a10;double b12+21, c16;char ch3*4;n 一维数组的引用一维数组的引用例:例:example03.c数组名数组名常量表达式常量表达式 C 语言中数组的下标是从语言中数组的下标是从 0 开始的
20、开始的22数组变量数组变量n 二维数组的声明二维数组的声明类型关键字类型关键字 数组名数组名常量表达式常量表达式1常量表达式常量表达式2double A88, B88;n 二维数组的引用二维数组的引用例:例:example02.c数组名数组名常量表达式常量表达式1常量表达式常量表达式2 C 语言中二维数组是按行排列的语言中二维数组是按行排列的23字符变量字符变量n 字符变量的声明字符变量的声明char c1, c210, c86;l 每个字符变量只能存放一个字符每个字符变量只能存放一个字符l 字符是按字符是按 ASCII 码的形式存放在内存中的码的形式存放在内存中的n 字符串和字符串结束标志字
21、符串和字符串结束标志l 字符串是以双引号括起来的字符序列字符串是以双引号括起来的字符序列l 通常用字符数组存放字符串通常用字符数组存放字符串l 字符串结束标志字符串结束标志“0”是系统自动生成的是系统自动生成的l 常用的字符串函数有(在头文件常用的字符串函数有(在头文件 string.h 中中):): puts、gets、strcat、strcpy、strcmp、strlen 例:例:example04.c24主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件25C 程序结构程序结
22、构C 程序程序源程序文件源程序文件 1源程序文件源程序文件 2源程序文件源程序文件 n 预处理命令预处理命令变量声明变量声明函数函数 1函数函数 n 函数首部函数首部函数体函数体局部变量声明局部变量声明执行语句执行语句26语句语句l 表达式语句表达式语句l 函数调用语句函数调用语句l 控制语句控制语句l 复合语句复合语句l 空语句空语句n C 语句可分为以下五类语句可分为以下五类函数名函数名(实际参数表实际参数表);条件、循环等条件、循环等将多个语句用将多个语句用 括起来组成的一个语句括起来组成的一个语句只有分号只有分号表达式;表达式;27赋值语句赋值语句n 赋值语句赋值语句变量变量 = 表达
23、式;表达式;l 左端只能是变量名左端只能是变量名l 当表达式的数据类型与左边的变量不一致时,系统自当表达式的数据类型与左边的变量不一致时,系统自动将表达式的值转换为左端变量的数据类型动将表达式的值转换为左端变量的数据类型 l 可以多重赋值(初始化时不能多重赋值)可以多重赋值(初始化时不能多重赋值)x=y=z=0;28输出输出printfC 语言的输入输出函数包含在头文件语言的输入输出函数包含在头文件 “stdio.h” 中中n 输入输入/输出三要素:输出三要素:对象对象( (数据数据) )、格式、设备、格式、设备n 输出输出函数:函数:printfl 格式控制字符串:格式控制字符串:格式字符串
24、格式字符串转义字符转义字符普通字符串普通字符串printf(“格式控制字符串格式控制字符串”,输出表列,输出表列); 格式字符串:以格式字符串:以“”开头,后面跟各种开头,后面跟各种 格式字符格式字符 普通字符串:原样输出普通字符串:原样输出printf(“k=%d, a=%fn”,k, a);29格式字符串格式字符串% 标志标志输出最小宽度输出最小宽度.精度精度长度长度 类型类型 printf(pi= %-12.6lf, n, pi)以以 % 开头开头标志标志精度精度格式字符格式字符- :左对齐左对齐+ :输出符号输出符号空格空格、# 输出最小宽度输出最小宽度小数点后小数点后输出位数输出位数
25、长度长度30 %d、%o、%x、%X、%u ( 整数整数 ) %e (实数:采用科学计数法形式实数:采用科学计数法形式 ) %f (实数:采用浮点数形式实数:采用浮点数形式) %g ( 由系统自动选取上述两种格式之一由系统自动选取上述两种格式之一) %c ( 输出单个字符输出单个字符) %s ( 输出字符串输出字符串) l 转义字符转义字符n (换行换行) t (制表符制表符) b (退格退格) r (回车回车) f (走纸换页走纸换页) (单引号单引号) ” (双引号双引号) (反斜杆反斜杆) % (百分号百分号) a (响铃响铃 )格式字符串格式字符串% 标志标志输出最小宽度输出最小宽度.
26、精度精度长度长度 类型类型 例:例:example_printf.c31输输入入scanfn 输输入函数:入函数:scanfl 地址运算符为地址运算符为 “ & ”l 格式控制字符串只含格式控制字符串只含“格式字符串格式字符串”,一般格式为,一般格式为scanf(“格式控制字符串格式控制字符串”,地址表列,地址表列);scanf(“%d%f”,&k,&a);%*输入数据宽度输入数据宽度长度长度 类型类型 “* *” 表示跳过该输入值表示跳过该输入值 输入多个数据时,如果格式字符串之间没有间隔符,则输入输入多个数据时,如果格式字符串之间没有间隔符,则输入数据以空格或回车隔开;如果有间隔符,则用间
27、隔符隔开数据以空格或回车隔开;如果有间隔符,则用间隔符隔开scanf(“%d,%f”,&k,&a);32关系运算与逻辑运算关系运算与逻辑运算 n 关系运算符关系运算符 关系运算优先级低于算术运算,第一排高于第二排关系运算优先级低于算术运算,第一排高于第二排 运算结果为:运算结果为:真真 “1” 或或 假假 “0” = = !=n 逻辑运算符逻辑运算符 优先级:优先级:! 高于算术运算,高于算术运算,|低于低于&低于算术运算低于算术运算 运算结果为:运算结果为:真真 “1” 或或 假假 “0” 逻辑运算时,所有非零值均表示真逻辑运算时,所有非零值均表示真| & !33if 语句语句n if 语句
28、的三种形式语句的三种形式 表达式可以是任意表达式表达式可以是任意表达式 (关系、逻辑、赋值、算术等)(关系、逻辑、赋值、算术等) 语句可以是复合语句语句可以是复合语句 else if 中间必须要留空格中间必须要留空格 if 语句可以嵌套语句可以嵌套 else 可以省略可以省略if(表达式表达式) 语句语句;if(表达式表达式) 语句语句1;else 语句语句2;if(表达式表达式1) 语句语句1;else if(表达式表达式2) 语句语句2; else if(表达式表达式n) 语句语句n;else 语句语句n+1;34switch 语句语句n switch 语句的三种形式语句的三种形式执行过程
29、:执行过程:先计算先计算表达式表达式的值,的值,并逐个与并逐个与 case 后的常量相比较,后的常量相比较,当其与某个常量相等时,当其与某个常量相等时, 即执行即执行其后的语句,然后不再进行判断,其后的语句,然后不再进行判断,继续执行后面所有继续执行后面所有case后的语句后的语句。如表达式的值与所有如表达式的值与所有case 后的常后的常量表达式均不相同时,则执行量表达式均不相同时,则执行 default 后的语句后的语句switch(表达式表达式) case 常量常量1: 语句语句1; case 常量常量2: 语句语句2; case 常量常量n: 语句语句n; default : 语句语句
30、n+1; 表达式是对整数或字符作运算表达式是对整数或字符作运算 语句可以是复合语句语句可以是复合语句 switch 语句可以嵌套语句可以嵌套 通常每个语句后面要加通常每个语句后面要加 break35for 循环循环n for 语句语句for(表达式表达式1;表达式表达式2;表达式表达式3) 循环体循环体执行过程:执行过程: 1) 先求解表达式先求解表达式1 2) 求解表达式求解表达式2,若其值为真(非,若其值为真(非0),则执行),则执行循环体循环体中中的语句;的语句; 若其值为假(若其值为假(0),则结束循环),则结束循环 3) 计算解表达式计算解表达式3,并回到上面的第,并回到上面的第 2
31、) 步步 循环体可以是单个语句,也可以是复合语句循环体可以是单个语句,也可以是复合语句 表达式表达式1、2、3均可省略,但分号不能省均可省略,但分号不能省 3个表达式都省略时,构成无限循环个表达式都省略时,构成无限循环for(循环变量赋初值循环变量赋初值;循环条件循环条件;循环变量增量循环变量增量) 循环体循环体36while 循环循环n while 语句语句while(表达式表达式) 循环体循环体 循环体可以是单个语句,也可以是复合语句循环体可以是单个语句,也可以是复合语句n dowhile 语句语句do 循环体循环体 while(表达式表达式) 无论条件是否成立,至少执行一次循环无论条件是
32、否成立,至少执行一次循环37跳转语句跳转语句n break 语句语句l 跳出循环体跳出循环体n continue 语句语句l 跳过跳过本次本次循环中剩余的语句循环中剩余的语句,强行执行下一次循环强行执行下一次循环n return 语句语句l 从函数返回从函数返回l 函数的返回值通过函数的返回值通过 return 返回返回return 表达式表达式return(表达式表达式)38主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件39函数分类函数分类l 从函数定义的角度:库函数和用户定
33、义函数从函数定义的角度:库函数和用户定义函数l 从有无返回值角度:有返回值函数和无返回值函数从有无返回值角度:有返回值函数和无返回值函数l 从数据传送角度:无参函数和有参函数从数据传送角度:无参函数和有参函数n 函数分类函数分类数学函数、输入输出函数、字符串操作函数等数学函数、输入输出函数、字符串操作函数等n 库函数库函数参见课程主页参见课程主页40数学函数数学函数int abs(int i) double fabs(double x) long labs(long n) double exp(double x) double log(double x) double log10(double
34、 x) double pow(double x,double y) double pow10(int p) double sqrt(double x) double acos(double x) double asin(double x) double atan(double x) double cos(double x) double sin(double x) double tan(double x) double cosh(double x) double sinh(double x) double tanh(double x) double ceil(double x) double
35、floor(double x) int rand() double modf(double x,double *iptr) double fmod(double x,double y) l 头文件头文件 “math.h”l 编译时加编译时加 lm 选项选项l 更多函数参见课程主页更多函数参见课程主页例:例:example_math.c41函数的定义函数的定义n 函数的函数的一般一般定义形式定义形式类型标识符类型标识符 函数名函数名(形式参数列表形式参数列表) 声明部分声明部分 语句语句l 类型标识符指明了本函数的类型,即函数返回值的类型类型标识符指明了本函数的类型,即函数返回值的类型 l 形参
36、要指定数据类型,有多个形参时,用逗号隔开形参要指定数据类型,有多个形参时,用逗号隔开l 如果函数不带参数,则如果函数不带参数,则形式参数形式参数可以省略,但括号不能省可以省略,但括号不能省函数头函数头函数体函数体int max(int a, int b) if (ab) return a; else return b;例:例:42函数调用函数调用main() int max(int a, int b); int x,y,z; printf(input two numbers:n); scanf(%d%d,&x,&y); z=max(x,y); printf(maxmum=%d,z);int m
37、ax(int a, int b) if(ab) return a; else return b;例:例:example_fun1.c43形参与实参形参与实参n 函数的形参和实参函数的形参和实参l 形参只在被调用时才分配内存单元,调用结束即被释放形参只在被调用时才分配内存单元,调用结束即被释放l 形参只有在函数内部有效形参只有在函数内部有效 l 实参可以是常量、变量、表达式、函数等,但它们必须实参可以是常量、变量、表达式、函数等,但它们必须具有确定的值,以便把这些值传送给形参具有确定的值,以便把这些值传送给形参 l 实参和形参在数量上,类型上,顺序上应严格一致实参和形参在数量上,类型上,顺序上应
38、严格一致l 参数是变量时,传递的是参数是变量时,传递的是数值数值,即数据传递是单向的,即数据传递是单向的44数组参数数组参数n 数组作为函数参数数组作为函数参数l 数组的元素作为实参数组的元素作为实参l 数组名作为参数数组名作为参数 形参与实参的类型必须相同形参与实参的类型必须相同 函数调用时,传递的是数组的首地址(函数调用时,传递的是数组的首地址(地址传递地址传递) 形参与实参的长度可以不一致形参与实参的长度可以不一致 多维数组也可以作为函数的参数多维数组也可以作为函数的参数 在形参表中,可以不指定形参数组的长度,或用一个变量在形参表中,可以不指定形参数组的长度,或用一个变量来表示形参数组元
39、素的个数来表示形参数组元素的个数void nzp(int a);void nzp(int a, int n);void nzp(int A5, int m);45函数返回值函数返回值n 函数的函数的返回值(函数值)返回值(函数值)l 返回值只能通过返回值只能通过 return 语句返回主调函数语句返回主调函数l 函数中允许有多个函数中允许有多个 return 语句,语句, 但每次调用只能有一个但每次调用只能有一个return 语句被执行语句被执行l 返回值的类型和函数定义时的类型应一致,返回值的类型和函数定义时的类型应一致, 否则以函数定义时的类型为准,自动进行类型转换否则以函数定义时的类型为
40、准,自动进行类型转换l 如果返回值为整型,在函数定义时可以省去类型说明如果返回值为整型,在函数定义时可以省去类型说明l 没有返回值的函数,可以定义为没有返回值的函数,可以定义为“空类型空类型”(void)46函数调用函数调用n 函数函数调用调用的的一般形式一般形式函数名函数名(实参列表实参列表)n 函数函数调用调用的的方式方式l 函数表达式函数表达式l 函数语句函数语句l 函数实参函数实参z=max(x,y);scanf(%d,&a);printf(%d,max(x,y);47函数调用函数调用l 如果被调函数是整型或字符型时,可以不作说明如果被调函数是整型或字符型时,可以不作说明l 当被调函数
41、定义在主调函数之前时,可以不作说明当被调函数定义在主调函数之前时,可以不作说明l 库函数不需作说明,但必须包含该函数所在的头文件库函数不需作说明,但必须包含该函数所在的头文件类型标识符类型标识符 被调函数名被调函数名(类型类型 形参,类型形参,类型 形参,形参, )类型标识符类型标识符 被调函数名被调函数名(类型,类型,类型,类型, )n 函数调用前需声明函数调用前需声明可以在所有函数定义之前,在函数外预先说明各个函数可以在所有函数定义之前,在函数外预先说明各个函数的类型,则在以后的调用中,不需要作说明的类型,则在以后的调用中,不需要作说明48函数调用函数调用n 函数函数可以嵌套可以嵌套调用调
42、用n 函数可以递归调用函数可以递归调用49局部变量局部变量l 在函数内作定义说明,作用域仅限于该函数内在函数内作定义说明,作用域仅限于该函数内l 主函数中定义的变量也主函数中定义的变量也只能在主函数中使用只能在主函数中使用l 主函数中也不能使用其它函数中定义的变量主函数中也不能使用其它函数中定义的变量l 形参是被调函数的局部变量,实参是主调函数的局部变量形参是被调函数的局部变量,实参是主调函数的局部变量l 在不同函数中可定义相同的变量名,在不同函数中可定义相同的变量名, 但它们代表的是不同的对象,分配不同的内存单元但它们代表的是不同的对象,分配不同的内存单元l 复合语句中也可定义变量,其作用域
43、只在复合语句范围内复合语句中也可定义变量,其作用域只在复合语句范围内n 局部变量(内部变量)局部变量(内部变量)根据作用域的不同,变量可分为根据作用域的不同,变量可分为全局变量全局变量与与局部变量局部变量50全局变量全局变量l 在函数外部定义的变量,其作用域是整个源程序在函数外部定义的变量,其作用域是整个源程序l 在函数中使用全局变量,一般应作全局变量说明在函数中使用全局变量,一般应作全局变量说明 (extern)l 在函数之前定义的全局变量,可不作说明在函数之前定义的全局变量,可不作说明l 如果外部变量与局部变量同名,则使用局部变量如果外部变量与局部变量同名,则使用局部变量n 全局变量(外部
44、变量)全局变量(外部变量)51变量存储类别变量存储类别l 动态存储,函数调用结束后即被释放动态存储,函数调用结束后即被释放l 所有的局部变量所有的局部变量缺省为自动变量缺省为自动变量n 自动变量(自动变量(auto)变量的存储方式有:变量的存储方式有:动态存储动态存储与与静态存储静态存储l 静态存储,函数调用后不释放,保留原来的值静态存储,函数调用后不释放,保留原来的值l 静态局部变量在编译时赋初值,即只赋初值一次静态局部变量在编译时赋初值,即只赋初值一次l 若没有赋初值,静态局部变量的值为若没有赋初值,静态局部变量的值为0或空字符;或空字符; 而自动变量的值不定而自动变量的值不定n 静态局部
45、变量(关键字:静态局部变量(关键字:static)l 将局部变量存放在将局部变量存放在CPU的寄存器中,提供执行效率的寄存器中,提供执行效率l 只有自动变量可作为寄存器变量,存放个数有限只有自动变量可作为寄存器变量,存放个数有限n 寄存器变量寄存器变量(关键字:(关键字:register)52主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件53指针指针l 指针极大地丰富了指针极大地丰富了C语言的功能语言的功能l 运用指针编程是运用指针编程是C语言最主要的风格之一语言最主要的风格之
46、一l 运用指针可以很方便地使用数组和字符串运用指针可以很方便地使用数组和字符串l 指针能使指针能使C语言象汇编语言一样处理内存地址,提高效率语言象汇编语言一样处理内存地址,提高效率l 指针是指针是C语言中最重要的一环,也是最为困难的一部分语言中最重要的一环,也是最为困难的一部分l 能否正确理解和使用指针是掌握能否正确理解和使用指针是掌握C语言的一个标志语言的一个标志54指针定义与引用指针定义与引用l 用来用来存放某个变量的地址存放某个变量的地址的变量称为指针变量,的变量称为指针变量, 通常称为指向该变量的指针通常称为指向该变量的指针l 指针变量的定义指针变量的定义n 指针变量(指针)指针变量(
47、指针)类型标识符类型标识符 *指针变量名指针变量名; 指针的类型是该指针所指向的变量的数据类型指针的类型是该指针所指向的变量的数据类型n 指针变量的引用指针变量的引用& :取地址运算符:取地址运算符* :指针运算符(或称:指针运算符(或称“间接访问间接访问” 运算符)运算符)a=3; p=&a; *p=5;55指针运算指针运算n 指针作为函数参数:指针作为函数参数:传递变量的地址传递变量的地址n 指针运算指针运算l 赋值运算赋值运算int a,*pa,b5,*pb;pa=&a; pb=b;int a,*pa=&a,b5,*pb=b;l 加减运算:加减运算:主要针对指向数组的指针变量主要针对指向
48、数组的指针变量int b5,*pb0=b,*pb3;pb3=pb0+3;n 空指针:空指针:值为值为 0 的指针变量的指针变量例:例:example_pointer1.c例:例:example_pointer2.c56数组指针数组指针l C语言中,数组名代表该数组所在的内存单元的首地址语言中,数组名代表该数组所在的内存单元的首地址l 数组元素的引用方式:下标法、指针法数组元素的引用方式:下标法、指针法n 指向一维数组的指针变量指向一维数组的指针变量l 数组名作为函数参数:传递数组名作为函数参数:传递数组的首地址数组的首地址*pb=b; b3; *(pb+3); *(b+3);n 指向二维数组的
49、指针变量指向二维数组的指针变量l 二维数组的数组名代表整个数组的首地址二维数组的数组名代表整个数组的首地址l 二维数组可分解为多个一维数组来处理二维数组可分解为多个一维数组来处理int a34;a; a0; *a; &a00;a+1; a1; &a1;例:例:example_pointer3.c57数组指针数组指针n 指向二维数组的指针变量指向二维数组的指针变量int (*p)4, A34; p=a;类型标识符类型标识符 (*指针变量名指针变量名)长度长度;(*p+i)+j&Aij数组的列数数组的列数例:例:example_pointer4.c58字符串指针字符串指针n 指向字符串的指针变量指
50、向字符串的指针变量l 访问字符串的两种方式:字符数组、字符串指针访问字符串的两种方式:字符数组、字符串指针l 字符串指针的定义与普通变量指针定义一样,但赋值不一样字符串指针的定义与普通变量指针定义一样,但赋值不一样char c,*p=&c;char *s=Hello world;char *ps; ps=Hello world;l 字符串指针变量与字符数组的区别字符串指针变量与字符数组的区别 赋值不一样赋值不一样char *ps, str20; ps=Hello world;str=Hello world;59函数指针等函数指针等n 指向函数入口的指针变量指向函数入口的指针变量略(详见讲义或参
51、考书籍)略(详见讲义或参考书籍)类型标识符类型标识符 (*指针变量名指针变量名)();n 指针型函数指针型函数(略)(略)n 指针数组和指向指针的指针指针数组和指向指针的指针(略)(略)n main函数的参数函数的参数main (int argc, char *argv);60主要内容主要内容q C语言概述语言概述 q 数据结构数据结构q 程序设计流程(顺序、选择、循环)程序设计流程(顺序、选择、循环)q 函数函数q 指针指针q 文件文件61文件操作文件操作n 文件指针文件指针n 文件的关闭文件的关闭fclose(文件指针名文件指针名)FILE *指针变量名指针变量名;n 文件打开文件打开文件
52、指针名文件指针名=fopen(文件名文件名, 使用文件方式使用文件方式); 文件名为字符串文件名为字符串 打开方式有:打开方式有:(r为读,为读,w为写,为读写,为写,为读写,t为文本,为文本,b为二进制为二进制rt、wt、at、rb、wb、ab、rt+、wt+、at+、rb+、wb+、ab+62文件读写文件读写n 文件的读写(文件的读写(stdio.h)l 字符读写函数:字符读写函数:fgetc 和和 fputcl 字符串读写函数:字符串读写函数:fgets 和和 fputsl 数据块读写函数:数据块读写函数:freed 和和 fwritel 格式化读写函数:格式化读写函数:fscanf 和
53、和 fprinf略(详见讲义或参考书籍)略(详见讲义或参考书籍)63其它其它n 预处理命令预处理命令l 包含头文件包含头文件:#includel 宏定义宏定义:#define#define N 100#define f(x) (x*x+3*x)#include #include “math.h”l 条件编译指令条件编译指令: #if、#else、#endif #ifdef、#ifndef64计时函数计时函数n clock(time.h)n time(time.h)double x;x = clock()/CLOCKS_PER_SEC; /* 需要计时的程序片段需要计时的程序片段 */ x =
54、clock()/CLOCKS_PER_SEC - x;time_t t0, t1;double t;t0=time(NULL); /* 需要计时的程序片段需要计时的程序片段 */ t1=time(NULL);t=difftime(t1,t0);例:例:example_time.c65上机作业上机作业(1) 比较三种矩阵相乘的计算效率比较三种矩阵相乘的计算效率取取 m=n=L=1024, 每种算法计算每种算法计算20次,统计总的运算时间次,统计总的运算时间算法一:算法一:i-j-k 循环循环for(i=0; im; i+) for(j=0; jn; j+) for(k=0; kL; k+) Ci
55、j=Cij+Aik*Bkj; C=A mn BnLfor(j=0; jn; j+) for(k=0; kL; k+) for(i=0; im; i+) Cij=Cij+Aik*Bkj; 算法二:算法二:j-k-i 循环循环for(i=0; im; i+) for(k=0; kL; k+) for(j=0; jn; j+) Cij=Cij+Aik*Bkj; 算法三:算法三:i-k-j 循环循环66上机作业上机作业l 迭代初始向量取零向量迭代初始向量取零向量l 最大迭代步数设为最大迭代步数设为 1000 次次l 相对残量误差精度设为相对残量误差精度设为 10-6(2) 用用 Jacobi 和和 GS 迭代算法解线性方程组迭代算法解线性方程组 Ax = b, 其中其中67