本Blog的第一篇技术性文章,为了避免虎头蛇尾的情况出现,我打算开个蛇头(虽然我比较害怕蛇这种生物。。。。)。
简单的理解关于C/C++指针的语法,以及一些声明。起初学C语言的时候,我就经常被这坑爹语法所坑,例如
//eg. int (*p)[3]; double (*p)(int a);
后来看了一些书,对此就慢慢熟悉了。所以,以此开头写一篇小文章,也算是温习了。
首先我们看对于变量的声明,变量是我们在编写程序中不可避免需要使用到的,例如
//eg. int x; char ch;
等等。首先在c/c++中有一些基础类型的变量,例如int类型、double类型,再次基础上衍生出各种派生类型的变量,例如int型指针变量,数组。由此衍生出了各种坑爹的语法,那么如何阅读呢,我们先看一下阅读规则。
阅读声明首先要阅读变量的名字,例如int *x里面的x
第二步是最重要的,从变量名最近的地方开始,依照符号优先级依次解释类型,这个优先级是
1.用于整理声明的小括号//ps:就像数学运算里面的小括号一样,先算括号里面的
2.用于表示数组的[]和用于表示函数的()//这两个是同级的,如果同时存在,那么他们的阅读顺序是从左向右
3.用于表示指针的*
这里有一个小理解,就是说我们首先给这个变量确定一个类型,然后再在变量前面加形容词,例如我们首先确定x是一个指针,然后我们再说x是一个xxx的指针,首先确定是什么,然后再去描述它
最后一步我们用自然语言连接,附上最左边的类型修饰符就好了。
看起来很麻烦,我们举几个例子实操一下
//eg. int x[10];//x是一个数组 这个数组有10个元素组成 附上最左边的类型解释,这是一个由10个int组成的数组 int x[10][3];//x是一个数组(元素*10),从左向右解释,追加形容词,x是一个数组(元素*3)的数组(元素*10) //其实二维数组就是数组的数组 int *x[10]//注意到,x左边是*右边是{],都是紧邻着x,那么我们就要看优先级,[}的优先级高于* //所以我们首先解释[],x是一个数组,然后我们再附加描述,x是一个int指针组成的数组 int (*x)[10]//和上面相比只多了一个(),但是小括号里面的要优先解释,所以我们说x是一个指针 //然后再附加描述,x是一个什么什么样的指针,x是一个指向数组的指针,什么数组呢?是10个int组成的数组 int x(int *a)//x是一个函数,函数的参数是int *a,返回值是int int *x(int *a)//x是一个函数,函数的参数是int *a,返回值是int * int (*x)(int *a)//x是一个指针,指向一个函数,这个函数的参数是int *a,返回值是int int (*x[10])();//x是一个数组,数组由指针组成的,指针指向没有参数的函数,且该函数的返回值为int
关于最后一个函数指针,贴一个代码
//innsd #include <iostream> void f1(); void f2(); void f3(); using namespace std; int main() { void (*p[3])(); p[0] = f1; p[1] = f2; p[2] = f3; (*p[0])(); (*p[1])(); (*p[2])(); return 0; } void f1() { cout << "f1" << endl; } void f2() { cout << "f2" << endl; } void f3() { cout << "f3" << endl; }
输出结果为:f1 f2 f3,无编译错误。
解读c/c++中的声明如抽丝剥茧,掌握顺序之后一路剥开即可。