函数概念
- 由一个或多个语句块组成,完成某项特定任务的子程序。
- 一般会有输入参数和返回值,对过程进行封装和细节的隐藏,具有相对独立性。
函数类型
库函数
- 常用库函数
– IO函数
– 字符串操作函数
– 字符操作函数
– 内存操作函数
– 时间/日期函数
– 数学函数
– 其他函数 - 库函数的查询工具
– MSDN
– https://legacy.cplusplus.com
– https://zh.cppreference.com
自定义函数
- 函数组成
ret_type fun_name(para1,*)
{
statement;//语句项
}
//ret_type 返回类型
//fun_name 函数名
//para1 函数参数
- 示例
#include <stdio.h>
void swap(int* pa,int* pb)
{
int tmp =0;
tmp = *pa;
*pa = *pb;
*pb = tmp;
}
int main()
{
int n1 = 5;
int n2 = 9;
printf("交换前:n1=%d,n2=%d\n",n1,n2);
//交换n1和n2
swap(&n1,&n2);
printf("交换后:n1=%d,n2=%d\n",n1,n2);
return 0;
}
函数使用
函数参数
- 实参(实际参数)
真实传递给函数的参数,可以是常量、变量、表达式、函数等。 - 形参(形式参数)
函数名后括号内的变量,在函数调用完成后就会被销毁,即只在函数中有效。
函数调用
- 传值调用
– 函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参。 - 传地址调用
– 把函数外部创建的变量的地址传递给函数参数;
– 函数内部可以直接操作函数外部的变量。
练习
1.写函数:可以判断一个数是不是素数。
2.写函数:判断一年是不是闰年。
3.写函数:实现一个整型有序数组的二分查找。
4.写函数:每调用一次该函数,就将num值增加1。
//代码1
int is_prime(int m)
{
int i=0;
for(i=2;i<sqrt(m);i++)
{
if(m%i==0)
return 1;//不是素数
}
return 0;//是素数
};
//代码2
int is_leap_year(int year)
{
if((year%4 ==0&&year%100!=0) || (year%400 ==0))
return 1;
else
return 0;
}
//代码3
int binary_search(int arr[],int k,int sz)
{
int left=0;
int right=sz-1;
while(left<=right)
{
int mid =(left+right)/2;//中间元素下标
if(arr[mid]<k)
{
left = mid+1;
}
else if(arr[mid]>k)
{
right = mid-1;
}
else
return mid;
}
return -1;
}
void auto_add(int* m)
{
(*m)++;
}
int main()
{
int num = 0;
auto_add(&num);
printf("num=%d\n",num);
auto_add(&num);
printf("num=%d\n",num);
return 0;
}
嵌套调用
- 函数与函数之间相互组合使用共同完成任务的过程。
链式访问
- 将一个函数的返回值作为另一个函数的参数的过程。
声明和定义
- 函数声明:一般在函数使用前出现(先声明后使用),一般放在头文件中。
- 函数定义:函数的具体功能实现。
函数递归
- 递归的概念:函数在其定义或说明中直接或间接调用自身的一种方法。
- 递归的必要条件
1.存在限制条件,当满足该条件时,递归不再继续。
2.每次递归调用之后会越来越接近限制条件。 - 示例
//接收一个整型值并按照顺序打印每一位。
void print(int m)
{
if(m>9)
{
print(m/10);
}
printf("%d",m%10);
}
int main()
{
int num = 0;
scanf("%d",&num);
print(num);
}
//求字符串长度(不创建临时变量)
int my_strlen(char* str)
{
if(*str !='\0')
return 1+my_strlen(str+1);
else
return 0;
}
int main()
{
char arr[]="Hello world!";
printf("arr的长度为%d\n",my_strlen(arr));
}
- 练习
求n的阶乘(不考虑溢出)
int factorial(int m)
{
if(n<=1)
return 1;
else
return n*factorial(n-1);
}
求斐波那契数列(不考虑溢出)
//递归,速度慢
int Fib(int n)
{
if(n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);
}
//改进
int Fib1(int n)
{
int a=1;
int b=1;
int c=1;
while(n>2)
{
c=a+b;
a=b;
b=c;
n--;
}
return c;
}
- 经典题目
– 汉诺塔问题
– 青蛙跳台阶问题