C 语言高级特性
一、预处理
// 头文件卫士(推荐用 #pragma once 替代)
#ifndef _MYHEADER_H
#define _MYHEADER_H
/* ... */
#endif
// 条件编译
#ifdef DEBUG
#define LOG(...) fprintf(stderr, __VA_ARGS__)
#else
#define LOG(...) ((void)0)
#endif
// 宏
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
// ↑ Linux 内核链表的核心宏
// 字符串化
#define STR(x) #x
#define CONCAT(a,b) a##b
// __FILE__, __LINE__, __func__, __DATE__, __TIME__
二、volatile 与 restrict
1. volatile(嵌入式核心)
- 告诉编译器:变量可能被外部改变,不要优化
- 场景:硬件寄存器、中断共享变量、多线程共享变量
volatile uint32_t *const UART_REG = (uint32_t *)0x40001000;
// ↑ 每次访问都真的读写内存/寄存器
2. restrict(C99)
- 告诉编译器:此指针是访问该内存的唯一方式,可优化
- 多用于函数参数,如
memcpy(void *restrict dst, const void *restrict src, size_t n)
三、位运算
x | (1 << n) // 置位 n
x & ~(1 << n) // 清位 n
x ^ (1 << n) // 翻转位 n
(x >> n) & 1 // 读位 n
(x & mask) == mask // 检查多个位
实用宏(Linux 内核风格):
#define BIT(n) (1UL << (n))
#define BITS_PER_LONG 32
#define GENMASK(h, l) (((1UL << ((h) - (l) + 1)) - 1) << (l))
#define FIELD_PREP(mask, val) (((val) << __builtin_ctz(mask)) & (mask))
#define FIELD_GET(mask, val) (((val) & (mask)) >> __builtin_ctz(mask))
四、函数指针与回调
typedef int (*cmp_t)(const void *, const void *);
typedef void (*event_cb_t)(int event, void *userdata);
struct event_loop {
event_cb_t cb;
void *userdata;
};
void loop_register(struct event_loop *loop, event_cb_t cb, void *ud) {
loop->cb = cb;
loop->userdata = ud;
}
五、复合字面量(C99)
struct point p = (struct point){ .x = 1, .y = 2 };
int *arr = (int[]){1, 2, 3}; // 匿名数组
六、变长数组(C99)
int n = atoi(argv[1]);
int arr[n]; // 栈上分配(慎用:大数组会栈溢出)
七、可变参数
#include <stdarg.h>
void my_log(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
八、GCC 常用扩展
// 编译期检查
_Static_assert(sizeof(void *) == 8, "Need 64-bit");
// 属性
__attribute__((noreturn)) void die(void);
__attribute__((format(printf, 1, 2))) void log(const char *fmt, ...);
__attribute__((unused)) static int unused_var = 0;
__attribute__((constructor)) void init(void); // main 之前自动调用
__attribute__((destructor)) void fini(void); // main 之后自动调用
__attribute__((deprecated)) void old_func(void);
// 内建函数
__builtin_expect(x, 0) // 分支预测提示(likely/unlikely)
__builtin_popcount(x) // 1 位个数
__builtin_ctz(x) // 末尾 0 个数
__builtin_clz(x) // 前导 0 个数
__builtin_prefetch(p, 0, 1) // 预取
__builtin_memcpy(dst, src, n)// 编译器已知 memcpy 优化
九、__attribute__((cleanup)) —— GNU C 自动清理
static void autofree(void *p) {
free(*(void **)p);
}
void foo(void) {
__attribute__((cleanup(autofree))) char *buf = malloc(64);
/* buf 在作用域结束时自动 free */
}
十、设计模式(C 版本)
- 回调机制:函数指针 + userdata
- 状态机:switch + 状态变量
- 对象模拟:函数指针表(vtable)+ 数据结构
- 发布/订阅:链表 / 哈希表 + 注册回调
- RAII 替代:cleanup 属性 / goto cleanup