目录
一.函数的组成
1.实际参数(实参):
2.形式参数(形参):
二.函数的调用
1.传值调用
2.传址调用
3.函数的嵌套调用和链式访问
三.函数的声明和定义
1.函数的声明:
2.函数的定义:
四.函数的递归和迭代
1.函数的递归
2.函数的迭代
3.用函数递归解决经典问题
(1)汉诺塔问题
(2)青蛙跳台阶问题
函数分为库函数和自定义函数。在开发的过程中每个程序员都可能用的到, 为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序开发。
C语言有许多库,每个库包含许多库函数。
C 语言常用的库函数都有: IO 函数 字符串操作函数 字符操作函数 内存操作函数 时间 / 日期函数 数学函数 其他库函数一.函数的组成
ret_type
fun_name
(
para1
,
*
)
{
statement
;
//
语句项
}
ret_type
返回类型
fun_name
函数名
para1
函数参数
例如:实现一个能交换两数的函数
#include
//方式一不能完成任务
void Swap1(int x, int y) {
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
//方式二才能实现
void Swap2(int *px, int *py) {
int tmp = 0;
tmp = *px;
*px = *py;
*py = tmp;
}
1.实际参数(实参):
真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式(表达式的值)、函数(函数的返回值)等。
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形
参。
2.形式参数(形参):
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内
存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
代码一:形参是实参的拷贝,形参和实参的地址不同,形参和实参是独立的空间,形参的改变不影响实参的改变。
代码二:传入实参的地址,形参拷贝的是实参的地址,解引用修改形参,就能修改实参。
二.函数的调用
1.传值调用
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
2.传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。
3.函数的嵌套调用和链式访问
不同函数之间可以根据实际的需求进行组合的,也就是互相调用的。函数可以嵌套调用,但是不能嵌套定义。
例如:函数二嵌套调用了函数一。
#include
void
new_line
()//函数一
{
printf
(
"hehen"
);
}
void
three_line
()//函数二
{
int
i
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
new_line
();
}
}
把一个函数的返回值作为另外一个函数的参数。例如:strcat函数的返回值作为strlen函数的参数
三.函数的声明和定义
1.函数的声明:
1.
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。(声明时函数的形参名可以省略)
2.
函数的声明一般出现在函数的使用之前。要满足
先声明后使用
。
3.
函数的声明一般要放在头文件中的。
2.函数的定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
四.函数的递归和迭代
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
递归实现求字符串长度函数:
int my_strlen(char*str){
if(*str!=' ')
return 1+my_strlen(str+1);
else
return 0;
}
2.函数的迭代
迭代是
重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。函数的迭代指循环实现,是非递归的过程。
例如求n的阶乘函数实现:
//函数的递归实现
int fun1(int n){
if(n==1)return 1;
else
return n*fun1(n-1)
}
//函数的迭代实现
int fun2(int n){
int ret,i;
for(i=1;i<=n;i++){
ret=ret*i;
}
return ret;
}
3.用函数递归解决经典问题
(1)汉诺塔问题
由分析可得,步骤一和三递归实现即可。
//实现求出需要移动圆盘总次数的函数
int fun(int n){
if(n==1) return 1;
else
return 2*fun(n-1)+1;
}
(2)青蛙跳台阶问题
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
列出函数表达式:(与斐波那契数列类似)
int fun(int n){
if(n==1)return 1;
if(n==2)return 2;
if(n>2) return fun(n-1)+fun(n-2);
}
二.函数的调用
1.传值调用
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
2.传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。
3.函数的嵌套调用和链式访问
不同函数之间可以根据实际的需求进行组合的,也就是互相调用的。函数可以嵌套调用,但是不能嵌套定义。
例如:函数二嵌套调用了函数一。
#include
void
new_line
()//函数一
{
printf
(
"hehen"
);
}
void
three_line
()//函数二
{
int
i
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
new_line
();
}
}
把一个函数的返回值作为另外一个函数的参数。例如:strcat函数的返回值作为strlen函数的参数
三.函数的声明和定义
1.函数的声明:
1.
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。(声明时函数的形参名可以省略)
2.
函数的声明一般出现在函数的使用之前。要满足
先声明后使用
。
3.
函数的声明一般要放在头文件中的。
2.函数的定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
四.函数的递归和迭代
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
递归实现求字符串长度函数:
int my_strlen(char*str){
if(*str!=' ')
return 1+my_strlen(str+1);
else
return 0;
}
2.函数的迭代
迭代是
重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。函数的迭代指循环实现,是非递归的过程。
例如求n的阶乘函数实现:
//函数的递归实现
int fun1(int n){
if(n==1)return 1;
else
return n*fun1(n-1)
}
//函数的迭代实现
int fun2(int n){
int ret,i;
for(i=1;i<=n;i++){
ret=ret*i;
}
return ret;
}
3.用函数递归解决经典问题
(1)汉诺塔问题
由分析可得,步骤一和三递归实现即可。
//实现求出需要移动圆盘总次数的函数
int fun(int n){
if(n==1) return 1;
else
return 2*fun(n-1)+1;
}
(2)青蛙跳台阶问题
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
列出函数表达式:(与斐波那契数列类似)
int fun(int n){
if(n==1)return 1;
if(n==2)return 2;
if(n>2) return fun(n-1)+fun(n-2);
}
2.传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。
3.函数的嵌套调用和链式访问
不同函数之间可以根据实际的需求进行组合的,也就是互相调用的。函数可以嵌套调用,但是不能嵌套定义。
例如:函数二嵌套调用了函数一。
#include
void
new_line
()//函数一
{
printf
(
"hehen"
);
}
void
three_line
()//函数二
{
int
i
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
new_line
();
}
}
把一个函数的返回值作为另外一个函数的参数。例如:strcat函数的返回值作为strlen函数的参数
三.函数的声明和定义
1.函数的声明:
1.
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。(声明时函数的形参名可以省略)
2.
函数的声明一般出现在函数的使用之前。要满足
先声明后使用
。
3.
函数的声明一般要放在头文件中的。
2.函数的定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
四.函数的递归和迭代
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
递归实现求字符串长度函数:
int my_strlen(char*str){
if(*str!=' ')
return 1+my_strlen(str+1);
else
return 0;
}
2.函数的迭代
迭代是
重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。函数的迭代指循环实现,是非递归的过程。
例如求n的阶乘函数实现:
//函数的递归实现
int fun1(int n){
if(n==1)return 1;
else
return n*fun1(n-1)
}
//函数的迭代实现
int fun2(int n){
int ret,i;
for(i=1;i<=n;i++){
ret=ret*i;
}
return ret;
}
3.用函数递归解决经典问题
(1)汉诺塔问题
由分析可得,步骤一和三递归实现即可。
//实现求出需要移动圆盘总次数的函数
int fun(int n){
if(n==1) return 1;
else
return 2*fun(n-1)+1;
}
(2)青蛙跳台阶问题
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
列出函数表达式:(与斐波那契数列类似)
int fun(int n){
if(n==1)return 1;
if(n==2)return 2;
if(n>2) return fun(n-1)+fun(n-2);
}
三.函数的声明和定义
1.函数的声明:
1.
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。(声明时函数的形参名可以省略)
2.
函数的声明一般出现在函数的使用之前。要满足
先声明后使用
。
3.
函数的声明一般要放在头文件中的。
2.函数的定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
四.函数的递归和迭代
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
2.函数的定义:
函数的定义是指函数的具体实现,交待函数的功能实现。
四.函数的递归和迭代
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
1.函数的递归
程序调用自身的编程技巧称为递归(
recursion
)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身。递归的主要思考方式在于:把大事化小 。
递归的条件:存在终止递归的限制条件,每次递归不断接近限制条件,最终达成限制条件。
例如:实现打印一个数的各位数的函数,限制条件是n为非0.
#include
void print(int n) {
if (n) {
print(n / 10);
printf("%d ", n % 10);
}
}
递归实现求字符串长度函数:
int my_strlen(char*str){
if(*str!=' ')
return 1+my_strlen(str+1);
else
return 0;
}
2.函数的迭代
迭代是
重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。函数的迭代指循环实现,是非递归的过程。
例如求n的阶乘函数实现:
//函数的递归实现
int fun1(int n){
if(n==1)return 1;
else
return n*fun1(n-1)
}
//函数的迭代实现
int fun2(int n){
int ret,i;
for(i=1;i<=n;i++){
ret=ret*i;
}
return ret;
}
3.用函数递归解决经典问题
(1)汉诺塔问题
(1)汉诺塔问题
由分析可得,步骤一和三递归实现即可。
//实现求出需要移动圆盘总次数的函数
int fun(int n){
if(n==1) return 1;
else
return 2*fun(n-1)+1;
}
(2)青蛙跳台阶问题
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
列出函数表达式:(与斐波那契数列类似)
int fun(int n){
if(n==1)return 1;
if(n==2)return 2;
if(n>2) return fun(n-1)+fun(n-2);
}



