1.为什么需要函数
①避免了重复性操作
②有利于程序的模块化
2.什么叫函数
逻辑上:能够完成特定功能的独立的代码单元
物理上:
①能接收数据(当然也能不接受)
②能够对接收的数据进行处理
③能够将数据处理的结果返回(当然也可以不返回任何值)
总结:函数是个工具,它是为了解决大量类似问题而设计的。函数可以当做一个黑盒。
3.如何定义函数
①格式:
函数返回值的类型 函数的名字(函数的形参列表)
{
函数的执行体
}
举例:
1 #include<stdio.h>
2
3 void max(int i,int j)
4 /*void表示这个函数没有返回值*/
5 /*max是函数名*/
6 /*i和j是形参(形式参数),函数中的变量叫形参*/
7 {
8 if(i>j)
9 printf("%d\n",i);
10 else
11 printf("%d\n",j);
12 }
13
14 int main() //程序先从主函数开始执行
15 {
16 int a,b,c,d,e,f;
17 scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
18
19 max(a,b);
20 /*程序把a的值发送给i,把b的值发送给j*/
21 /*然后程序跳到max内部执行*/
22 /*执行完以后,i和j的值会释放掉*/
23 max(c,d);
24 max(e,f);
25
26 return 0; //程序由主函数结束
27 }
②函数定义的本质:
详细描述函数之所以能够实现某一特定功能的具体实现方法
③return表达式的含义:
终止被调函数,向主调函数返回表达式的值。如果表达式为空,则只终止函数,不向主调函数返回任何值。
例子:
void f()
{
return; //只终止函数,不向被调函数返回任何值
}
int f()
{
return 10; //终止函数,并向主调函数返回10
}
int f()
{
//因为函数的类型是int
return 10.5; //所以最终返回的是10而非10.5
}
注意:break用于终止循环和switch,return用于终止函数
④函数的返回值
函数返回值的类型也称为函数的类型。如果函数名前的返回值类型和return表达式中表达式的类型不同的话,最终函数返回值的类型以函数名前的类型为准
例:
int f()
{
return 1.5; //因为函数的类型是int,所以函数f的返回值是1而不是1.5
}
4.函数的分类
①有参函数 和 无参函数
②有返回值函数 和 无返回值函数
③库函数 和 用户自定义函数
④值传递函数和地址传递函数
⑤普通函数 和 主函数(main函数)
注意:
一个程序有且只有一个主函数。
主函数可以调用普通函数,普通函数不能调用主函数。
普通函数可以相互调用。
主函数是程序的入口,也是程序的出口。
5.代码举例
①
1 //C_函数_分别比较a和b,c和d,e和f的值(方法二)
2 #include<stdio.h>
3
4 int max(int i,int j)
5 {
6 if(i>j) //找出较大值并返回
7 return i;
8 else
9 return j;
10 }
11
12 int main(void)
13 {
14 int a,b,c,d,e,f;
15 scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
16
17 printf("%d\n",max(a,b));
18 printf("%d\n",max(c,d));
19 printf("%d\n",max(e,f));
20
21 return 0;
22 }
②
1 //C_函数_判断一个数是否为素数
2 #include<stdio.h>
3
4 int IsPrime(int val)
5 {
6 int i;
7
8 if(val==2)
9 {
10 return 1;
11 }
12
13 for(i=2;i<=val;i++)
14 //若val能被i整除,则跳出循环,这样i始终小于val
15 //若val不能被i整除,则一直循环到i等于val
16 {
17 if(val%i==0)
18 break;
19 }
20
21 if(i==val)
22 return 1;
23 //若val不能被整除(即val是素数),则返回1
24 else
25 return 0;
26 //若val能被整除(即val是合数),则返回0
27 }
28
29 int main(void)
30 {
31 int val;
32 scanf("%d",&val);
33
34 if(IsPrime(val)) //调用函数判断输入的数是否为素数
35 printf("\n是素数\n");
36 else
37 printf("\n是合数\n");
38
39 return 0;
40 }
6.函数的声明
①函数声明的必要性:
程序从main函数进入,自上而下执行,如果不提前声明,编译器无法识别函数名(不知道那是一个函数名),就会报错。
所以函数声明的意义是告诉编译器即将可能出现的若干字母代表的是一个函数,以及该函数形参和返回值的具体情况
②格式
返回值的类型 函数的名字(函数的形参列表);
//函数声明是一个语句,所以分号不能少
注意:对库函数的声明是通过#include<库函数所在的文件的名字>来实现的
7.注意的问题
函数定义和函数调用的顺序(若调用放在定义的前面,则需要加函数声明)
8.函数的形参和实参
①形参,实参分别是什么
#include <stdio.h>
void f(int i) //i是形参
{
printf("%d",i);
}
int main()
{
f(5); //5是实参
return 0;
}
②形参与实参的关系
形参与实参个数相同,位置对应,数据类型必须相互兼容
9.函数的调用
当在一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:
1.将所有的实际参数,返回地址等信息传递给被调函数保存
2.为被调函数的局部变量(也包括形参)分配存储空间
3.将控制转移到被调函数的入口
从被调函数返回主调函数之前,系统也要完成三件事:
1.保存被调函数的返回结果
2.释放被调函数所占的存储空间
3.依照被调函数保存的返回地址将控制转移到调用函数
当有多个函数相互调用时,按照“后调用先返回”的原则,上述函数之间信息传递和控制转移必须借助”栈”来实现,即系统将整个程序运行
时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储
区,就行出栈操作,当前运行的函数永远都在栈顶位置
10.系统函数举例
double sqrt(double x);
求x的平方根
int abs(int i);
求i的绝对值
double fabs(double x);
求x的绝对值
……