第七章:数组与字符串
7.1 一维数组声明与遍历
定义与初始化
一维数组是相同类型元素的线性集合,声明语法:
数据类型 数组名[长度]; // 声明未初始化
数据类型 数组名[长度] = {值列表}; // 声明并初始化
初始化方式 | 示例 | 说明 |
完全初始化 | int arr[3] = {1, 2, 3}; | 所有元素显式赋值。 |
部分初始化 | int arr[5] = {0}; | 未显式赋值的元素自动初始化为0。 |
不指定长度(自动推导) | int arr[] = {4, 5, 6}; | 编译器根据初始值数量确定长度(此处为3)。 |
数组遍历
通过循环访问每个元素(下标从 0
开始):
int scores[5] = {85, 90, 78, 92, 88};
for (int i = 0; i < 5; i++) {
printf("scores[%d] = %d\n", i, scores[i]);
}
注意事项:
• 数组长度必须是编译时常量(C99前)。
• 越界访问是未定义行为(可能导致程序崩溃或数据损坏)。
7.2 二维数组与多维数组
二维数组声明
二维数组是“数组的数组”,语法:
数据类型 数组名[行数][列数];
内存排列:按行优先顺序存储。
初始化与遍历:
// 声明并初始化二维数组
int matrix[2][3] = {
{1, 2, 3}, // 第0行
{4, 5, 6} // 第1行
};
// 嵌套循环遍历
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
输出:
1 2 3
4 5 6
多维数组
类似二维数组扩展,如三维数组:
int cube[2][3][4]; // 2层,每层3行4列
7.3 字符数组与字符串
字符数组
用于存储字符序列,需手动添加终止符 \0
(ASCII值为0):
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str2[] = "World"; // 自动添加'\0',长度为6
字符串特性:
• 以 \0
结尾,长度比可见字符数多1。
• 可用字符串字面量初始化(如 char s[] = "abc";
)。
示例:输入输出字符串
char name[20];
printf("请输入姓名:");
scanf("%s", name); // 输入到name数组(自动补'\0')
printf("姓名:%s\n", name);
注意事项:
• scanf("%s", name)
会忽略空格和换行,可能引发缓冲区溢出(慎用)。
7.4 常用字符串处理函数
需包含头文件 <string.h>
,常见函数如下:
函数 | 功能 | 示例 | 注意事项 |
strlen(str) | 返回字符串长度(不含\0 ) | strlen("Hello") → 5 | 确保字符串以\0 结尾。 |
strcpy(dest, src) | 复制src到dest | strcpy(s1, s2); | dest需足够大,否则溢出。 |
strcat(dest, src) | 将src追加到dest末尾 | strcat(s1, "!"); | dest需预留足够空间。 |
strcmp(s1, s2) | 比较字符串(相等返回0) | strcmp("apple", "Apple") → 正数 | 区分大小写。 |
strchr(str, ch) | 查找字符首次出现的位置 | strchr("hello", 'l') → 指向第二个'l' | 返回指针,未找到返回NULL。 |
示例:拼接字符串
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2); // str1变为"Hello World"
printf("%s\n", str1);
return 0;
}
7.5 数组作为函数参数
传递规则:
• 数组名作为参数时退化为指针(传递首地址)。
• 需额外传递数组长度(除非以\0
结尾,如字符串)。
示例1:一维数组求和
int sumArray(int arr[], int size) { // 等价于 int *arr
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
int main() {
int nums[] = {1, 2, 3, 4};
printf("Sum: %d\n", sumArray(nums, 4)); // 输出:10
return 0;
}
示例2:修改二维数组元素
void fillMatrix(int mat[][3], int rows) { // 必须指定列数
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
mat[i][j] = i + j;
}
}
}
int main() {
int matrix[2][3];
fillMatrix(matrix, 2); // 修改原数组
return 0;
}
总结
- 数组核心特性:
• 连续内存存储,支持快速随机访问。
• 长度固定(动态数组需手动实现或使用C99变长数组)。
- 字符串本质:以
\0
结尾的字符数组,操作时需始终维护终止符。
- 函数参数传递:数组传递的是地址,函数内修改会影响原始数据。
避坑指南:
• 避免数组越界和缓冲区溢出(如使用 strncpy
替代 strcpy
)。
• 慎用 scanf("%s", buf)
,建议用 fgets(buf, size, stdin)
输入字符串。
• 多维数组作为参数时需明确除第一维外的所有维度大小。