//3.原类型不可带有存储类别
//typedef static int SI;//错误,"指定的存储类多于1个"
//typedef register int RI;//错误同上
//4.原类型应是一种类型,而不可是变量/对象
float f=0;//将f定义为变量
//typedef f FL;//错误
//5.不宜重定义的类型
typedef const CON;//重定义const
//CON int a=0;//但该类型无法正常使用
typedef unsigned US;//重定义unsigned
US us1=0;//正确,相当于unsigned int
//US int us2;//错误,无法正常使用
//注:因const、unsigned等并不是一种独立的类型,故不便对它们重定义
//三、观察新类型
//1.新类型的作用域
typedef int LTYPE;//定义局部类型LTYPE
void fun();//观察LTYPE在fun中是否有效
fun();
//可见,用typedef定义的类型也有作用域之分。在函数内用typedef定义的是局部类型
//typedef也可以像变量定义语句一样放置在函数之外,这时定义的是全局类型
//2.新类型可否是已有类型
//typedef int float;//错误,不能重定义标准类型
typedef int TYPE; //定义了新类型TYPE
//typedef char TYPE;//错误,"TYPE重定义"
typedef int GTYPE;//正确,尽管GTYPE是已有类型,但它是本函数外定义的
//可见,新类型名必须是合法的标识符,它在其作用域内必须是唯一的
//4增加程序的可移植性(有利于程序在不同处理器、操作系统和编译系统之间的移植)
/*例如,在TC下读文件的程序段如下:
FILE* fp;
long buffer1;
fread(&buffer1,sizeof(long),1,fp);//每次读出4个字节
若在VC下每次需要读出8个字节,程序需如下修改:
double buffer2;
fread(&buffer2,sizeof(double),1,fp);
现用typedef方法,程序段如下:
typedef long UNIT;//UNIT在TC中代表long,在VC中代表double
UNIT buffer;
fread(&buffer,sizeof(UNIT),1,fp);//每次读出UNIT个字节
当移植到VC下时,只需改动UNIT的定义即可:typedef double UNIT;*/
//二、typedef与define的区别
//用define也可实现简单的类型替换,如
#define INT long //用INT来代替long
//两种方式的区别如下:
//1.二者处理时间不同,宏替换是在预编译时进行的,而类型定义是在正式编译时处理的
//2二者本质不同,宏替换只是将宏名简单替换为目标字符串,而类型定义如同定义变量一样
//是真的为程序增加了一种可用类型
//3.二者复杂性不同,用typedef可定义各种复杂的类型,并以各种方式使用新类型(详见10_10_2.cpp)
//而define只能替换基本类型和自定义类型,无法替换派生类型,且使用起来很不安全,例如
#define pi int* //试图用pi代替整型指针
pi pi1;//正确,展开后为int* pi1;
pi pi2,pi3;//错误,原意是将pi2,pi3都定义成整型指针,但展开后为int* pi2,pi3; pi3并未定义成指针
#define NUM enum{one,two,three}//试图用NUM代替该枚举类型
NUM n1;//正确,定义了枚举常量one,two,three和枚举变量n1
//NUM n2;//错误,展开后为enum{one,two,three}n2;从而造成枚举常量one,two,three的重定义
#define DATE struct{int y,m,d;}
DATE *pd;//正确,定义了该结构型指针
//pd=(DATE)1;//错误,展开后为pi=(struct{int y,m,d;})1;目前尚不支持此种类型转换写法
#define TIME union{int h,m,s;}
//int L=sizeof(TIME);//错误,展开后为int L=sizeof(union{int h,m,s;});sizeof操作数错误
//可见,用define进行类型替换时,会产生各种意想不到的错误,故应避免使用,而改用安全的typedef