当前位置: 首页 > news >正文

C 语言基础知识复习资料

C 语言基础知识复习资料

目录

  1. 数据类型与变量

  2. 运算符与表达式

  3. 控制结构

  4. 数组与字符串

  5. 函数

  6. 指针 ⭐⭐⭐

  7. 结构体与联合体

  8. 文件操作

  9. 内存管理 ⭐⭐⭐


1. 数据类型与变量

1.1 基本数据类型

类型关键字大小说明
整型int4 字节基本整型
短整型short2 字节
长整型long4/8 字节
字符型char1 字节
单精度浮点float4 字节
双精度浮点double8 字节

1.2 类型修饰符

signed int a; // 有符号整型(默认) unsigned int b; // 无符号整型 long int c; // 长整型 short int d; // 短整型

1.3 变量声明与初始化

int a; // 声明,未初始化(值为随机值) int b = 10; // 声明并初始化 int c = 0; // 显式初始化为 0 const int MAX = 100; // 常量(不可修改)

⚠️ 易错点:

  • 未初始化的局部变量值是随机的(垃圾值)

  • 全局变量和静态变量默认初始化为 0

  • const变量必须在声明时初始化

1.4 例题

例题 1:下列哪个变量的值是不确定的?

int a; int b = 0; static int c;

答案:a(局部变量未初始化)


2. 运算符与表达式

2.1 算术运算符

+ - * / % // 加减乘除取模

⚠️ 易错点:

  • 整数除法结果是整数:5 / 2 = 2

  • 取模运算只能用于整数:5 % 2 = 1

2.2 自增自减运算符

int a = 5; int b = a++; // b = 5, a = 6 (后置:先使用后加) int c = ++a; // a = 7, c = 7 (前置:先加后使用)

⚠️ 重点:后置返回原值,前置返回新值

2.3 关系与逻辑运算符

== != > < >= <= // 关系运算符 ! && || // 逻辑运算符

2.4 位运算符

& // 按位与 | // 按位或 ^ // 按位异或 ~ // 按位取反 << // 左移 >> // 右移

例题:5 << 1的结果是?答案:10(相当于 5 * 2)

2.5 运算符优先级(高到低)

() [] -> . // 括号、数组、成员访问 ! ~ ++ -- // 单目运算符 * / % // 乘除取模 + - // 加减 << >> // 移位 < <= > >= // 关系 == != // 相等 & // 位与 ^ // 位异或 | // 位或 && // 逻辑与 || // 逻辑或 ?: // 条件 = += -= // 赋值

3. 控制结构

3.1 if-else 语句

