1.高级声明
int (* f)() //间接访问在函数调用之前,f成为函数指针返回一个整型值
int f[] // f是一个整型数组
int f()[]//函数返回值是一个整型数组然而, 函数只能返回标量,无法返回一个整型数组所以这个声明是非法的
int f[]();//f是一个数组,元素的类型是返回值为整型的函数,函数声明非法的
int ( *f [ ] ) ( );
//f是一个元素为函数指针的数组,返回值是int
int *(*f[ ])()//和上一个差不多,就是返回类型是int*
更完整的函数声明
int (*f)(int ,float);//f定义为一个函数指针,后边是参数类型
int *(*g[ ]) (int, float);//g是一个数组,数组元素是一个函数指针,所指向的函数接受两个参数,返回一个整型指针,这个是创建了一个指针数组
13.3 函数指针
函数指针有两个用途:转换表 作为参数传递给另外一个函数
简单声明一个函数并不意味着它可以马上使用,对函数执行间接访问之前必须把它初始化指向一个函数
一个例子
//声明与初始化函数指针
int f(int);
int (*pf)(int) = &f;//&符号可选的,因为函数名在使用时候总是由编译器把它转换成指针;
调用函数:
int ans;
ans = f(25);
ans = (*pf)(25 );//*操作取出了函数名,这个转换不是必须的
ans = pf(25);
13.3.1回调函数
主要就是在单链表中查找一个值的时候,希望它可以查找不同类型的值,然后有两点
1 比较是否相等的话这里需要编写函数,然后把函数指针传递给查找函数,
2.往函数传递一个指向值的本身而不是值本身,可以使用void*形参
ps:在使用比较函数的指针之前,必须要转换为正确的类型
来举个例子
Node *search_list (Node *node, void const *value, int (*compare) (void const *, void const *))
{while (node !=NULL)
{
if ( compare( &node->value, value) == 0)
break;
node = node ->link;
}
return node;
}
比较参数定义
int compare_ints( void const *a, void const * b)//这里参数必须声明为void * 以匹配函数原型。
{
if( *(int *)a == *(int *)b )//这里强制转换为int *类型
return 0;
else
return 1;
使用的话就是
desired_node = search_list(root,&desired_value,compare_ints );
13.3.2 转移表
创建一个转换表,首先声明并初始化一个函数指针数组,唯一需要留心之处是确保函数原型出现在数组之前
double add( double, double );//如果不使用转换表的话就是使用switch那些,然后会有很多case
double sub (double, double);
double mul(double, double);
double (* oper_func []) (double, double) = {
add,sub, mul.....};
然后使用的时候就可以
result = oper_func[ oper ](op1,op2);
13.4 命令行参数
其实这里我并没有看懂 希望哪天有人看懂了来和我讲一下,要不然等我翻完linux书以后再回来看
13.5字符串常量
当一个字符串常量用于表达式中,编译器将指定字符的一份拷贝存储与内存的一个位置,并存储一个指向第一个字符的指针,
这里给了一个把整型值转换为字符,简单方法以前没有想过,计算机很有趣了
putchar("0123456789ABCDE"[value%16];
麻烦版方法:
reminder = value %16;
if( reminder < 10 )
putchar (reminder + '0');
else
putchar( reminder -10 + 'A');