(共23张PPT)
函数
第九章
回顾
指针变量
指针运算符
指针与数组
内存分配
目标
掌握函数的结构
掌握函数声明和原型
按值传递 / 按地址传递
理解函数的作用域
掌握函数指针
函数
独立的程序段
执行一个具体的、明确定义的任务
易于编写、理解、调试和维护
将需要多次执行的一组指令定义为函数
函数的结构
type_specifier function_name ( arguments )
{
函数体
}
返回值的数据类型
有效的函数名
形式参数
函数的参数
#include
int squarer(int x);
main()
{
int i;
for(i =1; i <=10; i++)
printf("\nSquare of %d is %d ", i,squarer (i));
}
int squarer(int x)
{
int j;
j = x * x;
return(j);
}
形式参数
实际参数
从函数返回
int squarer(int x)
{
int j;
j = x * x;
return(j);
}
将控制权从函数传回主调程序
把 return 语句中的内容返回给主调程序
函数的数据类型
如果返回的是一个整型值或者没有返回值,可以省略类型标识符
为了避免出现不一致,最好指定数据类型
int squarer(int x)
{
int j;
j = x * x;
return(j);
}
调用函数
函数名后面必须有括号
一个函数只能返回一个值
程序可以有一个以上的函数
主调函数
被调函数
函数声明
在定义之前使用函数,必须声明
否则,一些编译器会返回错误
#include
main()
{
address();
}
address()
{
}
“隐式”声明
函数原型
指定参数的数据类型
如果调用时所使用的参数与原型的参数之间不一致,系统将报错
char abc(int x, int y);
abc(12);
变量
局部变量
在函数内部声明
进入一个程序块时创建,退出该程序块时销毁
形式参数
在函数定义中被声明为参数
在函数内部像局部变量一样使用
全局变量
在所有函数以外声明
在程序的整个执行期间都拥有值
存储类别 2-1
存储类别是变量的属性
存储类别定义了:
生命周期
保留特定值的时间长度
可见性
程序的哪些部分将能够“看见”该变量
存储类别 2-2
自动的(auto)
外部的(extern)
静态的(static)
寄存器的(register)
函数作用域规则
一块代码是否有权访问另一块代码或数据
函数内部的代码对该函数来说是私有或局部的
两个函数拥有不同的作用域但处于相同的级别
函数不能在其他函数以内定义
调用函数
按值传递
按地址传递
25
100#
25
100#
25
100
按值传递
变量的值被传递给被调函数,并且对这个值的任何改变都不会影响被传变量的原始值
默认情况下,函数参数都是按值传递的
参数值是通过临时变量传递的
所有操作都针对这些临时变量
按地址传递
允许函数访问内存位置
被调函数能够修改主调程序的参数的值
定义
getstr(char *ptr_str, int *ptr_int);
使用
getstr(pstr, &var);
函数调用的嵌套
main()
{
.
.
palindrome();
.
.
}
palindrome()
{
.
.
getstr();
reverse();
cmp();
.
.
}
多文件程序中的函数
函数可以定义成静态的或者外部的
静态函数只能在其程序文件内部被识别
static fn _type fn_name (argument list);
外部函数可以被程序的所有文件识别
extern fn_type fn_name (argument list);
函数指针
函数在内存中的物理位置-函数的入口点
void check(char *a,char *b,int (*cmp)())
{
printf("testing for equality \n");
if (!(*cmp)(a,b))
printf("Equal");
else
printf("Not Equal");
}
#include
#include
void check(char *a, char *b, int (*cmp)());
main()
{
char s1[80];
char s2[80];
int (*p)();
p = strcmp;
gets(s1);
gets(s2);
check(s1, s2, p);
}
总结
函数的结构
函数声明和函数原型
按值传递 / 按地址传递
函数的作用域规则
多文件程序中的函数
函数指针