第一、四个用途
用途一:
1.用作同时声明指针型的多个对象:
typedef char* PCHAR; // 一般用大写
PCHAR pa, pb; // 同时声明了两个指向字符变量的指针
2.替代:char *pa, *pb;
3.而 char* pa, pb; 含义是声明了一个指向字符变量的指针;和一个字符变量;
用途二:
在C中申明结构体对象:
struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
每次第一个结构体对象要多写一个struct,利用typedef 可以达到简写目的。
typedef struct tagPOINT
{
int x;
int y;
}POINT;
POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候
用途三:
解决跨平台问题,比如标准库中的size_t
用途四:
1.为函数类型重命名(typedef有两类自定义类型)
函数名就是一个指针,当调用一个函数时,我们都是直接用函数名调用,或者说通过指针调用。
明白函数名的特点后,看第一个typedef定义的类型
a.类型一,指针
#include <stdio.h>
typedef int (*fp_t)(char c);
int f0(char c) { printf("f0, c = %c\n", c); return 0;}
int f1(char c) { printf("f1, c = %c\n", c); return 1;}
int main()
{
int ret;
fp_t fp;
fp = f0;
ret = fp('a');
fp = f1;
ret = fp('x');
return 0;
}
类型二,非指针
#include <stdio.h>
typedef int fp_t(char c);
int f0(char c) { printf("f0, c = %c\n", c); return 0;}
int f1(char c) { printf("f1, c = %c\n", c); return 1;}
int main()
{
int ret;
fp_t* fp;
fp = f0;
ret = fp('a');
fp = f1;
ret = fp('x');
return 0;
}
2.type定义数组类型
1. 一维数组类型的定义格式
typedef <元素类型关键字><数组类型名>[<常量表达式>];
例如:
(1) typedef int vector[10];
(2) typedef char strings[80];
(3) typedef short int array[N];
(1) vector v1,v2;
(2) strings s1,s2="define type";
(3) array a={25,36,19,48,44,50}; //假定常量N≥6
2. 二维数组类型的定义格式
typedef <元素类型关键字><数组类型名>[<常量表达式1>][<常量表达式2>];
例如:
(1) typedef int matrix[5][5];
(2) typedef char nameTable[10][NN];
(3) typedef double DD[M+1][N+1];
(1) matrix mx={{0}};
(2) nameTable nt={""}; //或使用等同的{{'\0'}}初始化
(3) DD dd={{0.0}};
第二、两大陷阱
陷阱一:
记住,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; //不可行
编译将失败,会提示“指定了一个以上的存储类”。
第三、typedef 与 #define的区别
案例一:
通常讲,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;
- char string[4] = "abc";
- const char *p1 = string;
- const pStr p2 = string;
- p1++;
- p2++;
是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。