一、符号 *、()、[]

(摘取自 C Primer Plus 第6版 中文版 14.13)

1. 声明时这几个符号的含义:

* 表示一个指针
() 表示一个函数
[] 表示一个数组

2. 优先级规则:

(1)数组名后面的[]和函数名后面的()优先级相同,它们比*的优先级高
(2)[]和()的优先级相同
(3)[]和()都是从左往右结合

3. 根据上述规则,示例:
int goods[12][50]; // 声明一个由12个内含50个int类型值的数组组成的二维数组--规则(3)
int ** ptr; // 声明一个指向指针的指针,被指向的指针指向int
int * risks[10]; // 声明一个内含10个元素的数组,每个元素都是一个指向int的指针--规则(1)
int (* rusks)[10]; // 声明一个指向数组的指针,该数组内含10个int类型的值--规则(2)
int * oof[3][4]; // 声明一个3×4的二维数组,每个元素都是指向int的指针--规则(1)(3)
int (* uuf)[3][4]; // 声明一个指向3×4二维数组的指针,该数组中内含int类型值
int (* uof[3])[4]; // 声明一个内含3个指针元素的数组,其中每个指针都指向一个内含4个int类型元素的数组
二. 函数指针与函数及typedef的应用:

(摘取自 C Primer Plus 第6版 中文版 14.14,14.12)

1. 函数指针:

(1)即指向函数的指针,其中储存着函数代码的起始处的地址
(2)必须声明指针指向的函数类型,即函数的返回类型和形参类型

2. 声明一个指向某类型函数的指针,并赋值和使用:

(1)写出该类型函数的原型;
(2)把函数名替换成(*pf)形式的表达式,注意必须把*和指针名括起来(由于*与()的优先级);
(3)则pf是指向该类型函数的指针,可以把类型匹配的函数地址(如函数名)赋给它;
(4)用函数指针访问函数时:有(*pf)(参数)和pf(参数)两种语法,K&R C不允许后者的形式。
如:

void ToUpper(char *); // 该函数的类型是“带char * 类型参数、 返回类型是void的函数”
void ToLower(char *);
  • 把函数名ToUpper替换为表达式(*pf),表明pf是一个指向函数的指针,因此,(*pf)是一个参数列表为(char *)、 返回类型为void的函数。
void (*pf)(char *); // pf是一个指向函数的指针,指向该函数类型
char mis[] = "Nina Metier";
pf = ToUpper; // 有效,ToUpper是该类型函数的地址
(*pf)(mis); // 把ToUpper 作用于(语法1)
pf = ToLower; //有效,ToLower是该类型函数的地址
pf(mis); // 把ToLower 作用于(语法2,K&R C不允许该形式)
3. 函数指针作为函数的参数及对应函数调用,如:
// 函数声明:fp形参是一个函数指针,str是一个数据指针。 
void show(void (* fp)(char *), char * str);
// 函数使用:传入参数
show(ToLower, mis); // show()使用ToLower()函数:fp = ToLower;
show(pf, mis); // show()使用pf指向的函数:fp = pf;
// show函数中:用fp指向的函数作用于str
(*fp)(str);
4. typedef:

typedef 可以为某一类型自定义名称(如某结构体类型,函数指针类型等),不能用于值,由编译器解释,在类型上比#define更灵活不易错,作用域取决于其定义位置,能提高程序的可移植性。如:

// 若无typedef或#define
char * STRING; // STRING为一个指向char的指针变量
// 若为typedef
typedef char * STRING; // 编译器则把STRING解释成一个类型的标识符,该类型是指向char的指针
STRING name, sign; // 相当于char * name, * sign;
// 若为#define
#define STRING char *
STRING name, sign; // 相当于char * name, sign; 即只有name才是指针

// 把FRPTC声明为一个函数类型,该函数返回一个指针,该指针指向内含5个char类型元素的数组
typedef char (* FRPTC()) [5]; 

// 作为函数参数
typedef void (*V_FP_CHARP)(char *);
void show (V_FP_CHARP fp, char *); // 否则声明为 void show(void (* fp)(char *), char * str);
V_FP_CHARP pfun;
V_FP_CHARP arpf[4] = {ToUpper, ToLower, Transpose, Dummy}; // 声明并初始化一个函数指针的数组