一.简介
关于typedef关键字,以前刚刚学C语言的时候,用它来重定义结构体别名。之后的话就是在用函数指针的时候用过一些,然而并不知道这个还有什么用处。今天花点时间总结一下typedef的细节。
在计算机编程语言中用来为复杂的声明定义简单的别名,与宏定义有些差异。简单来说,就是用来给一个复杂变量定义一个好记一点的名字。另外,使用typedef可以简化一些复杂的声明。
二.typedef的用途
1.定义类型别名,而不是简单的替换
typedef的第一个功能是定义类型的别名,比如Int*,比较麻烦,我们可以直接定义成pINt代表int型指针。而这种typedef
// C++Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//typedef与#define的区别:
typedef int* TPINT;
#define DPINT int*
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1, b = 2;
//使用typedef的TPINT,两个都是指针
TPINT tpa, tpb;
tpa = &a;
tpb = &b;
cout<<"a by pointer: "<<*tpa<<" b by pointer: "<<*tpb<<endl;
//使用#define的只是简单的替换,第二个并不是pointer
//这句话相当于int *dpa, dpb;
//dpb是int类型的变量!!!
DPINT dpa, dpb;
dpa = &a;
dpb = b;
cout<<"a by pointer: "<<*dpa<<"b by value: "<<dpb<<endl;
system("pause");
return 0;
}
结果:
a by pointer: 1 b by pointer: 2
a by pointer: 1b by value: 2
请按任意键继续. . .
这里,使用typedef的话,所有定义的TPINT都是int*类型的,而#define仅仅是在编译的时候,将DPINT替换成了int*,后面的变量dpb就变成了int类型!!!所以,还是typedef靠谱一点!
2.定义平台无关类型
我们知道,编译宏可以很好的控制编译流,我们在编译跨平台程序的时候,很多时候是靠编译流的。编译流一般都是一些宏定义来控制。其他功能免不了用#define,但是类型定义有更好的typedef,所以关于类型的定义,我们完全可以使用typedef来替换#define
比如,在一些机器上,int为16位,long为32位,那么我们可以这样定义:
typedef int INT16
typedef long INT32
但是,有的机器上变成short位16位,int 32位,long变成了64位,那么我们如果想要运行的话,只能用short和int了,而我们使用了typedef,就可以很轻易的改typedef,而完全不需要大改项目:
typedef short INT16
typedef int INT32
3.为复杂声明定义一个简单的别名
typedef可以为复杂声明定义一个简单的别名,比如:
我们要定义一个装着MyObj对象的list,那么,每次定义的时候都要写出:
std::list<MyObj> objList;
但是,如果有typedef的话,就可以省去不少麻烦:
typedef std::list<MyObj> ObjList;
ObjList objlist;
不过,最明显的还是在用函数指针的时候。看一个例子:
不用typedef时,定义函数指针是介个样子滴:
// C++Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//函数
void testfunc(int x)
{
cout<<"x = "<<x<<endl;
};
int _tmain(int argc, _TCHAR* argv[])
{
//定义一个函数指针
void (*pfunc1)(int x);
void (*pfunc2)(int x);
pfunc1 = testfunc;
pfunc2 = testfunc;
pfunc1(1);
pfunc2(2);
system("pause");
return 0;
}
这个函数目前只有一个参数,看起来都够麻烦了,那么如果有一大堆的参数,简直不忍直视!!!
而typedef闪亮登场之后:
// C++Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//函数
void testfunc(int x)
{
cout<<"x = "<<x<<endl;
};
//使用typedef来重命名函数指针
typedef void (*pFunc)(int x);
int _tmain(int argc, _TCHAR* argv[])
{
//这下定义一个函数指针就简单多啦!!!
pFunc pfunc1;
pFunc pfunc2;
pfunc1 = testfunc;
pfunc2 = testfunc;
pfunc1(1);
pfunc2(2);
system("pause");
return 0;
}
结果:
x = 1
x = 2
请按任意键继续. . .
有了typedef,定义一个函数指针就像定义一个Int变量那样简单粗暴!!!
4.辅助声明结构体
这个在C++中是不需要的,而且貌似C语言也不需要了。老版本的C编译器可能会需要使用typedef来辅助定义结构体。
typedef struct tpoint
{
int x;
int y;
}Point;
Point pt;
三.typedef的注意事项
1.typedef重新定义类型别名,而非简单替换
看一个例子,关于const的。
// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#define DPINT int*
typedef int* PINT;
int _tmain(int argc, _TCHAR* argv[])
{
int i1 = 2;
int i2 = 3;
const PINT pi1 = &i1;
const PINT pi2 = &i2;
const DPINT pi3 = &i1;
//pi1 = &i2;这句是错误的,因为pi1整体为一个数据类型,Int*,即指针本身为const。
//而指针指向的内容却是可变的
*pi1 += 3;
//对于pi3,为单纯的替换,即const int* pi3,此处const为底层const,修饰int*所指向的内容。所以指针本身是可以修改指向的
pi3 = &i2;
system("pause");
return 0;
}
还是使用#define和typedef作对比。使用const PINT时,表示的是类型本身是const,而与类型的指向没关系,类型指向仍然是可变的。这点与#define正好不同!!
2.不能与存储类型关键字同时使用
typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性。
比如我们将typedef和static一起定义的话:
就会出现错误。
参考链接:
http://www.cnblogs.com/charley_yang/archive/2010/12/15/1907384.html
http://baike.baidu.com/link?url=dFIZ8bpYOr1oPz3yD7fph16lhmB-BRgDryDk3TrA9HtUQAvDWI8-23Nq1GFODhjuMSpAuckfhcYqU4l1iR92m_
http://blog.sina.com.cn/s/blog_5e8facd20100qfpn.html
http://www.cnblogs.com/ggjucheng/archive/2011/12/27/2303238.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)