嵌入式C语言-关键字typedef
定义和作用
typedef是C/C++中的一个关键字,作用是为现有的数据类型(int 、char 、flaot等)创建新的别名,其目的是为了方便阅读和理解代码。
用法
typedef 原有类型名 新类型名;
- 基本类型创建别名
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
- 指针创建别名
typedef int* ptr;
// 为指针创建别名,使指针类型更加易读,减少漏写*风险
- 定义结构体
typedef struct {int x;int y;
}ElogTagLvlFilter, *ElogTagLvlFilter_t;
// 定义ElogTagLvlFilter_t结构体指针别名// 声明结构体指针变量elogTagLvFilter
ElogTagLvlFilter_t elogTagLvFilter;
- 定义枚举类型
typedef enum{eRed,eGreen,eBlue,
}color_t;
- 定义数组
在C语言中,可以将固定长度的整型数组作为一个新的数据类型,在利用typedef定义新别名,更加简洁定义此种类型。
typedef int INT_ARRAY_3[3];
// 声明一个INT_ARRAY_3的数组变量
INT_ARRAY_3 array;void example(void)
{INT_ARRAY_3 arr = {1,2,3};for(int i=0; i<3;i++){printf("arr[%d] = %d\r\n",i,arr[i]));}
}
- 定义指针数组类型
// 定义一个新的类型IntPtrArray,表示一个包含3个int指针数组
typedef int *IntPtrArray_t[3];void example(void)
{int a = 1, b = 3, c = 4;IntPtrArray_t ptrArray = {&a, &b, &c};for(int i = 0; i < 3; i++){printf("ptrArray[%d] = %d\r\n", i, *ptrArray[i]);}
}
- 定义数组指针类型
typedef int (*ArrayPtr)[3];void example(void)
{int arr[3] = {1,2,3};ArrayPtr arrPtr = &arr;for(int i = 0; i < 3; i++){printf("arr[%d] = %d\r\n", i, (*arrPtr)[i]);}
}
- 定义函数指针
typedef int (*callback_t)(void *);void myCallback(void *data){}callback_t callback = myCallback;// 使用回调函数
callback(someData);
typedef与define区别
typedef和define在C/C++中的核心差异体现在处理机制、类型安全和作用域控制三个维度:前者是编译阶段的类型别名定义,具有类型检查和作用域限制;后者是预处理阶段的文本替换,缺乏类型安全且全局生效。
本质与处理机制差异
- typedef是关键字,创建真正的类型别名,编译器会检查类型兼容性。
typedef int* ptr;
ptr a,b; // a和b类型均为int*类型
- define是预处理命令,用于宏定义的文本替换,在预处理阶段完成,无类型检查,仅机械替换字符串,可能引发错误。
#define IntPtr int *IntPtr a,b;
//宏定义展开为
int *a,b; //a为指针,b是int
此处b因替换规则成为普通int而非指针。
语法与功能特性
- 类型安全
- typedef定义的别名具有完整类型信息,编译器会验证类型一致性。
- #define可能导致类型错误。例如 :
#define IntPtr int *IntPtr a,b;
//宏定义展开为
int *a,b; //a为指针,b是int
- 作用域
- typedef:受限于定义位置的作用域(例如函数内部定义的别名在外部不可见)
- #define:从定义开始全局生效,直到到文件结束或遇到#undef,易造成命名污染。
应用场景
- typedef使用场景如开头所述。
- define使用场景
- 定义常量或简单宏:#define MAX_SIZE (100)
- 跨平台条件编译:#ifdef WIN32。。。#endif
核心区域总结
特性 | typedef | define |
---|---|---|
本质 | 编译器指令(类型重命名) | 预处理文本替换 |
作用域 | 遵循块作用域(如函数、命名空间) | 从定义处到文件末尾(或#undef) |
类型检查 | 编译时进行类型安全校验 | 无类型检查,直接文体替换 |
处理阶段 | 编译阶段 | 预处理阶段 |
对指针的支持 | 正确处理指针别名 | 可能因替换导致指针错误 |
复杂类型支持 | 支持结构体、函数指针等复杂别名 | 需谨慎处理括号,否则容易出错 |
末尾符合 | 需要分号; | 不需要分号 |
建议:typedef不用于定义常量别名;#define不用于数据类型宏定义。