函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之

Slides:



Advertisements
Similar presentations
《C语言程序设计》复习
Advertisements

親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
计算学科的基本问题 本章首先介绍一个对问题进行抽象的典型实例——哥尼斯堡七桥问题。然后,通过“梵天塔”问题和“停机问题”分别介绍学科中的可计算问题和不可计算问题。从“梵天塔”问题再引出算法复杂性中的难解性问题、P类问题和NP类问题,证比求易算法,P=NP是否成立的问题。
C 语言程序设计 西北大学 信息学院 计算机文化基础课教学课件.
第一章 C语言概述 计算机公共教学部.
C语言基础——指针的高级应用 Week 05.
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
第4章 选择结构程序设计 在现实生活中,需要进行判断和选择的情况是很多的 如果你在家,我去拜访你 如果考试不及格,要补考
C语言程序设计 第八章 函数.
Introduction to the C Programming Language
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
C语言程序设计 第五章 选择结构程序设计.
C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
第一章 C语言概述.
由C程序结构所知,一个完整的C语言程序是由一个且只能有一个main()函数(又称主函数)和若干个其他函数组合而成的。而前面各章仅学习main()函数的编程,本章将介绍其他函数的编程,包括其他函数的定义、调用、参数传递及变量的作用域等。
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
選擇排序法 通訊一甲 B 楊穎穆.
第3章 顺序结构程序设计 本章要点: 格式化输出函数──printf() 格式输入函数——scanf() 字符输出函数——putchar()
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
目录 10.1 指针的基本概念 10.2 指向变量的指针变量 10.3 指向数组的指针变量 10.4 指向函数的指针变量和指针型函数
第4章 选择结构程序设计 4.1 选择结构和条件判断 4.2 用if语句实现选择结构 4.3关系运算符和关系表达式
项目六 用指针优化学生成绩排名 项目要求 项目分析
第五章 选择结构程序设计 一、关系运算符和表达式 1、关系运算符 在程序中经常需要比较两个量的大小关系, 以决定程序下一步
Introduction to the C Programming Language
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
C语言程序设计 李祥.
第八章 函数.
第8章 善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
第6章 函数 学习的意义.
算法的基本概念.
C语言 程序设计基础与试验 刘新国、2012年秋.
第八章 使用指针.
谭浩强 编著 中国高等院校计算机基础教育课程体系规划教材 C++程序设计.
第七章 函数 西安工程大学.
第十章 指针.
第5讲 结构化程序设计(Part II) 周水庚 2018年10月11日.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
数组 梁春燕 华电信息管理教研室.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
六、函数 教学目标: 函数的概念、定义、调用和返回 带自定义函数的程序设计 递推算法 递归思想及算法实现 函数的参数传递方式 C语言程序设计.
第8章 函数 函数参数和函数的值 概述 函数定义的一般形式 函数的调用(嵌套调用、递归调用) 数组作为函数参数
目录 9.1 结构体类型 9.2 共用体类型 9.3 枚举类型 9.4 类型声明符typedef 1.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
C语言复习3----指针.
C语言复习2----函数.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
1.2 C语言程序的结构与书写规则 一、 C语言程序的总体结构
C程序设计.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
C程序设计.
第5章 函 数.
第一章 C语言概述 教师:周芸.
C语言程序设计 李祥 QQ:
第九章 指针.
第2章 数据类型、运算符与表达式 本章要点: 基本数据类型 常量和变量 算术运算符和算术表达式 关系运算符和关系表达式
第二章 类型、对象、运算符和表达式.
习 题 课(作业).
本节内容 函数嵌套调用的内存布局 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第四章 函数 丘志杰 电子科技大学 计算机学院 软件学院.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第三章 高级函数特性.
第九章 指针 C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
C程序设计 复习 1、计算机系统的组成 外部设备:输入、输出设备(同人打交道《十进制》)
Presentation transcript:

函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之 各模块相对独立、功能单一、结构清晰、接口简单 控制了程序设计的复杂性 提高元件的可靠性 缩短开发周期 避免程序开发的重复劳动 易于维护和功能扩充 开发方法: 自上向下,逐步分解,分而治之 使每一个模块成为相对独立、功能单一、结构清晰、接口简单、容易理解的程序 每个模块可以独立设计算法,单独编写和测试 一个模块中的错误不易扩散和蔓延到其它模块, 众人可同时进行集体性开发 软件具有模块结构,软件开发工作如同搭积木,一个模块可以在不同程序中多次使用

C是模块化程序设计语言 C程序结构 C是函数式语言 必须有且只能有一个名为main的主函数 C程序的执行总是从main函数开始,在main中结束 函数不能嵌套定义,可以嵌套调用

