问题:
1.在查阅u-boot源码(uboot\lib_arm\board.c )的过程中,发现了以下知识点:
1.1定义一个函数类型
typedef int (init_fnc_t)(void);
1.2 定义了一个双重指针
// uboot\lib_arm\board.c 446行
init_fnc_t **init_fnc_ptr;
//uboot\lib_arm\board.c 483行
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
//uboot\lib_arm\board.c 416行
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
reloc_init, /* Set the relocation done flag, must
do this AFTER cpu_init(), but as soon
as possible */
#endif
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
display_dram_config,
NULL,
};
}
知识点解析
采用如下例子解析
#include<iostream>
//定义三个函数
int fun1(void)
{
printf("函数1初始化成功\n");
return 0;
}
int fun2(void)
{
printf("函数2初始化成功\n");
return 0;
}
int fun3(void)
{
printf("函数3初始化成功\n");
return 0;
}
/***
定义一个函数类型:
返回值int
函数名 init_fnc_t
传递的参数void等构成
*/
typedef int (init_fnc_t)(void);
/*
用定义好的函数类型,定义一个数组
该数组是指针数组,每个指针都指向init_fnc_t函数类型
*/
init_fnc_t* init_sequence[] = {fun1,fun2,fun3};
int main(void)
{
init_fnc_t** init_fnc_ptr=nullptr; //定义了二重指针 存放了一个指针,该指针指向的类型是函数类型
//指针变量,存放的是一个指针,该指针
//类比:int* p; p是一个指针变量,说白了p就是一个变量,这个变量特殊,有*p这个操作。
// 之所以有*p这个操作就是因为变量p存储的是一个地址
// 人们为了能够对地址中的内容读写,所以要有*p这个操作
// 更详细的说:
//对p直接赋值,其实就把 ‘地址1’ 存放在 变量p中 然后通过*p 对‘地址1’所指向的内容进行操作
//*p = 3; 即把 ‘地址1’中的内容变为3
//所以 init_fnc_ptr 是一个指针变量,存放的是地址1,但地址1中存放的还是一个地址 为地址2
// 因此 *init_fnc_ptr 表示改变地址2的值,不是改变地址2中的内容哈
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
// 打印出地址,发现和fun1,fun2,fun3的地址相同
printf("此时对应的指针为:%x\n",*init_fnc_ptr);
printf("函数1的地址为:%x\n", fun1);
printf("函数2的地址为:%x\n",fun2);
printf("函数3的地址为:%x\n",fun3);
if ((*init_fnc_ptr)() != 0)
printf("初始化失败了");
}
}
指针,双重指针,指针函数解析
1.指针
int *p = 0x20000000;
*p=2;
解析:
2 双重指针
int** p;
p = 0x2000 0000;
*p = 0x3000 0000;
**p = 2;
解析:
3 当双重指针指向的是函数时。 双重指针作用有两个,一个是用来指向指针,一个是用来指向指针数组。
这里是用来指向一个函数指针数组
// for 循环中 为什么不用 **init_fnc_ptr 而是用 *init_fnc_ptr呢,仔细理解
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
// 打印出地址,发现和fun1,fun2,fun3的地址相同
printf("此时对应的指针为:%x\n",*init_fnc_ptr);
printf("函数1的地址为:%x\n", fun1);
printf("函数2的地址为:%x\n",fun2);
printf("函数3的地址为:%x\n",fun3);
if ((*init_fnc_ptr)() != 0)
printf("初始化失败了");
}
}