第五章 函数
特点
- 避免重复的代码,提高复用性
- 模块化编程,把一个复杂的问题给拆分成一个一个小的功能模块
- 函数定义,实现具体功能的一个模块,从原则上,尽可能使功能单一。
- 低耦合,高内聚
1、函数的定义
定义语法
返回类型 函数名称(数据类型 参数名1,数据类型 参数名2…) 参数列表
{
return 表达式;
} //函数体
如果没有返回类型、默认是int(不建议)
返回值有类型,可以是int、long、double、float、char、void
返回值是void表示不返回任何数据,不能返回数组类型
返回值有两种情况
- 情况1,表示函数调用是否成功的状态, 0(表示调用成功)1(表示调用失败)
- 情况2,表示对数据加工完后的值,也就是计算结果;
函数名,标识符,字母,数字,下划线,不能以数字开头。函数名要做到见名知意
参数,会与其他模块进行交互,如果没有参数,参数列表空着即可;如果有多个参数,以逗号隔开。参数必须有数据类型
void cmptwonum(int a,int b) //应该在xxx.c中写,c语言源文件
{
if(a>b)
{
printf("a>b\\n");
}
else
{
printf("a<=b\\n");
}
return; //void与return配套,非void与return 0,返回值与类型要对应
//返回值分两种:返回结果,返回类型。成功返回0,失败返回1
}
int cmptwonum(int a,int b) //参数 在xxx.c中,c语言源文件,存储实现类的信息
2、函数的调用
在C语言当中,函数在调用之前必须先声明。声明的意思就是告诉编译器,有这个函数
声明前需要先定义函数;换而言之,在准备调用函数时,告诉gcc有这个东西。
函数的声明
void cmptwonum(int a,int b); //xxx.h c语言的头文件
int show();
void cmptwonum(int a,int b):xxx.h c语言的头文件,要存放声明类的信息
函数的调用
- 需要使用(),圆括号是一个运算符也就是函数调用运算符。
- ()圆括号不可省略
函数名(参数);
- 函数调用的时候有函数调用符,就是()
- 参数类型匹配时,个数要相同,可以使常量、变量、表达式
- 在调用函数的时候,会发生跳转,从函数体开始执行,当执行完成后,会返回到调用的地方
- 在函数调用完成后,因为是一个表达式,所以调用完成后是有类型和值的,由return返回出来。
show()+1;
示例(函数的使用)
- 用函数进行任意两个数的加减乘除
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int jian(int a,int b)
{
return a-b;
}
int cheng(int a,int b)
{
return a*b;
}
int chu(int a,int b)
{
return a/b;
}
int main()
{
int num1=0;
int num2=0;
int ret =0;
printf("input 2 num:");
scanf("%d%d",&num1,&num2);
ret =add(num1,num2);
printf("add ret %d\\n",ret);
ret =jian(num1,num2);
printf("jian ret %d\\n",ret);
ret =cheng(num1,num2);
printf("cheng ret %d\\n",ret);
ret =chu(num1,num2);
printf("chu ret %d\\n",ret);
return 0;
}
3、变量的作用域和生存周期
作用域
能够使用变量(标识符)的范围称为变量的作用域
-
局部变量的作用域
在函数内部定义的变量为局部变量,函数的参数也是局部变量,
在花括号{}以内的变量(标识符)也是局部变量
局部变量的作用域在 离该变量定义最近的大括号
如果在一个局部范围内,又定义了一个大括号,在大括号内部,可以有同名标识符。那么内层的变量会遮挡(遮挡的原因是因为:内外层变量存在同名变量)外层的变量。使用变量的话,访问的是内部的变量
局部变量的作用域和生存周期是一致的
-
全局变量的作用域
变量可以在整个工程中都可以被访问到
不要用的过于频繁
生命周期
从变量的创建开始到变量对应内存空间的回收之间的这段时间称为生命周期
-
局部变量的生命周期
局部变量的生命周期 从定义变量开始 到 函数结束
局部变量的生命周期,从定义处开始,到最近的右大括号结束
-
全局变量的生命周期
全局变量生命周期从 a./out 开始运行就创建,直到a./out消亡,变量才会被回收。
全局变量创建的时候如果没有给初值,那么他的初值就是0
4、变量的存储类型
存储类型 数据类型 标识符;
auto int a;
register int b;
extern int c;
static int d;
int e;
auto
自动类型,针对于普通的局部变量,存储到栈区
在实际当中,auto int a== int a,auto可以省略
register
寄存器变量,
register int b;告诉编译器,建议把b这个变量,存储在cpu的寄存器中

extern
extern int c; 和全局变量搭配,extern翻译过来是外部,在多文件编程中使用,本质是一个声明
假如在1.c中定义一个全局变量,在2.c中需要使用在1.c定义的全局变量,就要先使用extern声明后才可以使用(此时不需要初始化)。
extern int fun(int a,int b); 函数的声明,会出现在头文件当中

static
静态,使用static修饰变量的话,那么这个变量会存储在 静态区(或者也可以说数据区),
从形式上看,类似于全局变量,但是受到作用域的限制,如果没有初始化,默认初值为0
static int d;
可执行程序的内存分布图

!重点!
函数的定义
函数的调用
作用域、生命周期(理论)
存储类型当中比较重要的是static(与作用域以及生命周期有关)和extern(用于多文件)



