K&R书中“PFI strcmp, numcmp;”写法是否符合C语言规范?
K&R《C程序设计语言》函数指针typedef问题解析
1. PFI strcmp, numcmp;的实际场景
K&R这里的写法不是用来声明函数本身,而是声明函数指针变量。在第5章的排序程序中,需要把比较函数的指针传递给排序函数(比如自定义的qsort),此时用PFI这个typedef来声明指针变量会更简洁。
举个贴合场景的代码示例:
// 先定义或声明比较函数 int strcmp_custom(char *s1, char *s2); int numcmp(char *s1, char *s2); // 用PFI定义函数指针类型别名 typedef int (*PFI)(char *, char *); // 声明函数指针变量 PFI cmp_func; // 根据需求给指针赋值(函数名会自动转为指针) cmp_func = strcmp_custom; // 将指针传递给排序函数 qsort(str_array, count, sizeof(char*), cmp_func);
你之前尝试用PFI lencmp;后直接定义int lencmp(char*, char*){...}报错,是因为误将指针变量声明当成了函数声明——PFI是指针类型,而函数定义是函数类型,二者类型不匹配,自然会冲突。
2. 该写法是否合法?
完全合法。typedef int (*PFI)(char*, char*);定义了一个函数指针类型的别名,PFI strcmp;就是声明一个名为strcmp的变量,其类型是指向int(char*, char*)类型函数的指针。需要注意:如果在同一作用域同时存在标准库的strcmp函数和这个指针变量,会出现名字冲突,但K&R的代码场景中要么是自定义strcmp,要么是在局部作用域使用该声明,所以不会有问题。
3. 是否属于K&R的语义错误?
不算语义错误,只是表述不够严谨。K&R原文没有明确强调这是函数指针变量声明,容易让读者误解为是在声明函数本身,但结合排序程序的上下文来看,用法意图是清晰的——就是为了简化函数指针变量的声明,而非函数声明。
4. 为何不采用函数类型的typedef?
你提到的typedef int FI(char *, char *);确实可以用来声明函数(比如FI strcmp;等价于int strcmp(char*, char*);),但K&R的场景核心是使用函数指针,而非声明函数:
- 如果用函数类型typedef,声明函数指针需要写成
FI *cmp_ptr;,而用指针类型的typedefPFI,直接写PFI cmp_ptr;更简洁,符合K&R追求代码简洁的风格; - 早期C语言编程习惯中,更倾向于直接typedef函数指针类型,以此规避函数指针复杂的语法结构,提升代码可读性;
- 排序程序的核心需求是传递函数指针,所以重点展示指针类型的typedef用法更贴合场景。
内容的提问来源于stack exchange,提问作者Lover of Structure
相关产品推荐
相关产品推荐

