C语言--typedef 和 #define 的区别

本文探讨了C/C++中typedef与宏定义(#define)的区别。通过示例解释了typedef如何提供更好的类型封装,并确保变量定义的一致性,同时指出它与宏替换在变量类型扩展和连续定义方面的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef 在表现上有时候类似于 #define,但它和宏替换之间存在一个关键性的区别。正确思考这个问题的方法就是把 typedef 看成一种彻底的“封装”类型,声明之后不能再往里面增加别的东西。

1) 可以使用其他类型说明符对宏类型名进行扩展,但对 typedef 所定义的类型名却不能这样做。如下所示:

#define INTERGE int
unsigned INTERGE n;  //没问题

typedef int INTERGE;
unsigned INTERGE n;  //错误,不能在 INTERGE 前面添加 unsigned。

2) 在连续定义几个变量的时候,typedef 能够保证定义的所有变量均为同一类型,而 #define 则无法保证。例如:

#define PTR_INT int *
PTR_INT p1, p2;

经过宏替换以后,第二行变为:

int *p1, p2;       这使得 p1、p2 成为不同的类型:p1 是指向 int 类型的指针,p2 是 int 类型。

相反,在下面的代码中:

typedef int * PTR_INT
PTR_INT p1, p2;

p1、p2 类型相同,它们都是指向 int 类型的指针。


### C语言 IO口控制、宏定义与结构体解析 #### 1. 宏定义 在C语言中,宏定义是一种预处理指令,通常用于简化代码编写并提高可维护性。它通过`#define`关键字实现,可以用来定义常量或函数式的表达式。 例如,在引用[^3]中提到的`UNI_PLUGIN_ENABLED(Xxxrecog)`就是一个典型的宏调用形式。这种宏可以在编译阶段决定某些功能模块是否被启用。类似的例子还有: ```c #define GPIO_PORTA_BASE 0x40007000U // 定义GPIO端口A的基础地址 #define LED_ON(port, pin) ((port)->BSRR |= (1 << (pin))) // 打开指定LED #define LED_OFF(port, pin) ((port)->BRR |= (1 << (pin))) // 关闭指定LED ``` 以上代码片段展示了如何利用宏来控制硬件IO口的状态。其中`LED_ON``LED_OFF`分别表示设置某个引脚为高电平或低电平[^5]。 --- #### 2. 结构体定义 结构体是C语言中一种重要的数据类型,允许开发者将不同类型的数据组合在一起形成一个新的复合型变量。以下是两个常见的结构体示例基于用户需求定制化设计而成: ##### `Sys_Status_t` 此结构体可用于存储系统的整体状态信息,比如运行模式、错误标志等字段。 ```c typedef struct { uint8_t system_mode; // 当前系统工作模式 bool error_flag; // 是否存在错误标记 float temperature_value; // 温度传感器数值 } Sys_Status_t; ``` 这里假设了一个简单的场景——监控设备的工作状况及其温度变化情况[^6]。 ##### `Detector_Threshold_t` 针对检测器阈值设定而创建的一个专用结构体实例。 ```c typedef struct { int lower_limit; // 下限触发条件 int upper_limit; // 上限触发条件 char description[50]; // 描述文字说明 } Detector_Threshold_t; ``` 这个结构可以帮助管理不同种类探测仪各自的敏感程度范围,并附带一段描述便于识别具体用途[^7]。 --- #### 3. 输入输出(IO) 口控制逻辑 对于嵌入式开发而言,直接操控微控制器上的外设寄存器是最基础也是最核心的技术之一。下面给出了一段关于STM32系列MCU通用定时器PWM输出配置过程中的部分摘录作为示范: ```c // 初始化TIM2通道1 PWM 输出至PA0 引脚 void TIM2_PWM_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE ); // 启动时钟供应给TIM2 GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 ; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ; // 复用推挽输出模式 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ; GPIO_Init(GPIOA,&GPIO_InitStruct); TIM_TimeBaseInitTypeDef TIM_BaseStruct={0}; TIM_OCInitTypeDef TIM_OCStruct ={0}; TIM_BaseStruct.TIM_Period = ARR_VALUE -1 ; // 自动重装载计数最大值 TIM_BaseStruct.TIM_Prescaler =(PSC_VALUE )-1 ; // 预分频系数 TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1 ; TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up ; TIM_TimeBaseInit(TIM2,&TIM_BaseStruct); TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable ; TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High ; TIM_OCStruct.TIM_Pulse = CCR1_VALUE; TIM_OC1Init(TIM2,&TIM_OCStruct ); TIM_Cmd(TIM2,ENABLE ); } ``` 上述代码实现了对特定型号单片机内部资源的具体初始化流程,包括但不限于使能对应外设电源域供电开关、调整目标管脚属性适配实际应用场景所需电气特性等等操作步骤[^8]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值