C 语言 typedef

 用typedef命名已有类型

 陷阱一:

  记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:

  先定义:

  typedef char* PSTR;

  然后:

  int mystrcmp(const PSTR, const PSTR);

  const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。

  原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。

  简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。

  陷阱二:

  typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:

  typedef static int INT2; //不可行

  编译将失败,会提示“指定了一个以上的存储类”。

  1、typedef的用法

  在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

  typedef    int       INT;

  typedef    int       ARRAY[10];

  typedef   (int*)   pINT;

  typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

  2、#define的用法

  #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

  #define   INT             int

  #define   TRUE         1

  #define   Add(a,b)     ((a)+(b));

  #define   Loop_10    for (int i=0; i<10; i++)

  在Scott Meyer的Effective C++一书的条款1中有关于#define语句弊端的分析,以及好的替代方法,大家可参看。

  3、typedef与#define的区别

  从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢?主张用typedef,因为在早期的许多C 编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

  宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:

  typedef    (int*)      pINT;

  以及下面这行:

  #define    pINT2    int*

  效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。

1. 首先,二者执行时间不同

关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。

Define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。

#define用法例子: 

复制代码
#define f(x) x*x  
main( )  
{  
int a=6,b=2,c;  
c=f(a) / f(b);  
printf("%d \n",c);  
} 
复制代码

程序的输出结果是: 36,根本原因就在于#define只是简单的字符串替换,应当加个括号“(X*X)”。

2. 功能不同

Typedef用来定义类型的别名,这些类型不只包含内部类型(int,char等),还包括自定义类型(如struct),可以起到使类型易于记忆的功能。 

如:

  1. typedef int (*PF) (const char *, const char *); 

定义一个指向函数的指针的数据类型PF,其中函数返回值为int,参数为const char *。

typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以i获得最高的精度:

  1. typedef long double REAL; 

在不支持 long double 的机器上,该 typedef 看起来会是下面这样:

  1. typedef double REAL; 

并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:

  1. typedef float REAL; 

#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

3. 作用域不同

#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。而typedef有自己的作用域。

  1. 复制代码
    void fun()   
    {   
    #define A int   
    }  
    void gun()   
    {   
    //在这里也可以使用A,因为宏替换没有作用域,   
    //但如果上面用的是typedef,那这里就不能用A ,不过一般不在函数内使用typedef  
    } 
    复制代码

4. 对指针的操作

二者修饰指针类型时,作用不同。

  1. 复制代码
    Typedef int * pint;  
    #define PINT int *  
    Const pint p;//p不可更改,p指向的内容可以更改,相当于 int * const p;  
    Const PINT p;//p可以更改,p指向的内容不能更改,相当于 const int *p;或 int const *p;  
    pint s1, s2; //s1和s2都是int型指针  
    PINT s3, s4; //相当于int * s3,s4;只有一个是指针
    复制代码

其实,typedef和define末尾的标号也是不一样的,希望大家不要忽略这一点。通过本文的分析,相信你已经了解了这两者之间的区别。掌握了区别之后,运用起来会更加的灵活。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值