typede和define

本文详细解析了C语言中的typedef和define关键字,强调了typedef用于类型定义,如数组和函数指针的别名,而define主要在预处理器阶段进行文本替换。同时讨论了两者在使用上的区别,以及宏函数的应用。
摘要由CSDN通过智能技术生成

C语言-关键字-typede和define

本文讲讲这两个关键字的精髓



前言

本文讲讲这两个关键字typede和define的精髓

1. 基本用法

define

define翻译成中文就是“定义”的意思。它是在对某个对象进行定义。例如,你教育一个三岁小孩指着一个黑色石头说这是香蕉,你给这个黑色的东西下了一个定义叫香蕉。孩子长大了一直管这个黑色的石头叫香蕉。可见这个define有洗脑的功能,给人一种可以胡乱搞的感觉。
常见的define用法如下:

//格式:#define <宏名/标识符> <字符串>
#defnie MAX_NUM 100 //后面没有分号
int main() {
	printf("最大数是%d\n", MAX_NUM );
}

但是它还可以“胡乱搞”, 下面的一行不是很符合词法的语句被它给定义了。

//格式:#define <宏名/标识符> <字符串>
#defnie SOME_WORDS "int max_num 100" //注意这里100后面没有分号
int main() {
	SOME_WORDS;//在这里把分号补上了
	printf("最大数是%d\n", max_num);
}

为什么能这样搞,因为前面有个#,说明这是预处理器做的事情,预处理器在预处理阶段可以将define定义的标识符用实际的字符串替换

typedef

typede翻译成中文定义就是“类型定义”,所以你要先展示被定义的类型,再来下定义,例如:

typedef unsigned int U32; //后面有分号

上面讲了点皮毛,旨在帮你对这两个关键字的用法做区分,正在有价值的东西在后面

2. typedef的精髓

typedef 修饰数组

typedef int arry[10];//这里给一个int型数组重新起了一个名字叫 arry,此时arry是类型名。

typedef 修饰函数指针

//摘自《嵌入式C语言的自我修养》 第7章 数据存储与指针
typedef int *(*func_ptr_t)(int *p, int len, char neme[]);
func_ptr_t arry[10];

脑瓜子嗡嗡的吧,不好好琢磨一下C语言,这还真的难理解,其实这也都是基本功。
上文展示了typedef给某个类型起别名的格式,那这个表达式typedef是在给谁起别名呢,格式看着都不一样。
其实这是typedef一种常用的语法,首先看typedef后面的部分,如下所示,该表达式声明了一个指针函数指针。那么这个表达式放在放在typedef 后面的意思是“声明了一个指针函数指针,该指针的名字叫func_ptr_t”,然后func_ptr_t arry[10];中又声明了一个数组,该数组里面的成员都是指针函数指针。

//摘自《嵌入式C语言的自我修养》 第7章 数据存储与指针
int *(*func_ptr_t)(int *p, int len, char neme[]);

理解typedef 需要走出define的阴影

再来对比这三种typedef的常用修饰,是不是有个疑问?为什么第2种不是把 int 类型重新命名成“arry[10]”?

typedef unsigned int U32; 
typedef int arry[10];
typedef int *(*func_ptr_t)(int *p, int len, char neme[]);

如果你有这种疑问,那说明你没有走出#define的阴影。

把这两种关键字的公式列出来你就能看明白了:

:#definf的公式 #define + <宏名/标识符> + <字符串>
typedef的公式 typedef + 类型声明

现在将上面typedef关键字全部删掉

unsigned int U32; //
int arry[10];
int *(*func_ptr_t)(int *p, int len, char neme[]);

再把一些无关的东西拿掉,仔细一看这不就是变量声明吗?看下面的注释

unsigned int U32; //声明一个变量,变量的名字叫U32
int arry[ ];//声明一个数组,数组的名字叫arry
int *(*func_ptr_t)();//声明一个指针函数指针,数组的名字叫func_ptr_t

再根据typedef的公式 :typedef + 类型声明

typedef unsigned int U32; // typedef + (声明一个变量,变量的名字叫U32)
typedef int arry[10];// typedef + (声明一个数组,数组的名字叫arry)
typedef int *(*func_ptr_t)(int *p, int len, char neme[]);//typedef + (声明一个指针函数指针,数组的名字叫func_ptr_t)

把typedef关键字一加回来,这些“变量名”就变成了“新类型”标识符,
typedef + (声明一个变量,变量的名字叫U32) -> 定义了一个标识符U32作为新的类型名,它是ungisned int的别名
typedef + (声明一个数组,数组的名字叫arry)-> 定义了一个标识符arry作为新的类型名,它是int型数组的别名
typedef + (声明一个指针函数指针,指针函数指针的名字叫func_ptr_t -> 定义了一个标识符func_ptr_t 作为新的类型名,它是指针函数指针的别名)

其实你还可以更进一步做变形,如下所示,这样写你看着是不是舒服点,至少我这个强迫症很喜欢这样去看

typedef unsigned int  U32; 
typedef int [10]      arry;
typedef int *(*)()    func_ptr_t;

3. 区分

讲到这里了,还是有人不能区分typedef 和 define。有3点原因:

  1. 还是个学生,用得少
  2. 平时写代码只关注逻辑,找别人代码复制粘贴就完了,谁研究这些细节
  3. 不理解他们得本质

针对上述三点给出我的一些看法

  1. 还是个学生,那你就死记硬背,你毕业了不一定敲代码
  2. 我觉得有道理
  3. 本质
    #define是预处理阶段的一种替换,相当于文本替换。
    typedef 是关键字,起到修饰作用,是起小名

在用法上:
typedef 更加适合于给一些复杂的类型声明起别名,看着就牛逼,
而define的牛逼之处不在于做简单的文本替换,这太低级了,而在宏函数,

4. 宏函数

写一个牛逼的宏函数,用来比较两个的大小。

#define MAX(x,y) ({
	typeof(x) _x = x; \
	typeof(y) _y = y; \
	void &(_x) == &(_y);  \
	(_x) > (_y) ? (_x) : (_y);\
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值