分类: C/C++
2012-03-30 00:15:58
声明:本博文内容主要都来自于《Linux C编程一站式学习》
1.指针数组和指向数组的指针
先看看 int * a[10] 和 int (*a)[10]之间的关系。
int *a[10] 表示的是a是一个数组,数组里面存储的是int * 指针,即该表达式的意思是一个指针数组,这个数组中的每个元素都是指向int型的指针;
int (*a)[10] 表示的是 a 是一个指针, int [10] 是一种类型,即a是指向有10个元素的的数组指针。
int *a[10]; int ** p = &a[0]; // 或者 int**p = a ; 从上面的例子可以看出后面两个表达式是等价的2. 函数指针
void say_hello(const char* str ){ printf("");}int main(){ void (*f)(const char*) = say_hello; f("hello world"); return 0 ;}void (*f)(const char*) 声明了一个函数指针,该指针指向参数为 const char* ,返回值为void 的函数类型。其中say_hello恰好是这种类型的函数,将其地址赋给该指针。Note: say_hello是一种函数类型,函数类型跟数组类型相似,做右值时可以自动转化成函数指针类型,因此可以直接赋给f;也可以写成 void (*f)(const char*) = &say_hello;其效果是一样的。3. 下面区分函数类型和函数指针类型首先定义函数类型: typedef int F(void) ; 再申明该函数类型的变量: F f , g ;上面的等同: int f(void)int g(void)如果再申明: F h(void) 就错误了!函数可以返回void类型、标量类型、结构体或者联合体,但是不能返回函数类型。看下面一定义:F *e(void)申明的该函数是返回F*一个函数指针,其中指针为标量,只有大小之分。下面看一个函数指针:int (*f)(void) 是定义了一个函数指针,我们可以将这个函数指针定义一个类型名叫做FP:typedef int (*FP)(void) 假设这个有个函数地址,真好指向这种类型的某个函数,Ox12345678,我们强制转换成一个函数指针并且调用它,两种方式都是正确的:1. ((FP)0x12345678)()2. (*(FP)0x12345678)()上面不用类型名,直接用函数类型也可以实现强制转换:1. ((int (*)(void))0x12345678)()2. (*(int (*)(void))0x12345678)()4.用函数指针实现函数的选择实现double rect_real_part(struct complex_struct z){ return z.a;}double rect_img_part(struct complex_struct z){ return z.b;}double rect_magnitude(struct complex_struct z){ return sqrt(z.a * z.a + z.b * z.b);}double rect_angle(struct complex_struct z){ double PI = acos(-1.0); if (z.a > 0) return atan(z.b / z.a); else return atan(z.b / z.a) + PI;}double pol_real_part(struct complex_struct z){ return z.a * cos(z.b);}double pol_img_part(struct complex_struct z){ return z.a * sin(z.b);} double pol_magnitude(struct complex_struct z){ return z.a;}double pol_angle(struct complex_struct z){ return z.b;}double (*real_part_tbl[])(struct complex_struct) = { rect_real_part, pol_real_part };double (*img_part_tbl[])(struct complex_struct) = { rect_img_part, pol_img_part };double (*magnitude_tbl[])(struct complex_struct) = { rect_magnitude, pol_magnitude };double (*angle_tbl[])(struct complex_struct) = { rect_angle, pol_angle };#define real_part(z) real_part_tbl[z.t](z)#define img_part(z) img_part_tbl[z.t](z)#define magnitude(z) magnitude_tbl[z.t](z)#define angle(z) angle_tbl[z.t](z)由上面的例子,根据条件实现选择功能,但是将每个功能都具体分配到每个函数中,每个函数实现其简单的功能。通过一个检索信息来选择实现哪一个函数,使函数实现功能单一化,不会兼顾多种情况,是代码“高耦合,低内聚”,更好的重用原来的代码。5.复杂声明的解析在分析复杂声明时,通常要借助typedef把声明分解成几种基本的形式。分析下面的例子 int (*(*fp)(void *))[10]a.首先定义 typedef int (*T(void *))[10] ; T1 *fp ;b.即上面的式子可以写成 : T *fp , 其中T应该是一个函数类型,参数是void *,返回值是T2类型 ;typedef int (*T2)[10] ;typedef T2 T1(void*) ; T1 *fp;c. T2和*及括号在一起,应该是个指针;typedef int T3 [10];typedef int (*T2)[10] ;typedef T2 T1(void*) ; T1 *fp;