内容正文:
<<C语言程序设计>> 课程
第7章 函数的使用
Page 1
<<C语言程序设计>>
主要内容
1 为什么使用函数
2 函数的基本使用
3 函数递归调用
4 用带参数的宏定义代替公式型函数
5 函数和变量的作用域及存储类型
Page 1
<<C语言程序设计>>
问题引入
实际编程中,有些通用性的功能在C语言中并没有提供库函数,比如数组排序、判断整数奇偶性等。象这些具有独立功能的程序段如果能单独写成一个函数,可以增强了程序代码的复用性,有利于分工合作,提高程序设计效率。
数学函数sqrt()、字符串处理函数strlen() 等。这些具有通用功能的函数称之为标准库函数,是由C语言开发环境提供,标准库函数给编程带来了极大的方便。
单击此处编辑母版文本样式
第二级
第三级
第四级
第五级
Page 1
<<C语言程序设计>>
为什么使用函数-模块化的程序设计
main()函数 scanf()函数
printf()函数 pow()函数 sqrt()函数
各种自定义函数
电脑模块化组装
模块化程序
Page 1
<<C语言程序设计>>
7.1 为什么使用函数
【例7-1】打印输出如下所示超市购物小票的票头
某某超市欢迎您
******************************
分析
1、第一行为欢迎词,自定义一个函数print_welcome来实现欢迎词的输出功能
2、第二行为一定数量的“*”号,自定义一个函数print_star来实现 “*”号的输出功能
单击此处编辑母版文本样式
第二级
第三级
第四级
第五级
Page 1
<<C语言程序设计>>
#include <stdio.h>
void print_welcome();//声明print_ welcome函数
void print_star(int n); //声明print_star函数
void main()
{
print_welcome(); //调用自定义函数
print_star(30);
}
参考代码
7.1 为什么使用函数
Page 1
<<C语言程序设计>>
void print_welcome() //定义print_welcome函数
{ printf("
某某超市欢迎您
");
}
void print_star(int n) //定义print_star函数,n值为'*'号的数量
{ int i;
for( i=0;i<n;i++)
putchar('*');
}
参考代码
7.1 为什么使用函数
Page 1
<<C语言程序设计>>
7.1 为什么使用函数
程序中自定义两个函数print_welcome和print_star,这两个函数通过调用库函数printf完成输出功能,最后主函数通过调用这两个自定义函数实现了超市购物小票的票头的打印。
Page 1
<<C语言程序设计>>
7.1 为什么使用函数
说明:一个源程序文件由一个或多个函数组成。C程序的执行从主函数main开始,主函数通过调用其他函数完成相关任务,其他函数的地位是平等的,可根据需要相互调用。
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
int max(int x,int y)
{ int z;
if(x>y) z=x;
esle z=y;
return z; }
1、函数定义的形式
返回值类型 函数名(参数表)
{函数体语句;}
无返回值的函数,类型为void
省略不写的函数返回类型为int
返回值类型
函数首部
函数体
参数表
定义函数操作数据的类型与个数
每个参数都包含类型说明
称为形式参数(形参)
函数体
以{开始,以}结束
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
void型函数没有返回值
非void型函数,用return语句返回函数值
函数返回值
return语句的格式
return 表达式 ;
如果声明的函数返回值类型和return语句中的返回值类型不一致,则以声明的为准。
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
变量必须先声明,后使用,函数也是一样,调用函数前,必须有函数的声明部分,作用是把有关函数的信息(函数名、函数类型、函数参数的个数与类型)通知编译系统,以便编译系统检查被调用函数是否正确存在。
注:如果不写函数声明,必须保证函数的定义出现在调用之前。
2 、函数的声明
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
1、库函数的声明:在源程序的开始位置包含对应的库函数头文件。
2、自定义函数的声明:函数首部取出来,再加上一个“;”即可。函数首部也称为函数原型,在函数声明中形参变量名可以省略不写,而只写形参的类型。
函数的声明的方法
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
#include "stdio.h"
void main( )
{ float a,b,c;
scanf("%f%f",&a,&b);
c=add(a,b);
printf("%f",c);
}
float add(float x,float y)
{ float z;
z=x+y;
return (z);
}
Page 1
<<C语言程序设计>>
7.2 函数的基本使用
#include "stdio.h"
void main( )
{ float a,b,c;
float add(float x,float y); /*函数声明*/
scanf("%f%f",&a,&b);
c=add(a,b);
printf("%f",c);
}
float add(float x,float y)
{float z;
z=x+y;
return (z);}
Page 1
<<C语言程序设计>>
7.3 函数的调用
函数调用时,要以某种方式将实参传递给形参,以完成对实参的特定操作,实参传递给形参的过程称为参数传递。
实参和形参
形参
实参
调用函数时给定的参数,实参可以是常量,变量,表达式,但必须有确定的值。
声明函数时指定的参数。
Page 1
<<C语言程序设计>>
7.3 函数的调用
函数声明完毕后,在程序中具体的使用函数称为函数的调用。对于有参函数,函数调用时参数表中要提供具体的数据,以完成对具体数据的特定的操作。
float add(float x,float y)
{float z;
z=x+y;
return z;}
main()
{
float sum=add(1.0,2.0);
}
形式参数
实际参数
Page 1
<<C语言程序设计>>
7.3 函数的调用
函数调用的形式
函数名(参数表)
main( )
{ int a=1,b=3,c;
c=max(a,b);
printf("max=%d",c); }
函数调用
对实参的要求
实参个数和形参个数相等。
实参的类型要和形参的类型一致。
被调用函数无形参,实参表是空的,但括号不能省略。
Page 1
<<C语言程序设计>>
7.3 函数的调用
【随堂练习】编写求阶乘的函数,主函数中调用该函数求某
一个自然数的阶乘。
函数
传入n
得到n!
类型 函数名(参数表)
{函数体语句;}
Page 1
<<C语言程序设计>>
#include <stdio.h>
int jie(int a)
{ int n=1, i;
for(i=1;i<=a;i++)
n=n*i;
return n;
}
void main()
{int result,a;
printf("请输入一个数字
");
scanf("%d",&a);
printf("result=%d",jie(a));
}
参考代码
Page 1
<<C语言程序设计>>
7.3 函数的调用
【随堂练习】编写求阶乘的函数,主函数中调用该函数求某
一个自然数的阶乘。
jie(4)
jie(3)*4
jie(2)*3*4
jie(1)*2*3*4
如果n==1,则jie(1)=1
如果n>1,则jie(n)=jie(n-1)*n
Page 1
<<C语言程序设计>>
int jie(int a)
{ if(a==1)
return 1;
else
return jie(a-1)*a;
}
void main()
{int result,a;
printf("please input a number
");
scanf("%d",&a);
printf("result=%d",jie(a));
}
参考代码
Page 1
<<C语言程序设计>>
7.3 函数的调用
在调用一个函数的过程中又直接或间接地调用该函数本身,称为函数的递归(recursive)调用。
程序中不应出现无终止的递归调用,一般递归函数函数体中都用if语句来控制,只要达到某一条件,函数就获得某一具体的值而停止递归调用。
Page 1
<<C语言程序设计>>
7.4 带参数的宏
带参宏定义的一般形式为:
#define 宏名(形参列表) 字符串
一般形式为:
宏名(实参表);
#include <stdio.h>
#define MAX(x,y) x>y?x:y //用带参数的宏void main()
{
int a,b,c;
printf("请输入两个整数:");
scanf("%d%d",&a,&b);
c=MAX(a,b);
printf("最大值为:%d.
",c);
}
Page 1
<<C语言程序设计>>
7.4 带参数的宏
说明:
1、宏名一般用大写字母表示。
2、形参不分配内存单元,因此不必作类型定义。
3、宏调用中的实参可以是常量、变量或表达式,但必须有具体的值。
4、在宏调用时, “先原样替换,然后再计算”。
#define MAX(x,y) x>y?x:y
Page 1
<<C语言程序设计>>
7.4 带参数的宏
【例7-10】用带参数的宏定义计算圆的周长。
#include <stdio.h>
#define PI 3.14
#define L(r) 2*PI*r //参数r为圆的半径
void main()
{
double r,c;
printf("请输入圆的半径:");
scanf("%lf",&r);
c=L(r);
printf("圆的周长为:%.2lf.
",c);
}
Page 1
<<C语言程序设计>>
注意带参宏的二义性
#include <stdio.h>
#define PI 3.14
#define L(r) 2*PI*r //参数r为圆的半径
void main()
{
double r,c;
printf("请输入圆的半径:");
scanf("%lf",&r);
c=L(r);
printf("圆的周长为:%.2lf.
",c);
}
如实参是一个表达式,如:c=L(r+2);,实参r+2替换形参r后,赋值表达式就变成了c=2*PI*r+2;,这显然与原意图不符,所以在宏定义书写时,应在字符串中的形参外加一个括号,即:#define L(r) 2*PI*(r) 。
Page 1
<<C语言程序设计>>
7.5 函数和变量的作用域
函数的作用域是指可使用该函数的程序范围。只能被本文件中其他函数调用的函数称为内部函数,内部函数也称为静态函数,用关键字static来声明。可供其他文件调用的函数称为外部函数,用关键字extern来声明。
[extern/ static] 函数返回值类型 函数名(形式参数列表)
{ 函数体;
}
缺省为extern
Page 1
<<C语言程序设计>>
7.5 函数和变量的作用域
变量的使用范围就称为变量的作用域,按照作用域的范围不同,可分为两种——局部变量和全局变量。
1.局部变量
局部变量也称为内部变量。局部变量是在函数内定义并使用。
2.全局变量
全局变量也称为外部变量,它是在函数外部定义的变量,其作用域是整个源程序文件。
Page 1
<<C语言程序设计>>
#include <stdio.h>
double max; //定义全局变量,最高分max
double a[10]; //定义全局变量
void array_max(int n) //求最高分
{ max=a[0];
for(int i=1;i<n;i++)
if(max<a[i])
max=a[i];}
void main()
{ for(int i=0;i<10;i++)
scanf("%lf",&a[i]);
array_max(10); //函数调用
printf("最高分为:%.2lf.
",max);
}
【例7-11】输入10个学生的成绩,求出最高分。
Page 1
<<C语言程序设计>>
课程小结:我们学习了什么?
为什么要使用函数
函数的基本使用 (定义、声明与调用)
函数递归调用
带参数的宏
函数和变量的作用域
Page 1
<<C语言程序设计>>
<<C语言程序设计>>
Page 1
<<C语言程序设计>>
$$