1:C中的typedef直译过来的语句,就是类型定义,它被发明出来的初衷就是为了,书写上的方便。我们可以用typedef来定义自己习惯使用的数据类型名称,可以替代自己所熟悉的基本类型、数组类型、指针类型以及自己定义的结构体类型、共用体类型、枚举类型等。
关键字(恒定) | 参数1 | 参数2 | 说明 |
1、typedef | 基本数据类型(如int float short char long double,unsigned) | 用户自定义标识符 | typedef unsigned int UNINT,后面就可以用UNINT直接来声明和定义无符号整形数据。 如 UNNIT a,b,c; |
2、typedef | 数组类型 typedef char NAME[30]; | X(表示没有)也可以理解为NAME,就是客户自定义的标识符 | 可以用NAME定义和声明一个char型字符数组,长度为30. NAME A=char A[30]; |
3、typedef | 指针类型、 typedef int *POINT; | POINT | POINT p1=int *p1; 注意p1前面不能再加上* |
4、typedef | 结构体 1:typedef struct ST{int age;char name;}INFOR 2:用TYPEDEF不完全声明 typedef struct ST INFOR; | INFOR | 定义之后可以直接使用INFOR来声明结构体变量了。 可以看到第一种模式叫做完全声明,第二种模式叫做不完全声明 |
4、typedef | 函数声明 typedef int FUNC(int agr_1) | FUNC CAL=int CAL(int agr_1) |
1:补充说明,第一种情况一般1情况下,只针对书写比较麻烦的格式,如unsigned 格式。这样可以做到简写的目的,方便源代码的编写。
2:第二种情况,也是针对unsigned 书写比较麻烦的数组类型。但是第二种情况需要注意格式的要求 typedef +别名+[数组长度],然后定义之后直接使用别名+新定义的数组名。
3:第三种是很有必要说明一下的,表中只是列举了,最简单的形式,typedef (*pfun_1)(int agr_1)。这就定义了一个基类型为(*标识符)(int 形参名)别名为pfun_1的函数指针。
4:也很有必要说明一下,首先需要注意(完全声明+不完全声明),其次这两种方法对于结构体、共用体、枚举都是适用的。
2:typedef和#define的区别和联系
如果不深入的去探究,typedef和#define(宏替换)功能好像都是一样的。都是可以为已存在类型取个别名。
两种书写方式上,存在差异:
#define INT int //注意这里没有;和其他一切的符号,各关键字之间,只用空格给隔开。
//一点需要书写时需要特别注意,并且记住这一特性,还有助于理解#define和typedef的底层逻辑上//的区别。
typedef int INT ; //注意这里是一个语句,是必须以;结尾的。
#define 别名 系统自带关键字+常量+变量
typedef 系统自带数据类型+用户自定构造数据类型 别名
另外,在使用方法上也是有区别的,typedef是可以理解为整体打包。如
#define INT int
unsigned INT = unsigned int;//是合法的描述
typedef int INT ;
unsigned INT; //非法语句
typedef整体打包后,能连续定义变量
INT a,b,c,d;=int a,b,c,d;
#define INT int
INT a,b,c,d; //属于错误语句,编译时系统会报错,此语句相当于int a,对后面的bcd,不会起到修饰作用。
typedef可以用来定义函数的别名,#define无法做到这一点。
typedef还有一类比较特殊的用法。
typedef struct __attribute__((packed))
{
char one;
short two;
char three;
int four;
} stc,*pstc;
最后一行,我们同时定义了,两个别名,分别可以用来定义结构体变量,和结构体指针变量。
编译方法,和占用内存上的区别:
#define 是预编译阶段,就处理完成。代码执行过程中不存在代码执行时间。
typedef是编译阶段处理,会占用内存中的空间,如嵌入式系统中,会占用ROM或Flash中的空间,自然也需要时间去执行这段代码。
作用域,#define开始到第一个#undef处停止。(#define无论是在函数(主函数+调用函数)内还是函数外定义都是可以使用的,也就是说任意出定义,任意出都可以使用)
int main()
{
/*在函数内定义#define,看看函数外部能不能使用*/
#define PI 3.1415927
printf("Hello world!\n");
printf("输出M定义无符号整数的值a=%d:\n",a);
fun_1();
return 0;
}
int fun_1(void)
{
#define YELLO 99.9
printf("看看能不能在其他函数中输出=%f",PI);
printf("先在本函数fun_1中输出YELLO=%f",YELLO);
fun_2();
return 0;
}
int fun_2(void)
{
printf("看看能不能在其他函数中输出YELLO=%f",YELLO);
}
typedef是可以必须先定义,然后再使用,typedef没有解除定义的关键字。另外类型定义如果,在每个函数内部定义,那么它的使用范围就是此函数内部,不能再其他函数中使用这个别名来定义变量,结构体等。
int main()
{
typedef struct __attribute__((packed))Information //这里的__attribute__((packed))
//是告诉编译器,我们不需要结构体字节对 齐
{
unsigned int age;
char nmae[30];
float height;
float weight;
}INFORMATION,*PINFORMATION;
fun_1();
return 0;
}
int fun_1(void)
{
INFORMATION student_1;
PINFORMATION *pstudent;
return 0;
}
看编译的结果可以看出来,typedef定义的别名,不能再其他函数中使用(当然,也不能再函数外使用)
另外,当一个基本类型或构造类型被定义了别名时,它原有的名字和定义格式,同样是适用的,
#define INT int
int a; //依然是合法的描述
typedef int INT ;
int b; //依然是合法描述