1. 奇特的申明
先来看看以下这些奇特的声明,你能一眼就明白他们什么意思吗?int p[3][4];int **p;int *p[3];
int (*p)[3];
int *p[3][4];
int (*p)[3][4];
int (* p[3])[4];
int (* p)();
int (* p[3])();
我先来告诉你第一个
首先p是含有3个元素的数组,然后3元数组里的元素是含4个元素的数组,最后4元数组里元素是int型的变量,也就是说p是3×4的int型二维数组。根据我讲述的顺序,大家应该明白其中的逻辑,下面来说明一下弄清每个声明的规则,关键在于修饰符的顺序:
表示数组[]与函数的()有同样的优先级,*修饰符优先级低于[]和(),并且都是自左向右的结合顺序。
基于这两条规则,我们来说明一下其余声明的含义:
int *p[3]; 分析: p是含有3个元素的数组 => 每个元素都是一个指针 => 指针指向int型变量
总结: p是含有3个int指针型的数组
int (*p)[3];分析: p是一个指针 => 该指针指向包含3个元素的数组 => 数组元素的类型是int型
总结: p是指向含有3个int型数组的指针
int *p[3][4];分析: p是含有3个元素的数组 => 每个元素是含有4个元素的数组 => 每个元素都是一个指针 => 指针指向int型变量
总结: p是含有3×4个int指针型的二维数组
int (* p[3])[4];
分析: p是含有3个元素的数组 => 每个元素是一个指针 => 每个指针指向4个元素的数组 => 每个元素是int型变量
总结: p是含有3个指向int型数组(含有4个元素)的指针数组
int (* p)();分析: p是一个指针 => 该指针指向一个函数 => 函数的类型是int型
总结: p是一个int型的函数指针
int (* p[3])();分析: p是含有3个元素的数组 => 每个元素是一个指针 => 每个指针指向一个函数 => 函数的类型是int型
总结: p是一个含有3个int型的函数指针的数组。
2. 理解const修饰符
上面对一些C语言中一些奇怪的声明进行了不厌其烦的解释,是不是就完事了呢,不是,还有...奇怪的const,仍然要问你,下面一些声明是什么意思:const int * p;
int * const p;
const int * * p;
int * * const p;
int * const * p;
其实有个很简单的规则来理解上面的const,就是const中总是修饰它的前一个位置的修饰符,什么意思呢,举例说明:
【int * * const p;】这个const是修饰前面的int **,也就是说经其修饰之后的变量,如下操作是非法的,【p = xx;(xx是一个int**型的变量)】,同理对于【int * const * p;】,【*p = xx;(xx是一个int*型的变量)】是非法的;对于【int const * * p;】,【**p = xx;(xx是一个int型的变量)】是非法的。又有兄弟问那对于【const int * * p;】,【**p = xx;(xx是一个int型的变量)】也是非法的,该怎么解释,我只能说,由于const前面已经没路了,或者说前面有倒墙,const没办法,只能回来继续修饰int。顺带说一下另一种情况,我在网上看到有这样的写法【int * p const;】,我在gcc编译是不通过的,应该是网上错了。
注:关于const这一段,完全是自己找的规律,如有错误,望请通知,我好纠正。3. const的作用 【本部分来源于网络】
- 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
- 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
- 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。
阅读(1239) | 评论(0) | 转发(0) |