一、类型定义符typedef
C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”,类型定义符typedef可用来完成此功能。
类型定义符typedef 原类型名 新类型名(类型别名);
用typedef定义数组、指针、结构体等类型别名将带来很大的方便,不仅使程序书写简单而且使意义更加明确,因此增强了可读性。
易于理解,容易修改,可移植性好。
typedef定义示例
typedef float/double Dollars;
Dollars cash_in, cash_out;
typedef struct student
{
char name[20];
int age;
char sex;
}Stu;
Stu stu = {"Jack",20,‘F’};
二、#define定义类型别名
typedef定义类型别名的功能也可用预处理指令#define即宏定义来代替
预处理指令#define定义类型别名的语法
#define 新类型名 原类型名
#define指令结尾没有分号
#define INTEGER int
INTEGER a = 100;
三、typedef和#define的区别
#define指令是在预处理阶段完成的,而typedef则是在编译时完成的,后者更为灵活方便。
#define无法正确处理指针类型,typedef更为合适。
typedef char* ptr_char;
ptr_char a,b,c; //a,b,c 都为指针
#define PTR_CHAR char*;
PRT_CHAR a,b,c; //a为指针,b和c为char型
四、重新总结:
大部分场景下:
define用于定义一些常量或者宏函数,然后再预处理阶段编译器会直接替换。
typedef用于定义一些新的类型,看起来更加直观或者写起来更方便。
两者确实有一定的联系,直接看代码:
#include<stdio.h>
//typedef unsigned char uchar;
#define uchar unsigned char
int main()
{
// uchar ch; //等价于 unsigned char ch;
uchar ch; //等价于 unsigned char ch;
return 0;
}
对代码做预处理
gcc -E demo.2 -o demo.i
vim demo.i
你会发现uchar被替换成了unsigned char
int main()
{
unsigned char ch;
return 0;
}
以上这两种情况,define和typedef用起来没有什么区别!!!
#include<stdio.h>
//typedef char *pStr;
#define pStr char *
int main()
{
pStr p1, p2;
p1 = NULL;
P2 = NULL;//使用typedef,p1, p2都是指针
return 0;
}
使用typedef,p1, p2都是指针。
使用#define pStr char *,预处理后你会发现p1是指针类型,但是p2还是char类型,原因还是宏定义只做简单的替换。
#include<stdio.h>
typedef char *pStr;
int main()
{
const pStr p;
p++; //编译错误
(*p)++;
return 0;
}
在前面加上const,很多人认为const修饰的是指针p指向的内容,其实并不是,p++编译的时候就会报错,也就是说const修饰的是指针p。
demo2.c: In function ‘main’:
demo2.c:73:6: error: increment of read-only variable ‘p’
p++;
^~