C++ 编程语法
数组是存储相同类型数据的容器,像一排连续的格子。本章涵盖一维数组、二维数组、字符数组(C 风格字符串)及常用操作。
6.1
数组(array)是一种线性数据结构,将相同类型的元素存储在连续的内存空间中。元素在数组中的位置称为索引(index),索引从 0 开始。
| 规则 | 合法示例 | 不合法示例 | 原因 |
|---|---|---|---|
| 只能含字母、数字、下划线 | scores, my_arr | my-arr | 含连字符 |
| 不能以数字开头 | arr2 | 2arr | 数字开头 |
| 不能与已定义变量重名 | myArr | int n=5; int n[10]; | 名字冲突 |
| 不能使用关键字 | forArr | int for[5]; | for 是关键字 |
| 1 | // 语法:类型 数组名[大小]; |
| 2 | int a[5]; // 定义可存 5 个整数的数组(未初始化) |
| 3 | |
| 4 | int b[5] = {90, 85, 78, 92, 88}; // 完整初始化 |
| 5 | int c[] = {90, 85, 78, 92, 88}; // 省略大小,自动推断为 5 |
| 6 | int d[5] = {1, 2}; // 部分初始化 → {1, 2, 0, 0, 0} |
| 7 | |
| 8 | a = b; // ❌ 错误!数组变量之间不能直接赋值 |
main() 内的局部数组存放在栈(Stack)中,栈空间默认仅 1~2 MB。数组过大会立即导致栈溢出(程序崩溃),且无任何警告,是极隐蔽的错误。main() 外部(全局变量),它会被分配到静态存储区,空间充裕。6.1.3
数组下标从 0 开始,最后一个元素的下标是 大小 - 1。通过 数组名[下标] 访问或修改指定位置的元素。
| 1 | int a[5] = {90, 85, 78, 92, 88}; |
| 2 | //下标: 0 1 2 3 4 |
| 3 | |
| 4 | cout << a[0]; // 输出:90(第1个元素) |
| 5 | cout << a[4]; // 输出:88(最后一个,下标 = 大小-1) |
| 6 | a[2] = 99; // 修改第3个元素 |
| 7 | |
| 8 | a[3] = {0,1,2}; // ❌ 错误!非定义时不能整体赋值 |
| 9 | |
| 10 | // 用循环遍历数组 |
| 11 | for (int i = 0; i < 5; i++) |
| 12 | cout << a[i] << " "; |
a[5](越界)不会报错,但会读写到相邻内存,造成程序崩溃或数据错误,是极危险的隐藏 bug。始终确保下标在 [0, 大小-1] 范围内。6.1.4
数组元素在内存中紧挨着,中间没有空间。在索引 1 处插入元素 3 时,需要先将该位置及之后的所有元素依次向后移动一位,再写入新值。由于数组长度固定,插入会导致尾部元素丢失。
| 1 | int index = 1, num = 3; |
| 2 | int nums[5] = {1,2,5,4,0}; |
| 3 | |
| 4 | // 从后往前移动,腾出 index 位置 |
| 5 | for (int i = 5 - 1; i > index; i--) |
| 6 | nums[i] = nums[i - 1]; |
| 7 | |
| 8 | nums[index] = num; // 写入新值 |
6.1.5
删除索引 1 处的元素时,需要把该位置之后的所有元素依次向前移动一位。删除后末尾元素无意义,有效长度减 1。
| 1 | int index = 1; |
| 2 | int nums[5] = {1,3,2,5,4}; |
| 3 | |
| 4 | // 从前往后移动,覆盖 index 位置 |
| 5 | for (int i = index; i < 5 - 1; i++) |
| 6 | nums[i] = nums[i + 1]; // 后一个覆盖前一个 |
| 7 | // 末尾元素已无意义,有效长度 -1 |
6.1.6 & 6.1.7
| 1 | int a[] = {3,1,4,1,5,9,2,6}, n = 8; |
| 2 | |
| 3 | // ── 求最大值 ── |
| 4 | int maxVal = a[0]; // 以第一个元素为初始最大值 |
| 5 | for (int i = 1; i < n; i++) |
| 6 | if (a[i] > maxVal) maxVal = a[i]; |
| 7 | |
| 8 | // ── 求总和与平均值 ── |
| 9 | int sum = 0; |
| 10 | for (int i = 0; i < n; i++) sum += a[i]; |
| 11 | double avg = (double)sum / n; |
| 12 | |
| 13 | // ── 逆序输出 ── |
| 14 | for (int i = n-1; i >= 0; i--) cout << a[i] << " "; |
sort() 排序(需 #include <algorithm>)| 1 | #include <algorithm> |
| 2 | int a[] = {3, 1, 4, 1, 5, 9}, n = 6; |
| 3 | |
| 4 | sort(a, a + n); // 升序:1 1 3 4 5 9 |
| 5 | sort(a, a + n, greater<int>()); // 降序:9 5 4 3 1 1 |
6.2
二维数组像一张表格,有行和列两个维度,适合存储矩阵、棋盘等数据。语法是 类型 数组名[行数][列数];。
| 1 | int matrix[2][3] = |
| 2 | { |
| 3 | {1, 2, 3}, // 第0行 |
| 4 | {4, 5, 6} // 第1行 |
| 5 | }; |
| 6 | |
| 7 | cout << matrix[0][1]; // 输出:2 |
| 8 | cout << matrix[1][2]; // 输出:6 |
| 9 | |
| 10 | // 嵌套循环遍历 |
| 11 | for (int i = 0; i < 2; i++) // 遍历行 |
| 12 | { |
| 13 | for (int j = 0; j < 3; j++) // 遍历列 |
| 14 | cout << matrix[i][j] << " "; |
| 15 | cout << endl; |
| 16 | } |
6.3
字符数组是 C 语言处理字符串的方式,本质是 char 类型的一维数组,但有一个特殊规定:末尾必须有 '\0'(空字符,ASCII = 0)作为终止符,告诉程序"字符串到这里结束了"。
| 1 | char name[8] = "abcdefg"; // 7 字符 + \0,长度必须 ≥ 8 |
| 2 | char str[] = "Hello"; // 自动推断长度为 6(5 + \0) |
| 3 | |
| 4 | // 读取单词(遇空格停止) |
| 5 | char word[20]; |
| 6 | cin >> word; // 遇空格停止 |
| 7 | |
| 8 | // 读取含空格的整行 |
| 9 | char sentence[100]; |
| 10 | cin.getline(sentence, 100); // 读取整行,包括空格 |
| 11 | |
| 12 | // 混用 cin 和 getline 时需先清空缓冲区 |
| 13 | int a; cin >> a; |
| 14 | cin.sync(); // 清空缓冲区残留的换行符 |
| 15 | cin.getline(sentence, 100); |
cin 读取整数后调用 cin.sync() 清空缓冲区,否则 getline 会直接读到残留的换行符。| 转义字符 | 含义 | ASCII | 使用示例 |
|---|---|---|---|
| \n | 换行 | 10 | cout << "Hello\nWorld"; |
| \t | 水平制表符(Tab) | 9 | cout << "A\tB\tC"; |
| \\ | 一个反斜杠 \ | 92 | cout << "C:\\Users"; |
| \" | 一个双引号 " | 34 | cout << "\"Hello\""; |
| \' | 一个单引号 ' | 39 | char c = '\''; |
| \0 | 字符串终止符(空字符) | 0 | char s[] = {'H','i','\0'}; |
#include <cstring>)| 函数 | 功能 | 示例 |
|---|---|---|
| strlen(s) | 返回字符串有效长度(不含 \0) | strlen("Hello") → 5 |
| strcpy(dest, src) | 将 src 复制到 dest | strcpy(b, a) |
| strcat(s1, s2) | 将 s2 拼接到 s1 末尾 | strcat(s, " World") |
| strcmp(s1, s2) | 比较字符串大小(按 ASCII),相等返回 0 | strcmp("abc","abc") → 0 |
| strlwr(s) | 将字符串转为全小写 | strlwr("HELLO") → "hello" |
| strupr(s) | 将字符串转为全大写 | strupr("hello") → "HELLO" |
| atoi(s) | 字符串转整数(非数字返回 0) | atoi("123") → 123 |
| atof(s) | 字符串转 double(非数字返回 0.0) | atof("3.14") → 3.14 |
6.3.5
<cctype><cctype> 提供了一系列字符分类和转换函数,参数为 int(传入 char 会自动转换),判断函数返回 0(假)或非 0(真)。
isdigit、isalpha、toupper/tolower 是字符处理题中使用频率最高的函数,搭配 for 循环遍历字符数组,可以快速完成字符分类、大小写转换等任务。