您的位置:首页 > 编程语言 > C语言/C++

C语言声明及typedef常见用法

2014-04-03 23:20 316 查看
C语言声明的优先级规则

A 声明从它的名字开始读取,然后按照优先级顺序依次读取

B 优先级从高到底依次是:

B.1 声明中被括号括起来的那部分

B.2 后缀操作符:

括号()表示这是一个函数,而

方括号[]表示这是一个数组

B.3 前缀操作符:星号*表示“指向...的指针”

C 如果const和 volatile 关键字的后面紧跟类型说明符(int long等)它作用域类型说明符,其他情况下,const 和 volatile关键字作用于它左面紧邻的指针星后。

通过上述规则分析下面C语言声明:

char * const *(*next)();

next是一个指针,它指向一个函数,该函数返回一个另一个指针,该指针指向一个类型为char 类型的常量指针

typdef:它为一种类型引入新的名字,并没有创建新的类型

一般情况下,typedef用于简洁地表示指向其他东西的指针。典型的例子是signal()原型的声明

void (*signal(int sig, void (*func)(int)))(int)

signal是一个函数,它返回一个函数指针,这个函数指针指向的函数接受一个int参数并返回void。

可通过typedef做如下改变

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

C语言存在多种名字空间:

标签名(label name)

标签(tag):这个名字空间用于所有的结构、枚举和联合

成员名:每个结构或联合都有自身的名字空间

其他

在同一个名字空间里,任何名字必须具有唯一性,但在不同的名字空间里可以存在相同的名字。由于每个结构或者联合具有自己的名字空间,所以同一个名字可以出现在许多不同的结构内。

typdedef struct my_tag{int i;}mytype;

struct my_tag var1;

mytype var2;

这个typedef声明引入了mytype这个名字作为"struct my_tag{int i;}"的简写方式。但它同时引入了结构标签my_tag,在他前面加个关键字struct可以表示同样的意思。

typedef struct fruit {int weight;}fruit; 语句1

struct veg{int weight;}veg; 语句2

它们代表的意思完全不一样,语句1声明了结构标签fruit和typedef声明的结构类型fruit;实际效果如下

struct fruit mandarin;

fruit mandarin;

语句2声明了结构标签veg和变量veg,只有结构标签能够在以后的声明中使用,如

struct veg potato;

如果试图使用veg cabbage这样的声明,将是一个错误。这有点类似下面的写法:

int i;

i j;

typedef和宏文本替换之间的区别。可以把typedef看成是一种“封装”类型----在声明之后不能再往里面增加别的东西。它和宏的区别体现在两个方面

1、可以用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做。

#define peach int

unsigned peach i; 没问题

typedef int peach;

unsigned peach i; 语法错误

2、连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变量均为同一种类型,而用#define定义的类型无法保证

#define int_ptr int *

int_ptr chalk, cheese;

经过宏扩展

int *chalk, cheese;

chalk是一个指针,cheese是一个整型。

typedef int* int_ptr;

int_ptr chalk,cheese;

chalk,cheese都为整型指针

枚举类型

enum sizes { small = 7, medium, large = 10, humungous};

缺省情况下,整型值是从零开始。如果对列表中的某个标识符进行了赋值,那么紧接其后的那个标识符的值就比所赋的值大1,然后类推

枚举中的成员可以当做宏一样直接使用,相比宏定义枚举具有一个优点:#define定义的名字一般在编译时被丢弃,而枚举名字则通常一直在调试器中可见,可以在调试代码时使用它们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: