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); // 连接
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 # 退出
代码风格建议
- 使用有意义的变量名
- 保持函数简短(不超过 50 行)
- 添加必要的注释
- 使用 const 保护只读数据
- 检查所有可能的错误
- 释放所有分配的资源
- 避免魔法数字,使用宏或常量