C 语言的申明总是令人头大, 对于这块内容也一直让我头疼. 希望通过这篇博客能够稍微梳理一下. 材料和例子来源于《C 专家编程》
一, C 语言的申明的优先级规则
先来个例子, 看看下面这行 C 代码到底是个啥玩意儿:
char * const *(*next)();
1.1 优先级规则
A 申明从它的名字开始读取, 然后按照优先级顺序依次读取.
B 优先级从高到低依次是:
B.1 声明中被括号括起来的那部分
B.2 后缀操作符:
括号 () 表示这是一个函数, 而方括号表示这是一个数组.
B.3 前缀操作符: 星号 * 表示 指向... 的指针.
C 如果 const 和(或)volatile 关键字的后面紧跟类型说明符(如 int,long 等), 那么它作用于类型说明符. 在其它情况下, const 和(或)volatile 关键字作用于它紧邻的指针星号.
1.2 分析 char * const (next)();
首先, 看变量名是 "next", 并注意到它直接被括号括住(A)
把括号括住的东西看作一个整体(*next), 得出 "next 是一个指向... 的指针"(B.1)
然后考虑括号外面的东西, 在星号前缀和括号后缀之间做出选择:
B.2 规则告诉我们优先级较高的是右边的函数括号, 所以得出 "next 是一个函数指针, 指向一个返回... 的函数"(B.2)
然后, 处理前缀 * 号, 得出指针所指的内容
最后, 把 "char * const" 解释为指向字符的常量指针
所以最后得出: next 是一个指针, 它指向一个函数, 该函数返回另一个指针, 该指针指向一个类型为 char 的常量指针.
虽然能够搞明白, 并且有规则可循. 但还是不得不吐槽, C 的申明也太复杂了. 哎~~~
二, typedef
2.1 使用 typedef 为你的申明做简化
看系统调用 signal 函数的申明:
void (*signal(int sig, void(*func)(int)))(int);
先不看 signal 括号里面的东西:
void (*signal( ))(int);
可以看出来, signal 是一个函数, 然后它返回一个指针; 该指针所指向的函数接受一个 int 参数, 并返回 void. 我们再来看 signal 括号里面的东西, 第一个参数不用解释, 来看第二个参数:
void(*func)(int)
不难看出 func 是一个函数指针, 指向的函数接受一个 int 参数, 返回 void. 接下来让我们用 typedef 来简化它:
- /* ptr_ti_func 是一个函数指针, 该函数接受一个 int 参数, 返回 void. */
- typedef void(*ptr_to_func) (int)
- // 接着再申明之前的那个 signal
- ptr_to_func signal(int, ptr_to_func);
- 2.2 typedef VS #define
- #define 只是做替换而已; 而 typedef 是真正的封装 -- 申明它之后, 不能再往里面增加东西. 举两个例子:
例子 1:
- #define myInt int
- usigned myInt i; // 可以没问题, 就是文字替换而已: unsigned int i;
- typedef int myInt;
- usigned myInt i; // 非法, 不可以在 myInt 里面加 usigned 了.
例子 2:
- #define int_ptr int *
- int_ptr a,b; //a 是 int * 类型, b 是一个 int;
- typedef int * int_ptr;
- int_ptr a,b; //a 和 b 都是 int * 类型.
最后想说一下作者本身对这个也只是初步了解, 如有理解错误欢迎反馈!!
See you next time. Happy Coding!!!
我的 GitHub
来源: https://www.cnblogs.com/dnhua/p/10126914.html