一、函数的定义

C语言程序的框架有两种:
1、一个main()单框架
2、一个main()+多个子函数 复合框架
注意:
1、一个源程序文件可由一个或多个函数组成
2、一个C语言程序可以由多个或多个源程序文件组成
3、C程序执行总是从main()开始,结束于main();可调用其它函数
4、函数不能嵌套定义,但可以互相调用,不能调用main()
函数的分类
1、无参数函数和有参数函数
2、库函数和用户自定义函数+main()

函数返回值类型 函数名(形式参数列表)
{
声明语句;
函数体;
}
函数的参数
1、定义有参函数时,函数名后面括号中的变量名称为形式参数(简称”形参”)
2、如果含有多个参数,参数之间用逗号隔开
3、每个形参之前都要有类型名
4、在进行函数调用时,主调函数将赋予这些形式参数实际的值
5、函数也可以没有参数,但是在函数名后面的括号不可省略
6、形参可以在函数体中直接使用,但不能在函数体外使用
函数体可以没有语句,但不能没有花括号,函数名后必须有一对小括号
int max(int x,int y)
{ }

二、函数的返回

1、函数值通过return语句返回
2、return语句的语法格式:
return 表达式; 或者 return(表达式);
3、return语句中表达式的值就是函数值,此表达式的类型与函数首部所说明的函数值类型应保持一致
如果两者不一致,C编译程序将表达式的类型转换成函数值类型;
如果不能实现转换,则会出错

当程序执行到return语句时,程序退出该函数,
返回到主调函数中调用它的地方,并带回函数值(无参函数不带回函数值)

同一个函数内,根据需要可以在多处出现return语句。执行哪个return语句,该return语句起作用。
但不论函数体中有多少个return语句,return语句只会执行一次。
函数返回值类型:两类
形式1:
int fun(int x,int y)
{
return 表达式;
}
形式2:
void fun(int x)
{
一定不要加return语句;
}

三、函数的调用

总结值传递机制的处理过程:
1、函数调用前,形参不占内存单元。发生函数调用时,才会给形参分配内存单元。
2、函数调用时将实参变量的值传给形参变量。此时,实参和形参取相同的值,但是对应不同的内存单元。
3、执行被调用函数的功能。
4、在被函数中遇到return语句或函数的结束括号,函数调用结束,形参变量的内存单元被释放
5、程序执行流程返回主调函数中执行下一条语句。
函数调用:
两种方式
方式1:
非void型
变量名=函数名(实参列表);
方式2:
void型
函数名(实参列表);
函数调用过程
在进行函数调用时系统将实参值对应的(按位置次序对应)传给形参,
是一种值的单向传递。
实参与形参之间有一个关系。
单项传值遵循三一致:(个数,类型,位置次序)
QQ截图20210912193302.png
QQ截图20210912193345.png

四、函数的原型声明

原型声明
方式1:#include<头文件>
方式2:声明的格式:
函数类型 函数名(形参类型1 形参1,形参类型2 形参2…);
函数类型 函数名(形参类型1,形参类型2…);

五、函数的嵌套

C语言的函数定义是独立的,即在一个函数内不能定义另一个函数,即不能嵌套定义
可以嵌套调用函数,也就是说,在调用一个函数的过程中可以调用另一个函数。
QQ截图20210912194409.png

六、函数的递归

C语言函数直接或间接的调用自己,这种函数调用方式称为递归调用
QQ截图20210912194700.png
用递归的方法求阶乘n!

  1. # include <stdio.h>
  2. int main()
  3. {
  4. int rec(int n);
  5. int m,w;
  6. printf("Please input:m=");
  7. scanf("%d",&m);
  8. w=rec(m);
  9. printf("m!=%d\n",w);
  10. return 0;
  11. }
  12. int rec(int n)
  13. {
  14. int t;
  15. if(n==1)
  16. t=1;
  17. else
  18. t=n*rec(n-1);
  19. return t;
  20. }

QQ截图20210912195543.png

七、变量三属性

变量三属性:类型、作用范围、存储类别
按类型:整型变量、实型变量、字符变量
按有效范围:局部变量、全局变量
按生存期:auto变量 static变量

局部变量(或称内部变量)
定义:在一个函数内部定义的变量为局部变量
1、局部变量只能在它所在的函数内有效
2、在不同的函数中可以出现同名的变量,它们分别属于不同的变量
3、复合语句中定义的变量只能在此复合语句中有效
4、所有形式参数都是局部变量
5、主函数定义的变量也只在主函数生效

全局变量(或称外部变量)
定义:在函数外部定义的变量为全局变量
1、全局变量的有效范围是本文件内从定义该变量的位置开始到本文件的结束
2、全局变量可以在它的有效范围内被每个函数引用
3、在同一文件中若全局变量与局部变量同名,局部变量”屏蔽“全局变量
4、全局变量在整个执行过程都将占用存储单元
5、降低程序的可移植性
6、降低程序的清晰性,各个函数执行时都有可能改变全局变量的值

存储类别
auto类别变量
1、auto类别变量用完后释放所占用空间
2、局部变量默认为auto类别,无初始化时,初值为随机值
3、使用时间短,一般都为auto类别变量

static类别变量
1、static类别从定义到程序运行结束均占用存储空间
2、全局变量默认为static类别,无初始化时,初值为0
3、static类别变量只进行一次初始化
4、生存期为整个源程序

register类别变量
1、register类别只能是局部变量才能被说明
2、一般不能直接使用

extern类别变量
1、extern类别变量可以加大变量的作用范围
2、两格说明格式
格式1:定义同时说明类别
存储类别 类型名 变量名
格式2:分别定义、说明
类型名 变量名
存储类别 变量名

宏定义
无参宏定义
格式:#define 宏名 宏内容
功能:用一个指定的标识符(宏名)来代表一串字符(宏内容)
1、宏名我们一般用大写字母表示,遵守用户自定义标识符命名规则
2、#define可以在函数外定义也可以在函数内定义,只能放在一行
#undef命令可以提前终止宏名的作用域
3、在进行宏定义时,可以引用已经定义的宏名嵌套置换
4、宏替换时,先替换完所有的宏后再运算,替换过程中不能乱加括号
带参宏定义
格式:#define 宏名(参数列表)宏内容
功能:提供了一种更加灵活的替换方式,有时候能起到函数的作用
1、在定义有参宏时,参数列表必须用一对小括号括起且小括号和宏名之间不能有空格
2、对有参宏名进行替换时,需要将形参改成相应的实参,并且注意分清形参和实参的对应关系