C 语言知识速查表
本文档提供 C 语言常用语法和函数的快速参考。
数据类型
基本类型
| 类型 | 大小(典型) | 值范围 |
|---|---|---|
char | 1 字节 | -128 到 127 |
unsigned char | 1 字节 | 0 到 255 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
int | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned int | 4 字节 | 0 到 4,294,967,295 |
long | 4/8 字节 | 至少 -2,147,483,648 到 2,147,483,647 |
long long | 8 字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
float | 4 字节 | 约 ±3.4E38 |
double | 8 字节 | 约 ±1.7E308 |
格式说明符
| 格式符 | 说明 |
|---|---|
%d | 有符号十进制整数 |
%u | 无符号十进制整数 |
%x | 十六进制(小写) |
%X | 十六进制(大写) |
%o | 八进制 |
%f | 浮点数 |
%lf | double |
%e | 科学计数法 |
%c | 字符 |
%s | 字符串 |
%p | 指针 |
%zu | size_t |
%ld | long |
%lld | long long |
运算符优先级
从高到低:
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1 | () [] -> . | 左到右 |
| 2 | ! ~ ++ -- + - * & sizeof | 右到左 |
| 3 | * / % | 左到右 |
| 4 | + - | 左到右 |
| 5 | << >> | 左到右 |
| 6 | < <= > >= | 左到右 |
| 7 | == != | 左到右 |
| 8 | & | 左到右 |
| 9 | ^ | 左到右 |
| 10 | | | 左到右 |
| 11 | && | 左到右 |
| 12 | || | 左到右 |
| 13 | ?: | 右到左 |
| 14 | = += -= *= /= 等 | 右到左 |
| 15 | , | 左到右 |
控制流程
条件语句
if (condition) {
// ...
} else if (condition) {
// ...
} else {
// ...
}
switch (expression) {
case value1:
// ...
break;
case value2:
// ...
break;
default:
// ...
}
循环语句
while (condition) {
// ...
}
do {
// ...
} while (condition);
for (init; condition; update) {
// ...
}
break; // 跳出循环
continue; // 跳过本次迭代
函数
函数声明与定义
int add(int a, int b); // 声明
int add(int a, int b) { return a + b; } // 定义
void process(int* arr, int size); // 数组参数
int* create(void); // 返回指针
函数指针
int (*func_ptr)(int, int); // 声明
func_ptr = add; // 赋值
int result = func_ptr(3, 5); // 调用
typedef int (*Operation)(int, int); // 类型别名
Operation op = add;
指针
基本操作
int x = 10;
int* ptr = &x; // 取地址
int value = *ptr; // 解引用
int* p = NULL; // 空指针
if (p != NULL) { // 检查
*p = 20;
}
指针运算
int arr[] = {1, 2, 3, 4, 5};
int* p = arr;
p++; // 移动到下一个元素
int diff = p - arr; // 元素个数差
指针与 const
const int* p; // 指向常量的指针(不能修改 *p)
int* const p; // 常量指针(不能修改 p)
const int* const p; // 两者都不能修改
数组
声明与初始化
int arr[5];
int arr[] = {1, 2, 3, 4, 5};
int arr[5] = {1, 2}; // 其余为 0
int arr[5] = {0}; // 全部为 0
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
数组大小
int size = sizeof(arr) / sizeof(arr[0]);
字符串
声明与初始化
char str[] = "Hello"; // 可修改
const char* ptr = "Hello"; // 不可修改
char str[100] = {0}; // 空字符串
常用函数
size_t len = strlen(str); // 长度
strcpy(dest, src); // 复制
strncpy(dest, src, n); // 安全复制
strcat(dest, src); // 连接
strncat(dest, src, n); // 安全连接
int cmp = strcmp(s1, s2); // 比较
char* p = strchr(str, 'a'); // 查找字符
char* p = strstr(str, "sub"); // 查找子串
char* token = strtok(str, ","); // 分割
结构体
定义与使用
struct Person {
char name[50];
int age;
};
struct Person p = {"张三", 25};
p.age = 26;
typedef struct {
int x;
int y;
} Point;
Point pt = {10, 20};
Point* ptr = &pt;
ptr->x = 15; // 箭头运算符
内存管理
void* p = malloc(size); // 分配
void* p = calloc(n, size); // 分配并初始化为 0
void* new_p = realloc(p, size); // 重新分配
free(p); // 释放
p = NULL; // 避免悬空指针
文件操作
打开与关闭
FILE* fp = fopen("file.txt", "r"); // 打开
fclose(fp); // 关闭
模式:r(读)、w(写)、a(追加)、rb/wb(二进制)
读写操作
// 字符
int ch = fgetc(fp);
fputc(ch, fp);
// 行
char* s = fgets(buffer, size, fp);
fputs(str, fp);
// 格式化
fprintf(fp, "值: %d\n", value);
fscanf(fp, "%d", &value);
// 二进制
size_t n = fread(buffer, size, count, fp);
size_t n = fwrite(buffer, size, count, fp);
文件定位
fseek(fp, offset, SEEK_SET); // 从开头
fseek(fp, offset, SEEK_CUR); // 从当前位置
fseek(fp, offset, SEEK_END); // 从末尾
long pos = ftell(fp); // 当前位置
rewind(fp); // 回到开头
预处理器
宏定义
#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
#undef PI // 取消定义
条件编译
#ifdef DEBUG
// ...
#endif
#ifndef HEADER_H
#define HEADER_H
// ...
#endif
#if VERSION >= 2
// ...
#elif VERSION == 1
// ...
#else
// ...
#endif
预定义宏
__FILE__ // 文件名
__LINE__ // 行号
__func__ // 函数名
__DATE__ // 编译日期
__TIME__ // 编译时间
常用标准库函数
stdlib.h
malloc(size) // 分配内存
calloc(n, size) // 分配并初始化
realloc(ptr, size) // 重新分配
free(ptr) // 释放内存
atoi(str) // 字符串转整数
atof(str) // 字符串转浮点数
strtol(str, &end, base) // 安全转换
rand() // 随机数
srand(seed) // 设置种子
qsort(arr, n, size, cmp) // 快速排序
bsearch(&key, arr, n, size, cmp) // 二分搜索
exit(status) // 退出程序
string.h
strlen(str) // 长度
strcpy(dst, src) // 复制
strcat(dst, src) // 连接
strcmp(s1, s2) // 比较
strchr(str, ch) // 查找字符
strstr(str, sub) // 查找子串
memcpy(dst, src, n) // 内存复制
memmove(dst, src, n) // 内存移动
memset(ptr, c, n) // 内存设置
memcmp(p1, p2, n) // 内存比较
ctype.h
isalpha(c) // 是否字母
isdigit(c) // 是否数字
isalnum(c) // 是否字母或数字
isspace(c) // 是否空白
isupper(c) // 是否大写
islower(c) // 是否小写
toupper(c) // 转大写
tolower(c) // 转小写
math.h
fabs(x) // 绝对值
sqrt(x) // 平方根
pow(x, y) // x 的 y 次方
ceil(x) // 向上取整
floor(x) // 向下取整
round(x) // 四舍五入
sin(x) // 正弦
cos(x) // 余弦
tan(x) // 正切
log(x) // 自然对数
log10(x) // 以 10 为底的对数
exp(x) // e 的 x 次方
time.h
time(NULL) // 当前时间戳
localtime(&t) // 本地时间
gmtime(&t) // UTC 时间
ctime(&t) // 时间字符串
strftime(buf, size, fmt, tm) // 格式化
clock() // 处理器时间
常见错误
| 错误 | 原因 | 解决方法 |
|---|---|---|
| 段错误 | 访问非法内存 | 检查空指针、数组越界 |
| 内存泄漏 | 未释放内存 | 确保 free 每个 malloc |
| 悬空指针 | 使用已释放的内存 | 释放后置 NULL |
| 缓冲区溢出 | 写入超过分配大小 | 使用安全的函数 |
| 未定义行为 | 越界、除零等 | 仔细检查边界条件 |
编译命令
gcc program.c -o program # 基本编译
gcc -Wall program.c -o program # 显示警告
gcc -g program.c -o program # 包含调试信息
gcc -O2 program.c -o program # 优化级别 2
gcc -std=c11 program.c -o program # 指定标准
gcc -E program.c # 只预处理
gcc -S program.c # 生成汇编
调试技巧
gdb ./program # 启动 GDB
break main # 设置断点
run # 运行
next # 单步(不进入函数)
step # 单步(进入函数)
print var # 打印变量
backtrace # 调用栈
continue # 继续执行
quit # 退出
C23 新特性速查
新关键字
| 关键字 | 说明 |
|---|---|
nullptr | 空指针常量(替代 NULL) |
constexpr | 编译时常量 |
true / false | 布尔字面量(无需 stdbool.h) |
alignas | 对齐指定 |
alignof | 对齐查询 |
typeof | 类型推断 |
typeof_unqual | 无限定符的类型推断 |
新类型
nullptr_t // nullptr 的类型
_BitInt(N) // 位精确整数,如 _BitInt(128)
unsigned _BitInt(N) // 无符号位精确整数
char8_t // UTF-8 字符类型(uchar.h)
_Decimal32 // 十进制浮点(可选)
_Decimal64
_Decimal128
属性
[[nodiscard]] // 警告忽略返回值
[[nodiscard("消息")]] // 带消息的警告
[[maybe_unused]] // 抑制未使用警告
[[deprecated]] // 标记弃用
[[deprecated("消息")]] // 带消息的弃用
[[fallthrough]] // switch 穿透
[[noreturn]] // 函数不返回
[[unsequenced]] // 函数无副作用
[[reproducible]] // 函数可重现
新常量语法
nullptr // 空指针
0b101010 // 二进制常量
1'000'000 // 数字分隔符
0xFF'FF'FF'FF // 十六进制分隔符
constexpr int N = 100; // 编译时常量
新预处理器指令
#elifdef MACRO // 等价于 #elif defined(MACRO)
#elifndef MACRO // 等价于 #elif !defined(MACRO)
#warning "消息" // 编译警告
#embed "file.bin" // 嵌入文件内容
__VA_OPT__(,) // 可变参数处理
新库函数
// 安全函数
memset_explicit(ptr, 0, size); // 保证清除内存
// POSIX 标准化函数
strdup(str); // 复制字符串
strndup(str, n); // 复制前 n 个字符
memccpy(dst, src, c, n); // 复制直到字符 c
localtime_r(&time, &tm); // 线程安全时间
gmtime_r(&time, &tm); // 线程安全 UTC 时间
// UTF-8 支持
char8_t ch = u8'A';
mbrtoc8(&ch8, src, n, &state); // 多字节转 UTF-8
c8rtomb(dst, ch8, &state); // UTF-8 转多字节
新格式说明符
printf("%b", value); // 二进制输出
printf("%08b", value); // 8 位二进制
类型推断(auto)
auto x = 42; // int
auto y = 3.14; // double
auto ptr = &value; // int*
auto str = "hello"; // char*
typeof 运算符
typeof(x) y = x; // y 的类型与 x 相同
typeof(0) z; // int z
// 泛型宏
#define SWAP(a, b) do { \
typeof(a) temp = a; \
a = b; \
b = temp; \
} while (0)
单参数 static_assert
static_assert(sizeof(int) == 4); // C23
static_assert(sizeof(int) == 4, "msg"); // C11
C23 编译选项
gcc -std=c23 program.c -o program # C23 标准
gcc -std=c2x program.c -o program # 过渡期选项
clang -std=c23 program.c -o program
C11 线程库 threads.h 速查
线程操作
thrd_t thread;
thrd_create(&thread, func, arg); // 创建线程
thrd_join(thread, &result); // 等待线程结束
thrd_detach(thread); // 分离线程
thrd_current(); // 获取当前线程
thrd_equal(t1, t2); // 比较线程
thrd_exit(0); // 退出线程
thrd_sleep(&ts, NULL); // 休眠
thrd_yield(); // 让出 CPU
互斥量
mtx_t mutex;
mtx_init(&mutex, mtx_plain); // 创建互斥量
mtx_lock(&mutex); // 加锁
mtx_trylock(&mutex); // 尝试加锁
mtx_timedlock(&mutex, &timeout); // 超时加锁
mtx_unlock(&mutex); // 解锁
mtx_destroy(&mutex); // 销毁互斥量
// 互斥量类型
mtx_plain // 普通互斥量
mtx_recursive // 递归互斥量
mtx_timed // 支持超时
条件变量
cnd_t cond;
cnd_init(&cond); // 创建条件变量
cnd_wait(&cond, &mutex); // 等待
cnd_timedwait(&cond, &mutex, &ts); // 超时等待
cnd_signal(&cond); // 通知一个线程
cnd_broadcast(&cond); // 通知所有线程
cnd_destroy(&cond); // 销毁条件变量
线程特定存储
tss_t key;
tss_create(&key, destructor); // 创建 TSS
tss_set(key, data); // 设置数据
tss_get(key); // 获取数据
tss_delete(key); // 删除 TSS
一次性调用
once_flag flag = ONCE_FLAG_INIT;
call_once(&flag, init_func); // 只执行一次
C11 原子操作库 stdatomic.h 速查
原子类型
atomic_int counter; // 原子整数
atomic_bool flag; // 原子布尔
atomic_size_t size; // 原子 size_t
atomic_flag spinlock; // 原子标志(保证无锁)
基本操作
atomic_store(&var, value); // 原子存储
atomic_load(&var); // 原子加载
atomic_exchange(&var, new_val); // 原子交换(返回旧值)
atomic_compare_exchange_strong(&var, &expected, desired); // CAS
atomic_compare_exchange_weak(&var, &expected, desired); // 弱 CAS
算术操作
atomic_fetch_add(&var, n); // 原子加法(返回旧值)
atomic_fetch_sub(&var, n); // 原子减法
atomic_fetch_or(&var, n); // 原子或运算
atomic_fetch_and(&var, n); // 原子与运算
atomic_fetch_xor(&var, n); // 原子异或
atomic_flag 操作
atomic_flag flag = ATOMIC_FLAG_INIT;
atomic_flag_test_and_set(&flag); // 测试并设置(返回旧值)
atomic_flag_clear(&flag); // 清除
内存序
memory_order_relaxed // 无顺序约束
memory_order_acquire // 获取语义
memory_order_release // 释放语义
memory_order_acq_rel // 获取-释放
memory_order_seq_cst // 顺序一致性(默认)
// 带内存序的操作
atomic_store_explicit(&var, val, memory_order_release);
atomic_load_explicit(&var, memory_order_acquire);
锁自由检查
ATOMIC_INT_LOCK_FREE // 0=从不无锁, 1=有时, 2=总是
ATOMIC_BOOL_LOCK_FREE
ATOMIC_POINTER_LOCK_FREE
atomic_is_lock_free(&var);
代码风格建议
- 使用有意义的变量名
- 保持函数简短(不超过 50 行)
- 添加必要的注释
- 使用 const 保护只读数据
- 检查所有可能的错误
- 释放所有分配的资源
- 避免魔法数字,使用宏或常量
- C23 推荐使用 nullptr 替代 NULL
- C23 推荐使用 constexpr 定义编译时常量