C 备忘
C 语言中一些不太常用, 但又有用的语法等备忘;
资料来源:
<>
更新
1
2024.04.06 初始
导语
C 语言中一些不太常用, 但又有用的语法等备忘;
- C11 可用; 编译器指定为 GCC;
C 语言
可变参数
<stdarg.h>
;fun(int x,…)
需要一个固定参数作为锚点;- 通过一组宏来传递可变参数;
va_arg(args, int);
必须知道参数类型; - 没有任何编译检查; 没有任何编译检查;
1 | // 初始化va_list |
线程局部存储 (Thread-Local Storage)
- tls; 线程专有变量声明;
_Thread_local
; c11 引入
1 | _Thread_local int threadLocalVar = 0; |
编译
静态断言 (Static Assertion)
- 编译时的断言检查, 检查失败会阻止编译进行;
- 检查 结构体长度 / 类型兼容 等等
1 |
|
结构体/联合体
匿名结构体和联合体 (Anonymous Structures and Unions)
- 可以在 结构体或联合体中使用匿名结构体和匿名联合体;
- 相当于减少了一层间接访问, 使用上更方便, 特别是层层嵌套下
1 | struct OuterStruct { |
结构体位字段 (Bit-fields)
- 为结构体成员指定精确 几个 bit;
- 用好了非常节省空间; 但有不同平台移植问题;
- 非资源严重受限,一般很少用吧;
1 | struct bitfield { |
灵活数组成员 (Flexible Array Member)
- 声明不定长的数组, 必须是结构体最后一个成员, c99 引入;
- 声明时不指定大小, 通常需要 malloc;
1 | struct flexible_array_struct { |
指定初始化器 (Designated Initializers)
- 初始化结构体时指定成员值
1 | struct point { |
复合字面量 (Compound Literals)
- 直接定义并初始化一个 匿名实例; c99 引入
- 说人话就是,随时方便 初始化任何 (结构体/联合体).
- 和 指定初始化器 有点像;
1 | // (type) { initializer_list } |
数据结构标记 (Tagged Union): 不是语法, 是惯用模式;
- union 定义多组类型; struct 包含 union 和 一个类型变量;
1 | typedef enum { |
宏
使用宏简洁…但是但是,但是 出问题其调试真不是一般麻烦;
类型通用宏 (Type Generic Macros)
- 根据不同类型,选择不同的 宏展开; c11 引入;
- default 是类型不符时的默认展开
1 | // _Generic( expression, type1 : expression1, type2 : expression2, …) |
X-Macros: 不是语法, 是惯用模式;
- 宏的宏;
- 但是在一些库 经常见到; 特别是 hash 或者 链表 库;
1 | // 定义X-Macros |
可变参数宏: 允许宏接受可变数量的参数
__VA_ARGS__
- 一般配合接收可变参数的函数;;;
1 |
|
Gcc
属性 __attribute__
: 告诉编译器一些特定属性;
- 可用于函数 变量 类型等
1 | void my_exit() __attribute__((noreturn)); |
typeof: typeof(表达式)
, 编译器将 表达式的类型来代替整个 typeof
构造
- 在宏中特别特别常用; 有些泛型的意思了;
1 |
|
transparent union: 类型安全的方式将多种不同类型的参数传递给函数,不需要进行显式的类型转换.
- 其实是个
__attribute__
的特例; - 注意: 无法假定 函数内收到的到底是什么类型, 只能通过其他方法取得类型标记;
1 | typedef union { |