函数
今天来复习函数,在循环的时候我们了解到循环就是完全重复执行相同的操作,这样可以为我们省下很多时间,那么针对主题功能相同,只是相关参数改变,我们又该怎么样来时代码的重复率降低呢?那么函数就很好的解决了这个问题。
在大型的c文件中可以有很多的函数,但是有且仅有一个main函数,main函数的程序的入口和出口.函数是 完成完成某个功能的指令序列的封装,C语言的指令(C语句)必须在函数的内部,C程序是由函数组成,函数是指令(语句)组成的.
设计一个函数
设计一个好的函数主要分为四大步:
取个函数名
函数名的命名规则同样要遵守标识符的命名规则,一般来说要清楚放映出函数的主要功能,两个单词间用下划线连接。
函数的说明
在写函数时,要把整个函数所定义的东西全部放在函数的最前面,
/*
find_max : 求一个数组的最大值
@ a : 数组名 .数组的类型必须是int
@ n : 数组元素的个数
*/
这样方便自己阅读,最重要的是,以后工作并不是一个人就可以负值整个项目,一个大项目需要多人合作,你写了说明,可以让别人更快的了解你的这个函数。
函数的返回值
当这个函数执行完的时候如果有个结果,那么就要返回到mian函数中去(当然前提是main函数中也调用了该函数),返回值也要详细的把介绍写上去
/*
find_max : 求一个数组的最大值
@ a : 数组名 .数组的类型必须是int
@ n : 数组元素的个数
返回值 :
返回数组a里面n个元素的最大值
最大值的类型是 int
*/还有一种void,它有几种意思:1、你去执行这个程序不一定需要返回值 2、你执行的这个程序返回值是确定的(一定成功or一定不成功)
返回的时候用return+你要返回的东西(此时要求 函数返回值的类型为 typeof(表达式) 或 兼容 ),如果是void类型的话,return可以不带任何东西以分号结尾就行,当然你也可以直接不写return。
函数的调用
函数写出来了,那我们怎么使用呢?我们记得我们创建函数的初衷是解决那些重复代码的问题,我们的函数就是重复的部分,那么不重复的部分就写在main函数里面,既然如此我们调用的时候也是在main函数里面调用。
如果你把函数写出来,而不去main函数里面调用,那么我们说你写的这个函数是没有用的,系统压根不会去执行它。
函数在调用的时候可以放在main函数后面也可以放在main函数前面,但是如果你要把main函数写在最前面,那么你在调用你自己构造的函数的时候就一定记得要声明,先声明后使用!
函数里面的参数
之前提过形参和实参,那么在函数里面谁是形参谁是实参呢?
形参就是在定义函数的时候创建的参数,在定义形参的时候要注明形参是什么类型的,但是不用赋值。(传给实参后也就销毁了)
实参就和形参不一样了,它是在调用函数的时候的参数,那这个时候你就不用对实参规定类型了但是一定要赋值。
形参和实参是一一对应的!
当调用的实参为变量时,函数的形参和实参是分别占用不同的存储单元,但是当调用的实参为数组和指针时,实参和对应的形参共用同一段存储空间所以大家在写交换函数的时候可能就会有些问题,因为调用的实参不是数组和指针的时候,形参和实参居然不在同一内存块上,那不是交换了个寂寞!!!但是改成数组,or指针交换就行了。
#include<stdio.h>
/*
@a:第一个交换数
@b:第二个交换数
返回值:无
*/
// void swap(int a,int b)
// {
// int temp;
// temp = a;
// a = b;
// b = temp;
// }
// int main()
// {
// int h = 1;
// int p = 2;
// swap(h,p);
// printf("h=%d p=%d",h,p);
// return 0;
// }
/*
@*a:第一个交换数
@*b:第二个交换数
返回值:无
*/
void swap(int*a,int*b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int h = 1;
int p = 2;
swap(&h,&p);
printf("h=%d p=%d",h,p);
return 0;
}
函数的声明
还是把它拿出来单独说说吧,上面已经说了在什么情况下需要使用函数的声明,现在来说说如何声明呢?基本形式:函数的返回值类型 函数名 (函数形式参数的类型列表);
//sum函数的声明 ==> 告诉编译器 sum 是一个函数,带两个int类型的参数 ,返回值int类型
int sum(int , int);
/*
sum :求和.求两个整数的和
@a : 第一个加数
@b : 第二个加数
返回值 :
返回 a + b 的和
*/
int sum(int a ,int b)
{
int s;
s = a + b;
return s;
}
数组作为函数的参数
数组作为函数的形参的时候怎么操作呢?
一维数组
/*
find_max : 找一个数组中的最大值.只求一维数组int类型元素的数组的最大值
@b : 元素类型为int类型的数组名
@n : 元素的个数.求数组n个元素的最大值
返回值 :
返回数组中的最大值
*/
int find_max(int b[],int n)
{
//b[0] b[1] ...b[n-1]
return max;
}这是一维数组的,可以看见形参那块,前面是数组的类型加名字,后面是数组元素的个数。
类似的,形参和实参是一一对应的,和前面说到的实参不用注明类型只要值,所以阿我们在调用的时候很明显就应该这么写
find_max( b, n)//写出数组的名字和元素个数即可
二维数组作为形式参数
之前复习数组的时候说过,二维数组就是一维数组,那么二者在构造的时候也是大同小异的
int a[3][4]我们可以看成是有3个int[4]类型的数组,那么在做函数声明的时候可以类比隐含指定的操作
f(int x[][4] ,int n)
f(a,3) ;实际调用注意这里面传入函数的个数,它不是所有元素的个数了,而是行个数,也就是填的是有3个int[4]的那个3!
int a[3][4];
假设需要把数组a当做参数,传入一个函数xxx
xxx(a,3);
那xxx这个函数的形式参数如何定义呢?
数组元素的类型 数组名[] , 元素个数
==>
int[4] x[] ,int n
==>
int x[][4] , int n
xxx(int x[][4] , int n) //函数只能接收 列数为4的二位数组 int[4]
{
//x[0][0] x[0][1] x[0][2] x[0][3]
//x[1][0] .... x[1][3]
...
//x[n-1][0] ... x[n-1][3]
}int b[4][5];
int[5] b[4];
xxx(b,4);//error,类型不匹配,会有警告
附上一个数组作为参数的代码
#include<stdio.h>
/*
get_min : 求数组中的最小值
@a : 数组名
@n : 数组元素的个数
返回值min :
返回 数组中的最小值
*/
int get_min(int a[],int n)
{
int min = a[0];
for(int i = 0;i<4;i++)
{
if(min>a[i])
{
min = a[i];
}
}
return min;
}
/*
scan_shuzhu : 从键盘上输入数组每一个元素的值,然后保存到相应的
数组中去.
@a :接收传入的int类型的数组名
@n :接受传入元素的个数
返回值 :
无
*/
void scan_shuzhu(int a[],int n)
{
for(int j = 0;j<4;j++)
{
scanf("%d",&a[j]);
}
}
int main()
{
int h[4];
scan_shuzhu( h, 4);
printf("%d", get_min(h,4));
return 0;
}