函数分类 从用户角度 从函数形式 使用库函数应注意: 1、函数功能 2、函数参数的数目和顺序,及各参数意义和类型 3、函数返回值意义和类型 标准函数(库函数):由系统提供 用户自定义函数 从函数形式 无参函数 有参函数 使用库函数应注意: 1、函数功能 2、函数参数的数目和顺序,及各参数意义和类型 3、函数返回值意义和类型 4、需要使用的包含文件

函数的定义 一般格式 现代风格: 函数返回值类型 缺省int型 无返回值void 合法标识符 函数类型 函数名(形参类型说明表) { 函数类型 函数名(形参类型说明表) { 说明部分 语句部分 } 现代风格: 函数体 例 有参函数(现代风格) int max(int x, y) { int z; z=x>y?x:y; return(z); } 例 有参函数(现代风格) int max(int x,int y) { int z; z=x>y?x:y; return(z); } 例 无参函数 printstar( ) { printf(“**********\n”); } 或 printstar(void ) 例 空函数 dummy( ) { } 函数体为空

传统风格: 函数类型 函数名(形参表) 形参类型说明 { 说明部分 语句部分 } 例 有参函数(传统风格) int max(x,y) 函数类型 函数名(形参表) 形参类型说明 { 说明部分 语句部分 } 传统风格: 例 有参函数(传统风格) int max(x,y) int x,y; { int z; z=x>y?x:y; return(z); }

函数的返回值 返回语句 例 无返回值函数 void swap(int x,int y ) { int temp; 例 无返回值函数 void swap(int x,int y ) { int temp; temp=x; x=y; y=temp; } 函数的返回值 返回语句 形式: return(表达式); 或 return 表达式; 或 return; 功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数 说明: 函数中可有多个return语句 若无return语句,遇}时,自动返回调用函数 void型函数

函数的调用 调用形式 函数名(实参表); 说明: 实参与形参个数相等,类型一致,按顺序一一对应 实参表求值顺序,因系统而定(自右向左)

例 参数求值顺序 main() { int i=2,p; p=f(i,++i); printf("%d",p); } int f(int a, int b) { int c; if(a>b) c=1; else if(a==b) c=0; else c=-1; return(c); main() { int i=2,p; p=f(i, i++); printf("%d",p); } int f(int a, int b) { int c; if(a>b) c=1; else if(a==b) c=0; else c=-1; return(c); 运行结果:0 运行结果:1

调用方式 函数语句: 例 printstar(); printf(“Hello,World!\n”); 函数表达式: 例 m=max(a,b)*2; 函数参数: 例 printf(“%d”,max(a,b)); m=max(a,max(b,c));

函数说明 对被调用函数要求: 必须是已存在的函数 库函数: #include <*.h> 用户自定义函数: 函数类型说明 一般形式: 函数类型 函数名(形参类型 [形参名],….. ); 或 函数类型 函数名(); 作用:告诉编译系统函数类型、参数个数及类型,以便检验 函数定义与函数说明不同 函数说明位置:程序的数据说明部分(函数内或外) 被调用函数定义出现在主调函数之前可不作函数说明

例 函数说明举例 main() { float add(float,float); /*function declaration*/ float a,b,c; scanf("%f,%f",&a,&b); c=add(a,b); printf("sum is %f",c); } float add(float x, float y) { float z; z=x+y; return(z); float add(float x, float y) { float z; z=x+y; return(z); } main() { float a,b,c; scanf("%f,%f",&a,&b); c=add(a,b); printf("sum is %f",c);

形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式 函数参数及其传递方式 形参与实参 形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式 例 比较两个数并输出大者 main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("Max is %d",c); } max(int x, int y) { int z; z=x>y?x:y; return(z); c=max(a,b); (main 函数) (max 函数) max(int x, int y) { int z; z=x>y?x:y; return(z); } 实参 形参

说明: 实参必须有确定的值 形参必须指定类型 形参与实参类型一致,个数相同 若形参与实参类型不一致,自动按形参类型转换———函数调用转换 形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

x 例 计算x的立方 a #include <stdio.h> product float cube(float x) ×× 1.2 1.2 #include <stdio.h> float cube(float x) { return(x*x*x); } main() { float a, product; printf("Please input value of a:"); scanf("%f",&a); product=cube(a); printf(”Cube of %.4f is %.4f\n",a,product); 1.728 x

参数传递方式 值传递方式 方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值 特点: 形参与实参占用不同的内存单元 单向传递

#include <stdio.h> main() { int x=7,y=11; 例 交换两个数 7 11 x: y: 调用前: #include <stdio.h> main() { int x=7,y=11; printf("x=%d,\ty=%d\n",x,y); printf("swapped:\n"); swap(x,y); } swap(int a,int b) { int temp; temp=a; a=b; b=temp; 调用: 7 11 a: b: x: y: swap: 7 11 x: y: a: b: temp 调用结束: 7 11 x: y:

地址传递 方式:函数调用时,将数据的存储地址作为参数传递给形参 特点: 形参与实参占用同样的存储单元 “双向”传递 实参和形参必须是地址常量或变量

printf(“a=%d,b=%d\n”,a,b); printf(“swapped:\n”); swap(&a,&b); 例 交换两个数 a 5 9 b 调前: swap(p1,p2) int *p1,*p2; { int p; p=*p1; *p1=*p2; *p2=p; } main() { int a,b; scanf("%d,%d",&a,&b); printf(“a=%d,b=%d\n”,a,b); printf(“swapped:\n”); swap(&a,&b); printf(”a=%d,b=%d\n",a,b); a 5 9 b 调swap: p1 &a &b p2 a 9 5 b 交换: p1 &a &b p2 a 9 5 b 返回:

#include <stdio.h> long sum(int a, int b); long factorial(int n); main() { int n1,n2; long a; scanf("%d,%d",&n1,&n2); a=sum(n1,n2); printf("a=%1d",a); } long sum(int a,int b) { long c1,c2; c1=factorial(a); c2=factorial(b); return(c1+c2); long factorial(int n) { long rtn=1; int i; for(i=1;i<=n;i++) rtn*=i; return(rtn); 文件包含编译预处理命令 函数类型说明 long sum(int a, int b); long factorial(int n); 函数调用 实参 函数定义 形参 函数返回值 沈阳东软软件股份有限公司 NEU-APN IA事业部 (机密)

函数的嵌套与递归调用 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数 main( ) 调用函数a 结束 a函数 b函数 调用函数b         

#include <stdio.h> int dif(int x,int y,int z); 例 求三个数中最大数和最小数的差值 #include <stdio.h> int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z); void main() { int a,b,c,d; scanf("%d%d%d",&a,&b,&c); d=dif(a,b,c); printf("Max-Min=%d\n",d); } int dif(int x,int y,int z) { return max(x,y,z)-min(x,y,z); } int max(int x,int y,int z) { int r; r=x>y?x:y; return(r>z?r:z); } int min(int x,int y,int z) { int r; r=x<y?x:y; return(r<z?r:z); main( ) 调用函数dif 输出 结束 dif函数 max函数 调用函数max 调用函数min min函数

定义:函数直接或间接的调用自身叫函数的递归调用 int f1(int x) { int y,z; …… z=f2(y); ……. return(2*z); } int f2(int t) { int a,c; c=f1(a); return(3+c); int f(int x) { int y,z; …… z=f(y); ……. return(2*z); } f( ) 调f 调f2 调f1 f1( ) f2( ) C编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出

例 求n的阶乘 #include <stdio.h> int fac(int n) { int f; if(n<0) printf("n<0,data error!"); else if(n==0||n==1) f=1; else f=fac(n-1)*n; return(f); } main() { int n, y; printf("Input a integer number:"); scanf("%d",&n); y=fac(n); printf("%d! =%15d",n,y);

void move(char getone, char putone) { printf("%c--->%c\n",getone,putone); } void hanoi(int n,char one,char two,char three) { if(n==1) move(one,three); else { hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); } main() { int m; printf("Input the number of disks:"); scanf("%d",&m); printf("The steps to moving %3d disks:\n",m); hanoi(m,'A','B','C'); 例 Hanoi问题 A B C

数组作为函数参数 ---数组元素作函数实参——值传递 数组作为函数参数 ---数组元素作函数实参——值传递 #include <stdio.h> main() { int a[10],b[10],i,n=0,m=0,k=0; printf("Enter array a:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); printf("Enter array b:\n"); scanf("%d",&b[i]); { if(large(a[i],b[i])==1) n=n+1; else if(large(a[i],b[i])==0) m=m+1; else k=k+1; } int large(int x,int y) { int flag; if(x>y) flag=1; else if(x<y) flag=-1; else flag=0; return(flag); 例 两个数组大小比较 4 3 2 1 5 a 56 23 12 10 76 88 b 21 43 98 66 54 a和b为有10个元素的整型数组 比较两数组对应元素 变量n,m,k记录a[i]>b[i], a[i]==b[i], a[i]<b[i]的个数 最后 若n>k,认为数组a>b 若n<k,认为数组a<b 若n==k,认为数组a==b i n=0 m=0 k=1 i n=0 m=1 k=1 i n=1 m=1 k=1 i n=1 m=1 k=2 i n=2 m=1 k=2 i n=3 m=1 k=2 n=0 m=0 k=0

数组名作函数参数 地址传递 在主调函数与被调函数分别定义数组,且类型应一致 形参数组大小(多维数组第一维)可不指定 形参数组名是地址变量

#include <stdio.h> float average(int stu[10], int n); 例 求学生的平均成绩 #include <stdio.h> float average(int stu[10], int n); void main() { int score[10], i; float av; printf("Input 10 scores:\n"); for( i=0; i<10; i++ ) scanf("%d", &score[i]); av=average(score,10); printf("Average is:%.2f", av); } float average(int stu[10], int n) { int i; float av,total=0; for( i=0; i<n; i++ ) total += stu[i]; av = total/n; return av; } . 2 1 9 score 56 23 12 …. 88 stu 实参用数组名

#include <stdio.h> void swap2(int x,int y) { int z; z=x; x=y; y=z; } main() { int a[2]={1,2}; swap2(a[0],a[1]); printf("a[0]=%d\na[1]=%d\n",a[0],a[1]); 例 数组元素与 数组名 作函数参数比较 值传递 1 2 a 调用 a[0] a[1] x y 2 1 x y 交换 1 2 a 调用前 a[0] a[1] 1 2 a 返回

#include <stdio.h> void swap2(int x[]) { int z; z=x[0]; x[0]=x[1]; x[1]=z; } main() { int a[2]={1,2}; swap2(a); printf("a[0]=%d\na[1]=%d\n",a[0],a[1]); 例 数组元素与 数组名 作函数参数比较 地址传递 1 2 a 调用前 1 2 a x 调用 2 1 a x 交换 2 1 a 返回

a k array j j i=0 j k j k j j j j j void sort(int array[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; if(k!=i) { t=array[i]; array[i]=array[k]; array[k]=t; } main() { int a[10],i; for(i=0;i<10;i++) scanf("%d",&a[i]); sort(a,10); printf("%d ",a[i]); printf("\n"); 例 数组排序----简单选择排序 1 2 3 4 5 6 7 8 9 a 9 k array 49 68 57 32 9 99 27 13 76 88 j j i=0 j k 49 j k j j j j j

a array k j k i=1 j k j j j k j k j j void sort(int array[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; if(k!=i) { t=array[i]; array[i]=array[k]; array[k]=t; } main() { int a[10],i; for(i=0;i<10;i++) scanf("%d",&a[i]); sort(a,10); printf("%d ",a[i]); printf("\n"); 例 数组排序----简单选择排序 1 2 3 4 5 6 7 8 9 a 49 68 57 32 99 27 13 76 88 array 13 k j k i=1 j k j j j k 68 j k j j

a array i=8 例 数组排序----简单选择排序 main() { int a[10],i; 例 数组排序----简单选择排序 void sort(int array[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; if(k!=i) { t=array[i]; array[i]=array[k]; array[k]=t; } main() { int a[10],i; for(i=0;i<10;i++) scanf("%d",&a[i]); sort(a,10); printf("%d ",a[i]); printf("\n"); 1 2 3 4 5 6 7 8 9 a 13 27 32 49 57 68 76 88 99 array i=8

int max_value(int array[3][4]) { int i,j,k,max; max=array[0][0]; 例 求二维数组中最大元素值 1 3 5 7 2 4 6 8 15 17 34 12 i j max=1 int max_value(int array[3][4]) { int i,j,k,max; max=array[0][0]; for(i=0;i<3;i++) for(j=0;j<4;j++) if(array[i][j]>max) max=array[i][j]; return(max); } main() { int a[3][4]={{1,3,5,7}, {2,4,6,8},{15,17,34,12}}; printf("max value is %d\n",max_value(a)); 1 3 5 7 2 4 6 8 15 17 34 12 i j max=3 1 3 5 7 2 4 6 8 15 17 34 12 i j max=5 多维形参数组第一维维数 可省略,第二维必须相同  int array[][4] j 1 3 5 7 2 4 6 8 15 17 34 12 i max=7 j 1 3 5 7 2 4 6 8 15 17 34 12 i max=7 j 1 3 5 7 2 4 6 8 15 17 34 12 i max=34

get_sum_row(int x[][3], int result[] ,int row, int col) { int i,j; 例 求二维数组中各行元素之和 get_sum_row(int x[][3], int result[] ,int row, int col) { int i,j; for(i=0;i<row;i++) { result[i]=0; for(j=0;j<col;j++) result[i]+=x[i][j]; } main() { int a[2][3]={3,6,9,1,4,7}; int sum_row[2],row=2,col=3,i; get_sum_row(a,sum_row,row,col); printf("The sum of row[%d]=%d\n",i+1,sum_row[i]); x result 3 1 4 6 7 9 a sum_row 18 12