1. C和C++语言中的优先级规则
C语言中语言声明的优先级规则如下(以后分析的基础):
A 声明从它的第一个名字开始读取,然后按照优先级顺序依次读取
B 优先级从高到低依次是
B. 1 声明中被括号括起来的那部分
B. 2 后缀操作符:
括号()表示这是一个函数
方括号[]表示这是一个数组
B. 3 前缀操作符:星号*表示“指向……的指针”
下面我们使用上述规则来分析以下例子
(1) char * const *(*next)();
(2) char* (*c[10])(int **p)
一步步分析:先分析括号里面的内容,我们知道C是一个数组,保存的是“…..的指针”然后根据规则B,要先分析后缀,得到指针是一个函数指针。该函数参数为P返回值为char*。最后得到:C是一个数组元素,它的元素类型是函数指针,其所指向的函数的返回值是一个指向char的指针。
(3) void(*signal(int sig,void(*func)(int)))(int);
从signal所在的括号开始提取:void(*signal( ) )(int); 首先signal后缀跟的是括号,我们得到signal是一个函数, 然后得到前缀为* 表示此函数返回的是一个”……指针”…………最后得到signal是一个函数,返回函数指针,函数所指向的指针接受一个int类型的参数并且返回void。
然后我们看signal函数参数本身: void(*func)(int) 表示func是一个函数指针,此指针指向的函数接收一个int参数,返回值是void。
如果我们定义typedef void(*ptr_to_func)(int)则表示 ptr_to_func是一个函数指针,该函数接受一个int参数,返回值为void 那么上述函数可以写为
ptr_to_funcsignal(int sig, ptr_to_func); 表示 signal 是一个函数 ,接收参数为int和 ptr_to_func,返回ptr_to_func ;
2. typedef int x[10]与 #define x int[10]的区别
typedef与宏文本替换之间存在关键性的区别。如下:
第一: 可以用其他类型说明符对宏名进行扩展,但对typedef所定义的类型名却不能这样做。 如下:
#define peach int
unsigned peach i ; // 可以
typedef int banana;
unsigned banana i ; // 错误
第二:在连续声明的变量中用typedef定义的类型能够保证声明中所有变量均同一种类型,而用#define定义的类型却无法保证。 如下:
#define int_ptr int*
int_ptr chalk, cheese;
经过宏扩展,第二行变为:
int *chalk, cheese; 这使得chalk 与cheese为不同的类型。chalk为int类型的指针,而cheese只是int类型变量。
typedef char * char_ptr;
char_ptr Benley, Royce ; Benley,和Royce类型是相同的。都是指向char的指针
原因: #define在编译时仅仅是名称替换而typedef可以被看成一个彻底封装的“类型”。在了解typedef 中变量具体表达什么意思的时候可以按照前面说的优先级规则进行解析。
3. 指针与typedef
typedef中使用指针往往带来意外的结果。例:
typedef string *pstring;
const pstring cstr;
c_str究竟代表什么类型。我们知道pstring是指向string的指针很多人都会误认为真正的类型是const string* cstr。错误原因是将typedef当成#define 直接进行文本扩展了,其实const修饰的是 pstring 而pstring是一个指针,因此,正确的等价形式应该是
string *const cstr;
--------------------------------------分割线 --------------------------------------
C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码
将C语言梳理一下,分布在以下10个章节中:
Linux-C成长之路(十):其他高级议题