typedef的用法、struct和typedef struct的区别

11 篇文章 0 订阅

一、typedef的用法

①:定义一种类型的别名,但不是简单的宏替换。

通常来说,typedef要比#define要好,特别是在有指针的场合:

typedef    char   *pStr1 ;
#define pStr2  char*;
pStr1  s1 ,s2 ;
pStr2  s3 ,s4 ;

在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。

先定义:
typedef  char * PSTR ;
然后:
int mystrcmp ( const PSTR ,  const PSTR ) ;

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

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

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

②:用typedef来定义与平台无关的类型。

比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

typedef long double REAL;

在不支持 long double 的平台二上,改为:

typedef double REAL;

在连 double 都不支持的平台三上,改为:

typedef float REAL;

也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

标准库就广泛使用了这个技巧,比如size_t。

另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。

③:为复杂的声明定义一个新的简单的别名。

在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。

原声明:int *(*a[5])(int, char*);

变量名为a,直接用一个新别名pFun替换a就可以了:

typedef int *(*pFun)(int, char*);

原声明的最简化版:

pFun a[5];

a本身是一个数组,里面保存的是指针类型的元素。

④:和struct搭配使用

这里另外用一个部分讲解。

 

二、struct和typedef struct的区别

在C语言,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如:

struct point {
int x ;
int y ;
} ;
struct point p ;

而在C++中,则可以直接写:结构名 对象名,即:

point p;

所以可以使用typedef和struct一起使用:

typedef  struct point {
int x ;
int y ;
}Point ;
Point p ;

这样就省去了struct。

在struct中定义自己的指针:

typedef  struct point {
int x ;
int y ;
struct point  *next ;
}Point ;

或者:

typedef struct point *Point;
struct point{
int x;
int y;
Point next;
};

在C++中可以直接:

typedef  struct point {
int x ;
int y ;
point  *next ;
}Point ;

struct在代码中常见两种形式:

struct A {
int x ;
int y ;
} ;
struct {
int x ;
int y ;
}A ;

前一种是结构体类型定义,定义{}中的结构为一个名称是“A”的结构体。

使用:

A     a;

a.x;

或者:

typedef  struct TagA {
int x ;
int y ;
}A ;   //A为TagA的别名,是等同的。

后者是结构体变量定义,以{}中的结构,定义一个名称为”A”的变量。这里的结构体称为匿名结构体,是无法被直接引用的。

使用:

A.x;

或者:

typedef  struct {
int x ;
int y ;
}A ;   //定义匿名结构体的别名为A

注意上面两种的使用方法!!!

最后注意:

typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef static int INT2; //不可行
编译将失败,会提示“指定了一个以上的存储类”。

分享到: 0

微信 OR 支付宝 扫描二维码
为本文作者 打个赏
pay_weixinpay_weixin
金额随意 快来“打”我呀~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值