【嵌入式C语言】08.递归+内联+回调+函数指针+指针函数+关键字
一、递归函数1.什么是递归(递归思想)指的是一个函数自己调用自己--》递归函数2.递归的例子求n的阶乘n*(n-1)阶乘3.递归的特点第一个无论什么递归一定有退出条件,如果没有初始化条件会陷入无穷递归第二个递归的次数不可以太多(递归的深度不能太深)太多有可能导致栈溢出(栈空间耗完了)栈空间的存储容量有限一般栈空间只有几兆4.什么时候会用到递归分析问题的思路如果你发现问题的解决后面的步骤需要依赖前面的步骤(后面步骤跟前面步骤间有数学关系)总结数学关系然后就可以采用递归二、内联函数1.什么是内联函数inline 函数的返回值 函数名(形参){}2.内联函数的作用解决函数调用时入栈和出栈的时间耗费对于经常要使用的短小的代码适合定义成内联函数内联函数编译器会在调用的位置直接把内联函数的源码复制过来3.内联函数的优缺点优点节约了函数调用入栈出栈的时间耗费内联函数用内联代码替换函数调用内联函数体的代码不能过长因为内联函数省去调用函数的时间是以代码膨胀为代价的。代码膨胀主函数在调用内联函数的时候编译器会把内联函数的代码拷贝到主函数调用位置(效果等同于直接把内联函数的源码写在了主函数的这个位置主函数代码空间就变大了)内联函数不能包含循环语句因为执行循环语句要比调用函数的开销大缺点增加主程序的长度增加了主函数占用的内存耗费了比较多的内存4.编译代码如果你的编译器无法识别内联函数gcc xxx.c -o xxx -fgnu89-inline //编译的时候加上-fgnu89-inline选项即可三、回调函数1.回调函数的概念程序员调用A函数,A函数调用的时候自动帮你调用B函数,B函数去完成最终需要的功能,B函数就叫做回调函数回调函数的本质是“行为参数化”把“做什么”交给调用者决定把“什么时候做”交给框架或算法决定。2.如何使用回调函数void fun(函数指针){通过函数指针来调用不同的函数执行不同的功能}3.使用场景四、函数指针和指针函数1.函数指针(中心词是指针)1.1 定义函数指针函数名就是个指针函数名表示函数的入口地址int add(int a,int b); 函数addint (*p)(int,int)add; 定义一个函数指针指向add1.2 使用函数指针int (*p)(int,int)add; 定义函数指针p指向addp(15,16); 通过函数指针p调用add2.指针函数(中心词是函数)只要一个函数的返回值是指针那么这个函数就叫做指针函数int *f1() //返回的是指针就是指针函数{}int f2(char *path) //返回的不是指针不是指针函数就是普通函数{}五、关键字1.关键字汇总static const extern define(不是关键字,是预处理命令) typedef2.各个击破2.1 static——静态第一种static修饰全局变量局部变量修饰全局变量此时这个全局变量只能在定义它的.c文件中使用其它.c文件不可以使用修饰局部变量表示该局部变量只能被初始化一次第二种static修饰函数,该函数只能在定义它的.c文件中使用作用2.2 const第一种修饰普通变量const int a99; //a是个常量常量是只读的不能修改可以访问const double b3.14;数组名类似于特殊的const数组名不能做左值第二种修饰指针int a99;第一种 const int *pa; //表示指针p不可以修改a的内容第二种 int const *pa; //第一种和第二种是等价的第三种 int *const pa; //p指向a以后后面就不可以再去指向其他变量的地址左定值右定向const 修饰谁谁不变2.3 extern声明外部的全局变量: 在别的.c文件中定义的全局变量(非静态 非static)如果当前文件需要使用用extern声明即可声明外部函数在别的.c文件中定义的函数(非静态)如果当前文件需要使用用extern声明即可2.4 define 宏定义2.4.1 宏定义的写法宏定义字符的替换宏定义一般写成大写写法一普通的宏定义,不带参数的宏定义#define PI 3.14#define PATH /dev/fb0#define N 10写法二带参数的宏定义(宏函数)——》纯文本替换不会帮你加括号#define F(n) n*n2.4.2 宏函数和普通函数对比宏函数不是真正意义上的函数宏函数没有入栈出栈的操作普通函数需要入栈出栈2.4.3 宏定义的特点第一个每个单独的宏定义都各自占一行第二个宏定义一行写不下必须加上续行符(\)第三个宏定义中的参数都是没有数据类型的第四个带参数的宏定义参数用圆括号括起来2.5 typedef 类型重定义2.5.1 作用给变量类型取别名2.5.2 用法用法一给基本数据类型取别名typedef 基本数据类型 新的别名;比如typedef unsigned int u32;用法二给指针类型取别名typedef char * charp;用法三给结构体取别名typedef struct{int x;int y;} Point;