在代码之中使用typedef声明有助于创建与平台无关的类型,隐藏C和C++语言中复杂和难以理解的符合类型,创造更为美观的代码。
但是typedef的使用却有一些很容易混淆的地方,简单的用法还可以,稍微复杂一些的用法我就搞不懂了。在网上搜了一些资料,
看了看,自己总结了一下。
一、谭浩强版的用typedef定义已有的类型名的别名的步骤如下:
(1)先按定义变量的方法写出定义体;
(2)将变量名换成新类型名;
(3)在最前面加typedef;
(4)之后就可以用新类型名去定义变量。
二、typedef用法
1、最简单的用法
如:typedef int myint;
myint sn; //相当于int sn;
是将myint作为int类型的同义词。
2、用typedef定义复合类型数组类型的同义词
如例所示typedef char WORD[20];
WORD w1, w2; //相当于char w1[20]; char w2[20];
则WORD就成了包含20个元素的char数组类型的同义词。
3、用typedef定义简单的复合的指针类型同义词
先看C和C++中指针类型纠结的定义。
char* pa, pb;
char *pc, *pd;
其中pa是char指针类型而pb不是,这多半不符合我们的常规理解方式,如果想要定义两个char指针,则必须像定义pc和pd那样;而且*的位置没有影响。
但是利用typedef我们却可以定义char*这种复合类型的同义词。如下所示:
typedef char * chPointer;
chPointer pi, po;这样pi和po都是char指针类型了。
这里还有一些需要注意的地方。如下:
有函数int myStrcmp(const char*, const char*) ;
如果定义Typedef char* pStr;而且声明myStrcmp()如下:
int myStrcmp(const pStr, const pStr),那么这将是错误的。因为函数原型中的参数是指向char常量的指针,而声明的却是指向char的指针常量。
对于这一点我想必须要理解typedef不只是简单的宏替换。应该从它所表示的意义上去理解。Typedef char* pStr定义的是一个指向char的指针,
所以const pStr中const修饰的是一个指针,也就是说const pStr 表示的是一个char型指针常量。
要解决不一致的问题可以这样:typedef const char* pStr;这样声明函数就变成了:
int myStrcmp(pStr, pStr);
4、typedef用于struct的用法
在旧的C的代码中声明struct新对象时,必须要带上struct,即形式为:
struct 结构名 对象名,如:
struct POINT
{
int px;
int py;
};
struct POINT pot;
而在C++中,则可以直接写:结构名 对象名,即:POINT pot;
为了在C代码的结构体声明中少写一个struct是代码更为紧凑和简约,就有了如下的声明方法:
typedef struct POINT
{
int px;
int py;
}POINT;
这样的一段代码实际上做了两件事情:
(1)
struct POINT
{
int px;
int py;
};
(2)
typedef struct POINT POINT;
以后就可以这样声明struct POINT类型的变量了:POINT pot;显得简约一点。
5、typedef隐藏复杂类型的用法
此种用法主要体现在定义函数型的指针上。关键点在于根据运算符的结合性,逐步理解其所代表的意义。
(1) 先看C语言中关于函数的声明
int Function(int ,char);
其对应的函数指针声明为:int (*Fp) (int,char);
当进行赋值时可以有以下形式:
Fp = &Function;函数调用时的形式为:(*Fp)(int, char)。
Fp = Function; 函数调用时的形式为: Fp(int, char)。
(2)再看C语言中关于数组的声明
int SN[6];
其对应的数组指针声明为int (*pS)[6];注意括号的使用,因为[]的优先级大于*。
使用方式为:pS = &SN; int a = (*pS)[0]。
(3)再看以下三个变量声明
#1 int* (*A[6])(char*,int*);
#2 void (*B[6])(int(*)());
#3 int(*)() (*P)[6];
然后再来分析以上声明所代表的意义。
#1
int* (*A[6])(char*,int*);
首先看变量名A,因为[]的结合性大于*,所以A首先是一个数组,然后每个数组元素都是一个指针;再看括号外边是一个函数的声明形式,所以A数组中的每一个元素都是指向函数的指针。这种函数返回值为int*型,参数形式为(char*,int*)。
用typedef来简化此种类型声明:
typedef int* (*pA)(char*, int*);
pA A[6];同int* (*A[6])(char*,int*);
#2
void (*B[6])(int(*)());
类似于#1,B是一个数组,每个元素是一个指针,这个指针指向一个函数,函数的返回值为void,参数为int(*)()(也就是一个函数,返回值为int无参数)。
用typedef来简化此种类型声明:
typedef void (*pB)(int (*)() );
pB B[6];同void (*B[6])(int(*)());
当然还可以逐步简化:
typedef int (*pi) ();简化指针指向的函数的参数;
typedef void (*pB)(pi);
pB B[6];同void (*B[6])(int(*)())。
#3
int(*)() (*P)[6];
首先P是一个指针,P指向了一个数组,这个数组的每一个元素为指向函数的指针,指向的函数类型是返回值为int无参数。
用typedef来简化此种类型声明:
typedef int(*pi)();简化数组的元素定义;
typedef pi (*PP)[6];
PP P;同int(*)() (*P)[6];
(4)2个模式:
type (*)(....) 函数指针 type (*)[] 数组指针
关键还在于根据运算符的结合性,理解typedef定义的类型的意义,C语言在很多类似的地方都让人纠结。