1.回调函数
1、概念
回调函数就是一个被作为参数传递的函数。
int func(int a){ printf("func a:%d\n",a);}
int show(int(*pfun)(int)){ pfun(10);}
int main(int argc,char*argv[])
{
show(func); //func 函数就是一个回调函数
return 0;
}
2、模仿标准C库 qsort (利用快速排序法排列数组)的实现
头文件 #include <stdlib.h>
定义函数 void qsort(void * base, size_t nmemb, size_t size,
int (* compar) (const void
*, const void *));
函数说明 参数 base 指向欲排序的数组开头地址, 参数 nmemb 代表数组中的元素数量, 每一元素的大小则由参数
size 决定, 最后一项参数 compar 为一函数指针, 这个函数用来判断两个元素间的大小关系, 若传给 compar 的
第一个参数所指的元素数据大于第二个参数所指的元素数据则必须回传大于零的值, 两个元素数据相等则回传 0.
2.内联函数
1、概念:类似于宏替换,是由inline修饰的函数.意指:当编译器发现某段代码在调用一个内联函数时,它不是去调用该函数,而是将该函数的代码,整段插入到当前位置。这样做的好处是省去了调用的过程,加快程序运行速度。
2、 什么时候用到内联函数:
-
函数的代码简短
-
函数被频繁地调用
3、注意
1)、内联函数实际上是用空间代价(程序尺寸增大)来换取时间效率(不再需要切换函数)
2)、内联函数定义一般放在头文件中
3)、内联函数的代码块尽量不超过5行
4)、内联函数体中,不能有循环语句、if语句或switch语句,否则,函数定义时即使有inline关键字,编译器也会把该函数作为非内联函数处理。
5)、内联函数要在函数被调用之前声明。关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。而且内联函数在声明阶段也要加上inline关键字
练习4:使用内联函数实现 求 三个整型数中的最大值
head.h文件
#ifndef __HEAD_H
#define __HEAD_H
inline int max(int a,int b,int c)
{
return a>b?(a>c?a:c):(b>c?b:c);
}
#endif
test.c文件
#include<stdio.h>
#include "head.h"
//源文件中进行内联函数的声明
extern inline int max(int a,int b,int c);
int main()
{
printf("max:%d\n",max(110,20,30));
return 0;
}
3.静态函数
1、概念
由static修饰的函数,称之为静态函数
2、作用
防止一个工程中不同文件因函数名冲突,静态函数仅限于本文件有效
test.c
#include<stdio.h>
//extern int func();
//静态函数只能在本文件中有效
static int static_func()
{
printf("test.c static_func\n");
}
int main()
{
func();
static_func();
return 0;
}
src.c
#include <stdio.h>
//该函数不能在test.c中被调用
static int static_func()
{
printf("src.c static_func\n");
}
int func()
{
static_func();
printf("func\n");
}
4.递归函数
1、概念:
自己调用自己,称之为递归
2、递归函数设计:
(1)问题模型本身要符合递归模型(递推模型)
(2)问题的解,当递归到一定层次时,答案是显而易见的,且能结束函数。
(3)先明确函数要实现的功能与参数的关系,暂不管功能具体的实现。
(4)呈现第n层与第n-1层的递推关系。
//框架
void func()
{
int a;
func(); ---> 无限递归,没有终止条件 --> 栈空间容易奔溃!
return;
}
一般递归函数携带终止条件
void func(int n)
{
if(n<=0)
return ;
func(n-1);
printf("%d\n",n);
}
int main()
{
func(4);
}
结果:
gec@ubuntu:/mnt/hgfs/share$ ./a.out
1
2
3
4
3、递归函数注意的地方:
- 自己调用自己(递归函数), 自己调用别的函数(函数嵌套)
- 一定有一个终止条件
- 不要递归得太深,否则导致栈空间奔溃
练习1:使用递归函数实现十进制转二进制的结果
#include<stdio.h>
//使用递归实现十进制转二进制
int decimalToBit(int value)
{
if(value/2==0){
printf("%d",value%2);
return 0;
}
decimalToBit(value/2);
printf("%d",value%2);
}
int main(void)
{
decimalToBit(142);
return 0;
}