Typedef declaration
typedef 声明 提供了一种将标识符声明为类型别名的方式,用于替代可能复杂的 类型名称
关键字 typedef 用于 声明 中,其语法位置相当于 存储类说明符 ,但不会影响存储期或链接:
typedef int int_t; // 声明 int_t 为 int 类型的别名 typedef char char_t, *char_p, (*fp)(void); // 声明 char_t 为 char 类型的别名 // char_p 为 char* 类型的别名 // fp 为 char(*)(void) 类型的别名
目录 |
说明
如果 声明 使用 typedef 作为存储类说明符,其中的每个声明符都会将标识符定义为指定类型的别名。由于声明中只允许使用一个存储类说明符,typedef声明不能是 static或extern 。
typedef 声明不会引入一个独立的类型,它仅为现有类型建立一个别名,因此 typedef 名称与其所别名的类型是 兼容的 。typedef 名称与普通标识符(如枚举成员、变量和函数)共享 命名空间 。
|
VLA的typedef只能出现在块作用域中。数组的长度在每次控制流经过typedef声明时都会被重新计算,这与数组本身的声明方式不同: void copyt(int n) { typedef int B[n]; // B是VLA,其大小为n,在此处立即计算 n += 1; B a; // a的大小是+=1之前的n值 int b[n]; // a和b具有不同尺寸 for (int i = 1; i < n; i++) a[i-1] = b[i]; } |
(since C99) |
注释
typedef 名称可以是 不完整类型 ,该类型可按常规方式补全:
typedef int A[]; // A 是 int[] 类型 A a = {1, 2}, b = {3,4,5}; // a 的类型是 int[2],b 的类型是 int[3]
typedef 声明常用于将名称从 标签命名空间 注入到普通命名空间:
typedef struct tnode tnode; // tnode 在普通命名空间中 // 是标签命名空间中 tnode 的别名 struct tnode { int count; tnode *left, *right; // 等同于 struct tnode *left, *right; }; // 现在 tnode 也是完整类型 tnode s, *sp; // 等同于 struct tnode s, *sp;
它们甚至可以完全避免使用标签命名空间:
typedef struct { double hi, lo; } range; range z, *zp;
typedef 名称也常用于简化复杂声明的语法:
// 包含5个函数指针的数组,这些函数返回指向包含3个整数的数组的指针 int (*(*callbacks[5])(void))[3]; // 使用typedef的等效声明 typedef int arr_t[3]; // arr_t是包含3个整数的数组 typedef arr_t* (*fp)(void); // 指向返回arr_t*类型的函数的指针 fp callbacks[5];
库经常将系统相关或配置相关的类型暴露为 typedef 名称,以便向用户或其他库组件提供一致的接口:
#if defined(_LP64) typedef int wchar_t; #else typedef long wchar_t; #endif
参考文献
- C23 标准 (ISO/IEC 9899:2024):
-
- 6.7.8 类型定义 (p: TBD)
- C17 标准 (ISO/IEC 9899:2018):
-
- 6.7.8 类型定义 (p: TBD)
- C11 标准 (ISO/IEC 9899:2011):
-
- 6.7.8 类型定义 (p: 137-138)
- C99标准(ISO/IEC 9899:1999):
-
- 6.7.7 类型定义(页码:123-124)
- C89/C90 标准 (ISO/IEC 9899:1990):
-
- 3.5.6 类型定义
关键词
参见
|
C++ 文档
关于
typedef
声明
|