2026-08-13
2026-08-13
技术
C 语言
学习内容:C 语言 Day13 笔记——数组(Array)
数组概述
数组是相同类型数据的有序集合,用于批量数据处理。核心概念:
| 概念 | 说明 | 类比 |
|---|---|---|
| 元素(Element) | 数组里的每个数据 | 楼里的每间房 |
| 下标(Index) | 从 0 开始的编号 | 房间号(第 1 间是 0 号) |
| 长度(Length) | 元素总个数 | 总房间数 |
| 数组名 | 首元素地址(指针常量) | 楼的地址 |
下标从 0 开始是 C 设计者有意为之:
arr[i]底层是*(arr + i),i=0 就是首元素本身。
定义数组的四种语法
| 方式 | 写法 | 特点 |
|---|---|---|
| 只定义不初始化 | int a[5]; |
局部数组垃圾值,全局/静态自动清零 |
| 完全初始化 | int b[5] = {1,2,3,4,5}; |
全部指定 |
| 部分初始化 | int c[5] = {1,2}; |
后面自动清零 → {1,2,0,0,0} |
| 省略长度 | int d[] = {1,2,3}; |
编译器推算长度 = 3 |
初始化技巧:
- 全零:
int arr[100] = {0};(最常用)或memset(arr, 0, sizeof(arr)) - 常量数组:
const int nums[5] = {...};必须初始化,之后不可改 - 用宏代替魔数:
#define SIZE 10
访问与遍历
数组不能整体访问,只能通过下标运算符 [] 访问单个元素,arr[i] 用法和普通变量完全一样。
三种遍历模式:正序 for、用 sizeof(arr)/sizeof(arr[0]) 动态算长度(推荐)、反向遍历。
数组内存 = 长度 × 类型宽度,如 int a[10] 占 10×4 = 40 字节。
数组越界
访问下标超出 0 ~ 长度-1 范围即越界。C 语言不检查越界(不像 Java/Python 抛异常)——为极致性能付出的安全代价,是 C 语言排名第一的隐形杀手。
| 情形 | 后果 |
|---|---|
| 轻微越界 | 踩到相邻变量,数据莫名其妙被改 |
| 严重越界 | 踩到返回地址,Segmentation Fault 崩溃 |
| 最隐蔽 | 看似正常,换个环境/数据就崩 |
防御:循环条件用宏常量、assert(index >= 0 && index < SIZE)、手动检查。
数组与函数——退化指针
数组作函数参数时长度信息丢失,三种写法等价:int arr[] / int arr[10] / int *arr,本质都是指针。必须额外传 len 参数。
sizeof 陷阱: 函数内部
sizeof(arr)只能得到指针大小(4 或 8),不是数组实际字节数。sizeof 只有在定义数组的同一作用域内才有效。
多维数组、字符数组与 VLA
- 二维数组:
int matrix[3][4],逻辑上矩阵,内存中行优先连续一维存储 - 字符数组:C 语言无 String 类型,用
\0(空字符)结尾的 char 数组表示字符串。char s[] = "Hello"自动加\0,长度 = 6。标准库字符串函数都依赖\0 - C99 VLA:
int arr[n]运行时定长,C11 变为可选、MSVC 从不支持,嵌入式通常禁用(栈空间不可预知),用malloc更安全
Rust
今日起放慢 Rust 学习节奏("慢点学习"),以消化、复习已学内容为主,不赶进度。
思考
无。
明日计划
- C 语言:进入数组常用操作(查找、插入、删除、排序、逆序)
- Rust:保持慢节奏,复习阶段 3(集合、迭代器、Todo CLI)