c/c++ 之typedef的用法

本文参考网络资料,相关博客链接如下:

http://c.biancheng.net/view/298.html

typedef:重新定义一种数据类型(或者是给类型起别名)。
C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称、数组类型名称、
指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。一旦用户在程序中定义了自己的数据类型名称,
就可以在该程序中用自己的数据类型名称来定义变量的类型、数组的类型、指针变量的类型与函数的类型等。

 

typedef的用法:
1.为基本数据类型定义新的类型名: typedef unsigned int uint32
    1.1    也就是说,系统默认的所有基本类型都可以利用 typedef 关键字来重新定义类型名
    1.2    我们还可以使用这种方法来定义与平台无关的类型。
        比如,要定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型,
        即:typedef long double REAL;
        
        当跨平台移植程序时,甚至还可以在连 double 都不支持的平台上,我们只需要修改一下 typedef 的定义即可,
        而不用对其他源代码做任何修改。
        其实,标准库中广泛地使用了这个技巧,比如 size_t 在 VC++2010 的 crtdefs.h 文件中的定义如下所示:
            #ifndef _SIZE_T_DEFINED
            #ifdef  _WIN64
            typedef unsigned __int64    size_t;
            #else
            typedef _W64 unsigned int   size_t;
            #endif
            #define _SIZE_T_DEFINED
            #endif

2. 为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称
    以结构体为例,下面我们定义一个名为 Point 的结构体:

    struct Point
    {
        double x;
        double y;
        double z;
    };

    在调用这个结构体时,我们必须像下面的代码这样来调用这个结构体:

    struct Point oPoint1={100,100,0};
    struct Point oPoint2;

    在这里,结构体 struct Point 为新的数据类型,在定义变量的时候均要向上面的调用方法一样有保留字 struct,
    而不能像 int 和 double 那样直接使用 Point 来定义变量。
    现在,我们利用 typedef 定义这个结构体,如下面的代码所示:

    typedef struct tagPoint
    {
        double x;
        double y;
        double z;
    } Point;

    因此,现在你就可以像 int 和 double 那样直接使用 Point 定义变量,如下面的代码所示:

    Point oPoint1={100,100,0};
    Point oPoint2;

    结构中包含指向它自己的指针

    struct tagNode
    {
        char *pItem;
        struct tagNode *pNext;
    };
    typedef struct tagNode *pNode;

3. 为数组定义简洁的类型名称
    
    typedef int INT_ARRAY_100[100];
    INT_ARRAY_100 arr;

4. 为指针定义简洁的名称
    
    typedef char* PCHAR;
    PCHAR pa;

    // PFun是我们创建的一个类型别名
    typedef int *(*PFun)(int,char*);
    // 使用定义的新类型来声明对象,等价于int*(*a[5])(int,char*);
    PFun a[5];

#define与typedef的区别和用法:

1、宏替换: 只能用#define了,比如:#define PI 3.14

2、给简单数据类型起别名:
    2.1 #define uint32 unsigned int 
    2.2 typedef unsigned int uint32  
    //其实这两个是一样的。

3、声明一个指向简单数据类型变量的指针
    
    3.1 #define uint32_p  unsigned int *  
        如果我们只用来声明一个指针变量是没问题的,但是要是出现这样一种情况:uint32_p  p1,p2;
        结果会怎样呢?
        根据#define替换的功能,可以解析成 unsigned int *p1,p2;
        而这个声明的作用与我们之前的目的是完全不一样了吧。
    
    3.2 typedef unsigned int*  uint32_p
        uint32_p,是一种新的数据类型,完全可以用它去声明uint32_p  p1,p2;

4、结构体类型的声明:
    typedef struct{
                uint32 a;
                uint16 *p;
                uint16 array[10];
                 }m_T;        
                 
    我们可以直接用m_T声明结构体变量;m_T  m1,*m2;
    而且我们可以把这个声明放在一个头文件里,方便其它想使用这个声明的地方。
    这里要是换成用#define实现会怎样呢?你可以试试一下

5、我们看这样一个表达式,也是学习指针(函数指针、指针函数)最为经典的例子:
    (*(  void (*)()  )0)();            //硬件地址跳到0处
    void(*)()    :是一个函数指针类型的声明,声明了一个指向返回值类型为void的函数的函数指针,
    
    假设fp是一个函数指针,那么如何调用fp所指向的函数,调用方法如下:
    (*fp)();
    要是从硬件的0地址启动,似乎(*0)();就可以调用指向0地址的函数。但是,这样是无效的。fp必须是一个指针
    现在就可以把“0”强制转换成函数指针类型,: ( void (*)() )0
    现在(*  ( void (*)() )0  )();            //外部调用一个函数指针,函数指针是 void (*)()型的函数指针
    
    如果在程序的其它地方也会用到void (*)(), 我们是不是考虑一下,用typedef  void(*)() A
    当再要定义返回值类型为void类型的函数指针时只用写:    A a;,  之前的例子就可以写作:(*(A)0)();
    如果换成#define void (*)() A,是不会也能实现这个效果呢?


写到这里我要借助C陷阱与缺陷里的内容了,请大家自己理解:

使用 typedef 的目的 or 好处:


1、为了隐藏特定类型的实现,强调类型的使用目的
2、允许一种类型用于多个目的,同时使得每次使用给类型的目的明确
如:typedef int (*Function)(const char *, const char *);

该定义表示 Function 是一种指向函数的指针的类型的别名,
要使用这种指针类型时只需直接使用 Function即可,
不必每次把整个声明都写出来

void (*Signal(int,void(*)(int)))(int);

typedef void (*HANDLER)(int);

HANDLER Signal(int,HANDLER);
上下两种声明意义是一致的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值