if (条件) { // 代码块 } else if (条件) { // 代码块 } else { // 代码块 }

⚠️ 易错点:

  • 判断相等用==,不是=

  • C 语言中 0 为假,非 0 为真

3.2 switch 语句

switch (表达式) { case 常量 1: // 代码 break; case 常量 2: // 代码 break; default: // 默认代码 }

⚠️ 易错点:

  • 忘记写break会导致"穿透"(继续执行下一个 case)

  • case 后面必须是常量表达式

3.3 循环语句

// for 循环 for (初始化; 条件; 更新) { // 代码 } ​ // while 循环 while (条件) { // 代码 } ​ // do-while 循环(至少执行一次) do { // 代码 } while (条件);

3.4 break 和 continue

break; // 跳出整个循环/switch continue; // 跳过本次循环,进入下一次

3.5 例题

例题:以下代码输出什么?

for (int i = 0; i < 5; i++) { if (i == 3) continue; printf("%d ", i); }

答案:0 1 2 4


4. 数组与字符串

4.1 一维数组

int arr[5] = {1, 2, 3, 4, 5}; // 初始化 int arr[5] = {0}; // 全部初始化为 0 int arr[] = {1, 2, 3}; // 自动推断大小为 3

⚠️ 重点:

  • 数组索引从 0 开始

  • 数组名是数组首元素的地址(指针)

4.2 二维数组

int matrix[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };

4.3 字符数组与字符串

char str1[] = "hello"; // 自动包含 '\0',长度为 6 char str2[6] = "hello"; // 刚好容纳 char str3[] = {'h', 'e', 'l', 'l', 'o', '\0'}; // 手动添加结束符

⚠️ 易错点:

  • 字符串必须以\0结尾

  • strlen()返回不包括\0的长度

4.4 字符串操作函数

#include <string.h> ​ strlen(str) // 字符串长度 strcpy(dest, src) // 字符串复制 strcat(str1, str2) // 字符串连接 strcmp(str1, str2) // 字符串比较(返回 0 表示相等)

4.5 例题

例题:strlen("hello")sizeof("hello")的结果分别是?答案:56


5. 函数

5.1 函数定义与声明

// 函数声明(原型) int add(int a, int b); ​ // 函数定义 int add(int a, int b) { return a + b; } ​ // 无返回值函数 void print(int n) { printf("%d", n); }

5.2 参数传递

C 语言只有值传递!

void swap_wrong(int a, int b) { int temp = a; a = b; b = temp; // 不会改变实参 } ​ void swap_correct(int *a, int *b) { int temp = *a; *a = *b; *b = temp; // 通过指针改变实参 }

⭐⭐⭐ 重点:要修改实参必须传递指针

5.3 递归函数

int factorial(int n) { if (n <= 1) return 1; // 终止条件 return n * factorial(n - 1); }

⚠️ 易错点:必须设置终止条件,否则会栈溢出

5.4 例题

例题:以下代码能否交换 a 和 b 的值?

void swap(int x, int y) { int t = x; x = y; y = t; } int main() { int a = 1, b = 2; swap(a, b); return 0; }

答案:不能,C 语言是值传递


6. 指针 ⭐⭐⭐⭐⭐

6.1 指针基础

int a = 10; int *p = &a; // p 指向 a 的地址 *p = 20; // 通过指针修改 a 的值

⭐⭐⭐ 重点:

  • &取地址运算符

  • *解引用运算符(获取指针指向的值)

6.2 指针运算

int arr[] = {1, 2, 3, 4, 5}; int *p = arr; ​ p++; // 指向下一个元素(移动 sizeof(int) 字节) p + 2; // 指向 arr[2] *(p + 3); // 等价于 arr[3]

6.3 指针与数组

int arr[5] = {1, 2, 3, 4, 5}; ​ arr[i] == *(arr + i) // 等价 i[arr] == arr[i] // 等价(合法但不推荐)

6.4 多级指针

int a = 10; int *p = &a; int **pp = &p; ​ **pp = 20; // 修改 a 的值为 20

6.5 空指针与野指针

int *p = NULL; // 空指针(安全) int *p; // 野指针(危险!未初始化)

⚠️ 易错点:

  • 使用指针前必须初始化

  • 释放内存后应将指针置为 NULL

6.6 const 与指针

const int *p1; // 指向常量的指针(不能通过 p1 修改值) int *const p2; // 常量指针(p2 不能指向其他地方) const int *const p3; // 指向常量的常量指针(两者都不能)

6.7 函数指针

int add(int a, int b) { return a + b; } ​ int (*func_ptr)(int, int) = add; // 声明函数指针 int result = func_ptr(3, 4); // 调用

6.8 例题

例题:以下代码输出什么?

int arr[] = {1, 2, 3}; int *p = arr; printf("%d", *(++p));

答案:2


7. 结构体与联合体

7.1 结构体

struct Student { char name[20]; int age; float score; }; ​ // 定义结构体变量 struct Student s1 = {"张三", 20, 95.5}; ​ // 访问成员 s1.age = 21; printf("%s", s1.name); ​ // 结构体指针 struct Student *p = &s1; p->age = 22; // 等价于 (*p).age

7.2 typedef 简化

typedef struct { int x; int y; } Point; ​ Point p = {1, 2}; // 不需要 struct 关键字

7.3 联合体

union Data { int i; float f; char c; }; ​ // 所有成员共享同一块内存 union Data d; d.i = 10; d.f = 3.14; // i 的值会被覆盖

⭐⭐⭐ 重点:联合体所有成员共享内存,大小等于最大成员的大小

7.4 例题

例题:以下结构体大小是多少?

struct { char a; int b; char c; };

答案:通常为 8 字节(考虑内存对齐)


8. 文件操作

8.1 基本操作

#include <stdio.h> ​ // 打开文件 FILE *fp = fopen("file.txt", "r"); // r: 读,w: 写,a: 追加 ​ // 读写操作 fscanf(fp, "%d", &n); fprintf(fp, "%d", n); ​ // 关闭文件 fclose(fp);

8.2 文件操作模式

模式说明
"r"只读打开
"w"只写打开(清空原文件)
"a"追加打开
"r+"读写打开
"w+"读写打开(清空)
"rb"二进制读
"wb"二进制写

8.3 文件读写函数

fgetc(fp); // 读取一个字符 fputc(c, fp); // 写入一个字符 fgets(str, n, fp); // 读取一行 fputs(str, fp); // 写入字符串 fread(buf, size, count, fp); // 二进制读 fwrite(buf, size, count, fp); // 二进制写

8.4 文件位置操作

fseek(fp, 0, SEEK_SET); // 移动到文件开头 fseek(fp, 0, SEEK_CUR); // 当前位置 fseek(fp, 0, SEEK_END); // 文件末尾 ftell(fp); // 获取当前位置 rewind(fp); // 回到文件开头

8.5 例题

例题:以下代码有什么问题?

FILE *fp = fopen("test.txt", "w"); fclose(fp);

答案:没有检查 fopen 是否成功返回 NULL


9. 内存管理 ⭐⭐⭐⭐⭐

9.1 动态内存分配

#include <stdlib.h> // 分配内存 int *p = (int *)malloc(sizeof(int)); // 分配 1 个 int int *arr = (int *)malloc(10 * sizeof(int)); // 分配 10 个 int // 分配并初始化为 0 int *p = (int *)calloc(10, sizeof(int)); // 10 个 int,初始为 0 // 调整大小 p = (int *)realloc(p, 20 * sizeof(int)); // 释放内存 free(p); p = NULL; // 防止悬空指针

9.2 内存分配函数对比

函数说明初始化
malloc(n)分配 n 字节不初始化
calloc(n, s)分配 n 个 s 字节初始化为 0
realloc(p, n)调整 p 的大小新部分不初始化
free(p)释放内存-

9.3 常见内存问题

内存泄漏:分配后未释放

void leak() { int *p = malloc(sizeof(int)); // 忘记 free(p) }

重复释放:

free(p); free(p); // 错误!

悬空指针:

int *p = malloc(sizeof(int)); free(p); *p = 10; // 错误!访问已释放内存

⚠️ 重点:

  • 每次malloc都要对应free

  • free后应将指针置为 NULL

  • 检查malloc返回值是否为 NULL

9.4 存储类别

auto int a = 10; // 自动变量(默认),栈上 static int b = 0; // 静态变量,数据区,保留值 extern int c; // 外部变量,引用其他文件的变量 register int d; // 寄存器变量(建议)

9.5 例题

例题:以下代码有什么问题?

int *get_array() { int arr[10]; return arr; // 返回局部数组地址 }

答案:返回了栈上局部变量的地址,函数返回后内存已释放


重点总结

⭐⭐⭐⭐⭐ 必须掌握

  1. 指针操作:指针与数组、指针运算、函数指针

  2. 内存管理:malloc/free、内存泄漏、内存对齐

  3. 结构体:定义、访问、结构体指针

⭐⭐⭐⭐ 重点掌握

  1. 函数参数传递:值传递、通过指针修改实参

  2. 字符串操作:字符串结束符、常用字符串函数

  3. 文件操作:文件打开模式、读写函数

⭐⭐⭐ 常考易错

  1. 自增自减:前置与后置的区别

  2. const 修饰:const 指针与指针 const

  3. 联合体:共享内存特性

  4. 递归:终止条件


综合练习题

练习 1:指针与数组

// 编写函数,使用指针遍历数组并求和 int sum_array(int *arr, int size);

练习 2:结构体

// 定义学生结构体,包含姓名、学号、成绩 // 编写函数计算平均分

练习 3:链表

// 创建单链表,实现插入、删除、遍历操作

练习 4:文件操作

// 读取文件内容并统计单词数量

参考资源

  • 《C Primer Plus》

  • 《C 和指针》

  • 《C 陷阱与缺陷》

  • 《深入理解计算机系统》


祝学习顺利!

http://www.jsqmd.com/news/573507/

相关文章:

  • Linux安装中文+MySQL的详细过程
  • ECharts折线图入门学习:从基础到实战的完整指南
  • Linux USB驱动开发核心技术与面试解析
  • OpenClaw自动化周报:Qwen3.5-9B解读工作截图生成总结
  • 万象视界灵坛在数字营销中的应用:广告图语义一致性自动评估系统
  • Spring Boot 异步任务线程池性能优化
  • SEO_10个提升网站排名的实用SEO技巧分享(370 )
  • PWM技术原理与工程实践全解析
  • OpenClaw备份恢复:千问3.5-35B-A3B-FP8配置迁移指南
  • 国产AI绘画模型Z-Image轻松玩:Neeshck-Z-lmage_LYX_v2部署全攻略
  • 1.2 电容 CAP Capacitance:从基础原理到高频电路中的关键应用
  • 浙江高速横切机采购指南:鸿科机械以实力铸就可靠之选 - 2026年企业推荐榜
  • 为什么是GBA什么是PBA
  • Java调用C/C++代码慢如蜗牛?揭秘外部函数调用延迟超200ms的5个隐藏瓶颈及实时优化清单
  • SAP FI模块实战:OBC4配置字段状态变式全流程解析(含常见报错处理)
  • 若依管理系统实战:基于Vuex的用户角色权限与动态菜单路由解析
  • Claude Code代码泄露,Anthropic损失几何?
  • AsyncAnalog库:AVR平台非阻塞ADC采样实战
  • 区块链智能合约安全审计:重入攻击与溢出漏洞防范
  • Vite项目中postcss-px-to-viewport的进阶配置:精准适配Vant与自定义设计稿
  • 内网渗透全流程拆解|从入门到实战,小白也能看懂的步骤
  • 轻流MCP|让AI从「会回答」走向「能参与实际业务」
  • OpenClaw外设控制扩展:Qwen2.5-VL-7B通过摄像头实时图像分析
  • 嵌入式开发中的编程规范实践与经验分享
  • 廊坊家庭如何选择专业母婴护理服务?2026年市场趋势与避坑指南 - 2026年企业推荐榜
  • 配置MyBatis-Plus打印执行的 SQL 语句到控制台或日志文件中
  • HexView 刷写文件脚本处理工具-进阶应用(十)-动态数据对齐与智能填充策略
  • AI 编码工具提升助力开源维护,法律与质量问题待解
  • Matlab布谷鸟算法:多目标优化求解代码(成本、时间、质量为目标)
  • 14天想冲刺蓝桥杯day3