跳到主要内容

C 语言知识速查表

本文档提供 C 语言常用语法和函数的快速参考。

数据类型

基本类型

类型大小(典型)值范围
char1 字节-128 到 127
unsigned char1 字节0 到 255
short2 字节-32,768 到 32,767
unsigned short2 字节0 到 65,535
int4 字节-2,147,483,648 到 2,147,483,647
unsigned int4 字节0 到 4,294,967,295
long4/8 字节至少 -2,147,483,648 到 2,147,483,647
long long8 字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
float4 字节约 ±3.4E38
double8 字节约 ±1.7E308

格式说明符

格式符说明
%d有符号十进制整数
%u无符号十进制整数
%x十六进制(小写)
%X十六进制(大写)
%o八进制
%f浮点数
%lfdouble
%e科学计数法
%c字符
%s字符串
%p指针
%zusize_t
%ldlong
%lldlong 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 定义编译时常量