c语言的声明
1.C语言采用 “声明的形式与使用的形式相似” 这种用法,这并非好主意,因为二者是截然不同的东西,同时C语言的声明存在的最大问题是无法让人用一种习惯性的自然方式即从左到右的顺序去阅读,这很令人不快。
“声明的形式与使用的形式相似”这种做法的好处是各种不同的操作符的优先级在“声明”与“使用”中是相同的,然而,操作符的优先级本身就是C语言中一个设计不当、过于复杂的部分。
- int *p[3] // p是int类型的指针数组
- int (*p)[3] //p是一个指向int数组的指针 p = (int ( *) [3])malloc(3)此时去掉 *两边看似多余的括号会报错。
2.C语言中合法的声明存在限制条件:
- 函数的返回值不能是一个函数,但允许是一个函数指针;
- 函数的返回值不能是一个数组,但允许是一个数组指针;
- 数组里面不能有函数,但允许有函数指针;
- 数组里面允许有数组。
3.结构(struct)、联合(union)和枚举(enum)
-
结构(struct)的通常形式:
struct 结构标签(可选){ 类型1 标识符1; 类型2 标识符2; ... 类型N 标识符N; }变量定义(可选);
虽然如此,但推荐结构的声明与变量的定义分开写,便于阅读,如下:
struct a_tag { int aa,bb,cc; }; struct a_tag p;
-
联合(union)的通常形式与结构相似,只是用union关键字代替了struct关键字,联合中的数据项是不会同时出现的,这是与结构的区别
-
枚举(enum)通过一种简单途径将一串标识符与一串整型值联系在一起,其一般形式为:
enum 可选标签 { 内容 } 可选变量定义;如:enum sizes{ small,middle = 2, large = 4,humungous };
缺省情况下整数值从0开始,如果某个标识符进行了复制,那么其后的标识符的值就比赋的值大1
4.理解C语言声明的优先级规则。
-
声明从它的名字开始读取,然后按照优先级顺序一次读取;
-
优先级从高到低依次是:
- 声明中被括号括起来的那部分;
- 后缀操作符:括号() 表示这是一个函数,方括号[]表示这是一个数组;
- 前缀操作符:星号*表示这是“指向…的指针”;
-
如果const或volatile关键字后面紧跟类型说明符(如int,long等),那么它作用于类型说明符,其他情况作用于它左边的星号*。
举例说明:char * const * (*next) (); – next 是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个char类型的常量指针。
5.typedef的作用
typedef为数据类型创建别名,而不是创建新的数据类型,可以对任何类型进行typedef声明。
typedef运用得当可简化复杂代码,如:
void (*signal(int sig,void (*func)(int)))(int);//signal函数声明
//这个声明很复杂,可以使用上面的方法理解
//signal是一个函数,它返回一个函数指针,该指针指向的函数接收一个int参数并返回void
//而signal的第二个参数也是一个函数指针,接收一个int返回void(即本身)
//我们可以通过typedef简化这个声明
typedef void(*ptr_to_func)int;//ptr_to_func即是一个函数指针
ptr_to_func signal(int ,ptr_to_func);//此时便简化了许多,也便于阅读。
- typedef与#define的区别:
- 首先,最显而易见的区别即是它们的两个“参数”位置相反,而且typedef语句末尾要加“;”
- 可以用其它类型说明符对宏类型名进行扩展,但对typedef定义的类型名却不能这样做,如:
#define x int unsigned x i;//正确 --分割线-- typedef int x; unsigned x i;//错误
- typedef能保证声明中的变量均为同一种类型,但#define不能,如:
typedef int* int_ptr; int_ptr p1,p2;//p1,p2均为int*类型 --分割线-- #define int_ptr int* int_ptr p1,p2;//p1是int*类型,但p2是int类型
6.一个问题
对于结构A,声明变量的时候见过A a
和struct A a
,第二种struct是否多此一举呢?当然不,当我们仅仅定义结构A时,即struct A{...};
接下来定义变量需要使用struct,而如果我们这样声明typedef struct A{...} A;
我们便可以使用A a
来定义变量了;注意二者区别,前者A为结构标签,后者A为typedef声明的结构类型。还有一点,struct A {...} A; A a;
这是错误的,因为后一个A已经是一个变量了,而不是变量类型。