关于函数指针的个人理解,uboot中二重函数指针的实例分析

来源:互联网 发布:物联网与人工智能 编辑:程序博客网 时间:2024/05/16 10:25

 函数指针,顾名思义,指向函数的指针。

下面是百度百科对函数的声明过程

函数指针的声明方法为:
返回值类型 ( * 指针变量名) ([形参列表]);
注1:“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
或者使用下面的方法将函数地址赋给函数指针:
f = &func;
个人理解: 函数名可以认为是地址,也就是说可以认为函数名本身就是一个指针类型,类似于数组的数组名,所以函数指针变量赋值的时候直接给赋值函数名就可以了,注意的是不要带后面的括号。
需要注意的是这两种赋值方式,f = func 是函数的首地址,类似于数组中的第一个变量的地址,f=&func是函数的地址。其实两者在地址上是相等。
其次就是声明时的优先级问题,int (*f) (int x);  因为*号的优先级比较低,所以当前要给变量f加 *,说明是一个指针类型。如果不加括号的话,
int* f (int x)就是一个返回值为int*的函数。
其次用函数指针调用函数时的调用方式有两种 ,一种就是 *f 这样取指针内容的方式,另一种就是直接还原成函数型 的调用,类似 f(x)
接下来分析Uboot中是实例,二重函数指针的使用方法。
typedef int (init_fnc_t) (void);//声明一个函数型,不是函数指针类型,所以如果要声明函数指针的话,要加*
//函数型是 int (name )void; name 的格式就是返回值为int 参数为void的类型。
//比如声明一个函数指针 init_fnc_t *ptr_func = NULL;
init_fnc_t *init_sequence[] = {//声明一个init_fnc_t*型的函数指针数组,因为函数名本身就是函数指针,因为[]的优先级要大于 *(指针)所以,init_sequence首先是一个数组,其次是一个init_fnc_t*型的数据,也就是指针型的数组。
cpu_init,/* basic cpu dependent setup */
 ******
NULL,
};
init_fnc_t **init_fnc_ptr;///声明一个二重指针,二重指针可以指向函数指针的地址,或者,指针数组的首地址。

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {//二重指针指向指针数组,首次执行的时候
if ((*init_fnc_ptr)() != 0) {  // *init_fnc_ptr = cpu_init 即cpu_init的运行首地址 在条件判断中使用了// *init_fnc_pt来进行判断,如果是NULL的话,循环跳出。
hang ();//if ((*init_fnc_ptr)() != 0) 函数的执行,如果返回值!=0,执行函数hang()挂起
}
}

原创粉丝点击