学习C语言重要的是理解它的设计思想和实现这些思想的原则
指针
指针的本质
指针的值是一块内存的地址,通过指针可以操作那块内存的值。内存的地址是什么?一个整数.
指向指针的指针的…指针
在C语言中,指针是精华,指向指针的指针也比较常用。其实指针的概念扩展开来可以有无限层的指针,但是本质上都指针:其值都是另一块内存的地址。例如下面可以定义4层指针
/* 多重指针并不该被使用,只是为了理解C语言的原则*/
int var = 5; //存在内存0x23处
int *p = &a; //指向0x23处的内存,存在内存0x100处
int **pp = &p; //指向0x100处的内存,存在0x200处
int ***ppp = &pp; //指向0x200处,存在0x300处
int ****pppp = &ppp; //指向0x300处,存在0x400处
指向函数的指针
程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。在实际的函数调用过程中,也是首先把函数名转换成函数指针。
/* 首先要定义好函数原型 */
int compare(void const *,void const *);
//定义指向函数的指针
int (*p_compare)(void const *,void const *);
//指针指向函数
p_compare = &compare;
//起始&是可以省略的,因为函数名在使用时,编译器总是先把它转换成函数指针
p_compare = compare;
如何调用?
- 直接使用函数名compare(p,q):函数名首先被转换成函数指针,它指向内存中函数的地址,然后执行开始于这个地址的代码
- 使用函数指针(*p_compare)(p,q):解引用获得函数名,函数名再被转换成函数指针,这种调用方式是不是最慢的?它的效果和使用函数名是一样的
- 函数指针 p_compare(p,q):直接使用函数指针,这是最直接的方式
注意和普通的函数区分开来:
int *p_compare(void const *,void const *)
p_compare是函数名,它返回整型指针。它的结合顺序是:p_compare首先跟()结合,表明它使一个指针,然后再和*结合,表明它的返回值是一个指针,int表明它使一个指向int型的指针int (*p_compare)(void const *,void const *)
p_compare是指向函数的指针,它的结合顺序是:首先跟(*p_compare)
表明它使一个指针,然后跟(void const *,void const *)
结合,表明它使指向函数的指针,int表明它的返回值
函数指针数组,首先它使一个数组,它的元素都是指向函数的指针,那么该如何定义它呢?试着用一些原则来逐步定义函数指针数组
- 它是一个数组,数组的定义:
p_function_array[]
- 元素是指针,指针数组的定义:
*p_fuction_array[]
- 指向的是函数,
(*p_function_array[])(void *,void *)
- 再加上返回值,
int (*p_function_array[])(void *,void *)
函数指针的使用
函数指针的作用场景是作为函数的参数,也就是回调函数,看一段代码
通过使用函数指针,可以使用与类型无关的查找方法。
不同的类型有不同的比较方法,但是查找的逻辑都是相同的,
所以可以通过为不同的类型提供不同的比较方法,就可以实现统一的查找逻辑。
p_compare就是回调函数,只要函数的声明符合条件,都可以作为search_list的参数
Java中如何实现回调函数?
Node *search_list(List L,void *value,int (*p_compare)(void const *,void const *)) {
for(;;)
if(p_compare(,) == 0)
do something
return 节点;
}
函数指针的场景是转移表,它可以实现switch的功能,考虑一个计算器的功能,把加减乘除抽象成函数,根据不同的命令,通过switch来选择相应的函数。转移表就可以完成这个操作:
double add(double a,double b);
double sub(double a,double b);
double mul(double a,double b);
double div(double a,double b);
//函数指针数组
double (*calc[])(double,double) = {add,sub,mul,div};
//使用
calc[0](a,b)
通过分析一些技巧的含义能让我们更好的理解C语言的原则,例如只要把握住指针的本质,在分析多层指针的时就不会有问题。