自定义函数
格式
返回值类型 函数名 ( 函数参数)
{
.......
}
例
int GetMax(int x,int y)
{
return x>y?x:y;
}
函数的参数
实参(真实的参数)
真实传给函数的参数;在函数调用时必须有确定的值;
形参(形式的参数)
在函数定义或声明时,函数名后的参数;只有在函数被调用时,才会实例化分配存储空间,在调用完成后,会自动销毁且形参只在函数内部有效。
int GetMax(int x,int y) //x,y为形参
{
if(x>y||x==y)
{
return x
}
return y;
}
void main()
{
int a=10;
int b=15;
int max;
max=GetMax(a,b); //a,b为实参
printf("最大值为%d\n",max);
}
函数的调用
传值调用
当函数被调用时实参传入,形参实例化分配存储空间并将获得与与实参相同的值。(形参实例化后相当于实参的临时拷贝)
函数内对参数的任何修改,都不影响实际参数
#include<stdio.h>
void swap(int x, int y);//函数的声明
int main()
{
int a = 10;
int b = 15;
printf("交换前%d %d\n", a, b);
swap(a, b);
printf("交换后%d %d\n", a, b);
return 0;
}
void swap(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
printf("swap中%d %d\n", x, y);
}
传址调用(通过指针,暂时了解即可)
将实参的地址传递给函数参数,如此,对函数参数的操作将影响实参;
#include<stdio.h>
void swap(int *x, int *y);
int main()
{
int a = 10;
int b = 15;
printf("交换前%d %d\n", a, b);
swap(&a, &b);
printf("交换后%d %d\n", a, b);
return 0;
}
void swap(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
printf("swap中%d %d\n", *x, *y);
}
函数的使用
嵌套调用
函数中调用函数
void fun1() //函数嵌套
{
printf("我是外面\n");
fun2();
}
void fun2()
{
printf("我是里面\n");
}
void main()
{
fun1();
}
链式访问
函数的返回值可以作为其他函数的参数
void fun3() //链式访问
{
printf("3--%d ", printf("2--%d ", printf("1--%d ", 43)));
}
void main()
{
fun3();
}
函数的声明和定义
函数声明:
告诉编译器,函数名,函数参数,函数返回值;具体实现无关紧要。
声明要在函数使用之前
函数声明一般放于头文件中
返回值类型 函数名 ( 函数参数);
分文件书写
test.h
//防止反复声明,函数无法实现
#ifndef _TEST_H_ //if no define
#define _TEST_H_
//函数声明
int GetMax(int x,int y);
#endif
函数的定义
函数的具体实现
test.c
//#include
//<>在标准的include中查找
//""在当前目录的中查找
#include"test.c"
int GetMax(int x,int y)
{
return x>y?x:y;
}
函数递归(自己调用自己)
形式清晰
存在限制条件,每次调用都接近限制条件,当满足条件后不在调用;
int factorial(int n) //求n的阶乘
{
if(n == 1) //限制条件
{
return 1;
}
return n * factorial(n - 1); //调用
}
栈溢出
由于函数的每一次调用都要给形参分配空间,而系统分配给程序的空间是有序的,当递归深度太大或出现死递归、死循环,空间耗尽,就会溢出。
可以用递归(循环)解决
可读性稍差
int factorial(int n)
{
int result=1;
for (int i = 2; i <= n; i++)
{
result *= i;
}
return result;
}
两种方式各有优缺点,根据实际问题选择。
最难不过坚持!