1.函数:
在c中,函数用于完成某个特定功能的指令序列的封装
1.1 函数的作用:
(1)代码复用(高内聚,低耦合)----代码与功能高度相契合,函数间关联性低
(2)模块化设计
(3)灵活调用
2.函数的定义:
返回值类型 函数名(形参列表)---形参列表可不写或返回值类型写void(return后面没东西)
{
语句;
return xxx;
}
“返回值类型”:return后面那个表达式值的类型,一般为单值类型即基本类型和指针类型
eg:int add(int a,int b){ return a;} void compare(){return ;} .....
3.函数的调用和传参
上代码:
#include <stdio.h>
int add(int a,int b)//两数相加(形参列表中的名字可以随便写也可以不写,但一定要有数据类型int,float之类的)
{
return a+b;//返回一个值
}
int main()
{
int a,b;//定义两个变量
scanf("%d%d",&a,&b);//
printf("a=%d,b=%d\n",a,b);
printf("a+b=%d\n",add(a,b));//这里调用函数add,传递参数a,b过去,返回一个a+b的值
return 0;
}
4.变量的作用域和生存期
4.1 作用域:变量名能产生作用的范围
全局变量:函数体外,定义在最前面
全局变量的作用域:从定义域到整个工程(别的.c文件也可以访问该变量)
局部变量:函数体内或某个复合语句内定义的变量
局部变量的作用域:从定义域到函数体结束或复合语句结束
如果全局变量在定义时候使用static,则该变量只可以在当前.c文件中使用(保护作用)
编程规范:若不想别的文件访问,用static修饰
注意:使用函数时,形参不会改变实参!!
#include <stdio.h>
int add(int a,int b)//两数相加(形参列表中的名字可以随便写也可以不写,但一定要有数据类型int,float之类的)
{
a=4500;
b=50000;
return a+b;//返回一个值
}
int main()
{
int a,b;//定义两个变量
scanf("%d%d",&a,&b);//
printf("a=%d,b=%d\n",a,b);
add(a,b);
printf("a=%d,b=%d\n",a,b);
// printf("a+b=%d\n",add(a,b));//这里调用函数add,传递参数a,b过去,返回一个a+b的值
return 0;
}
看代码,a,b传参后,我改变他们的值,但实际上a,b的值并没有改变,如果想改变,就使用指针作为形参的方法(后面会详细讲指针)
#include <stdio.h>
int add(int *aa,int *bb)//两数相加(形参列表中的名字可以随便写也可以不写,但一定要有数据类型int,float之类的)
{
*aa=4500;
*bb=50000;
return 1;//返回一个值
}
int main()
{
int a,b;//定义两个变量
scanf("%d%d",&a,&b);//
printf("a=%d,b=%d\n",a,b);
add(&a,&b);
printf("a=%d,b=%d\n",a,b);
// printf("a+b=%d\n",add(a,b));//这里调用函数add,传递参数a,b过去,返回一个a+b的值
return 0;
}
4.2 生存期
生存周期:变量超过生存周期,内存会释放
全局变量的生存周期 : 程序不停,内存不释放
局部变量的生存周期 : 从定义到函数结束
注意static修饰的局部变量,程序不停,不释放,且只会初始化一次;
5. 递归函数(学的有点抽象,只写设计,具体了解看其他递归博客)
递归设计:
1.问题本身符合递归模型
2.明确函数要实现的功能和参数关系,不去管功能的具体实现
3.把第n层和n-1层的关系明确(很重要)
4.问题的解 ,递归到一定程度 ,一定是显而易见的
推荐练习:汉诺塔问题