参考: 里科《C和指针》
指针热身
int *f(); // ()优先级高于*,所以f是一个函数,返回int指针
int (*f)(); // f是一个函数指针,它指向的函数返回一个int值
int *(*f)(); // f是一个函数指针,它指向的函数返回一个int指针
int *f[]; // []的优先级更高,所以是一个数组,但元素是int指针
int (*f[])(); // f是一个数组,其元素类型是函数指针,它指向的函数返回值是int
int *(*f[])(); // 同上,只是返回的是int指针
函数指针
用途:把函数指针作为参数传递给函数;转换表
// 声明
int f(int);
// &非必需,因为编译器会把函数名转化为函数指针,&只是显式说明
int (*pf)(int) = &f;
// 使用
int ans;
ans = f(25);
ans = pf(25);
ans = (*pf)(25); // *只是显式说明
- 回调函数
// compare()在search_list()中用来比较值。这个函数可以处理多种类型的数据
// 声明
Node*
search_list(Node *node, void const *value,int (*compare)(void const *, void const *) );
// 使用
desired_node = search_list(root, &desired_value, compare);
- 转换表
比如设计一个计算器,如果有非常多的操作,整个switch会非常大,此时可以使用转换表:先声明并初始化一个函数指针数组,然后用一个语句替代switch。注意:需要始终验证下标的有效性。
// 原本的swithc
switch(oper) {case ADD:result = add(op1, op2);break;case SUB:result = sub(op1, op2);break;...
}//------使用转换表------------// 先写函数声明
double add(double, double);
double sub(double, double);
...
// 再初始化转换表
double (*oper_func[])(double, double) = {add, sub,...};
// 替换switch
result = oper_func[oper](op1, op2);
命令行参数
// argc是参数个数,argv是一个指针数组,其中的元素是指向字符串的指针
int
main( int argc, char **argv);
字符串常量
字符串常量实际是指针,下面是一些应用。
"xyz" + 1 // 是指向y的指针
*"xyz" // x
"xyz"[2] // z// 输入0~100,打印0~10个星号
void
mystery (int n)
{n += 5;n /= 10;print("%s\n", "**********" + 10 - n);
}// 打印余数。如果是十六进制的0~15,那直接[]转化成十六进制字符
putchar("0123456789ABCDEF"[value % 16]);