写C和C++时,声明变量是个必需的工作,自己写出来的还好。但经常需要看别人写的代码,怕就怕写的人不顾及你这个读者的感受,真的写出一堆看上去连语法都不清楚的代码来,尤其是对我们这些记忆力已经开始减退的来说更是个挑战。尤其C++在C的基础上难上加难,使得我不得不花些时间总结了一下,仅限于比较常用的,真那种完全为了考试而编出来的东西不在这个范围之列。
看一个变量的声明,
1. 第一步你要知道什么样的语句是一个声明。通常来说,一个声明是以类型名,或者const,volatile这样的type modifier,又或者extern,auto,static,typedef这些表明storage种类的东西来开头,还有特殊数据结构class,struct,union,enum这些东西,好在这些还不属于能把人搞昏的东西
2. 找出语句中所要声明的变量名,略过关键字啊类型名之后留下来的应该就是要找的变量名了,然后按照从右往左的原则来进行分析。一般来说,变量名的右边基本上都是括号类的东西,各种括号,圆括号”(“表示是一个函数,方括号”["表示是一个数组,花括号"{"表示是一个函数,尖括号"
3. 如果变量明的右边有结束括号,那便需要先把这个括号里的内容读完,然后在看结束括号右边的东西,然后再回到左边,反复下去,慢慢体会吧
下面举一些例子来说明一下
int const * volatile data;
首先找到变量名是data,所以从data开始,从右往左看,得到的结果为data是一个volatile指针,指向const int
double * const data[5]
先看变量名,还是这个data,但它右边是方括号,说明是个数组,从data的右边往左看,说明是一个const指针,指向double,所以最终结论为data是一个数组,这个数组有5个指向double类型的const指针
double (* const data)[5]
这回又多了一对圆括号,所以要先把这个括号里面的内容处理完,也是从右往左的顺序。总的顺序是先看(* const data),再看[5],最后以double结束,所以最终的结论为,这个data是一个const指针,指向一个包含5个double类型的数组
接下来看看函数指针
double & (* data)(int, double, void (*)(int));
data是个函数指针((* data)这部分内容),这个函数有三个参数,int,double,和一个需要int参数返回void的函数指针(void (*)(int)),所以总的理解是说data指向一个函数,这个函数有上面的三个参数,函数返回的是一个double类型的引用(&)
在用到函数指针的时候,最好用typedef来重新定义一个名字,这样阅读性会提高很多,比如qsort(3)这个函数,在stdlib.h头文件中声明
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
qsort需要4个参数,从哪里开始,元素的个数,每个元素多大和一个使用的比较函数
第四个参数就是使用了函数指针,但阅读性比较低,所以用一下typedef,像下面这样,
typedef int (* compare_function_t)(void const *, void const *); void qsort(void *base, size_t nmemb, size_t size, compare_function_t compare);
这样确实会好很多,还有一些比如会用到函数指针数组这种比较变态的写法,也建议用typedef过一下
typedef double (* func_ptr)(int); func_ptr data[10];
肯定还有遗漏掉的,不过对日常的编程工作来说差不多够用了