数组是相同类型数据的有序集合,可用于批量存储、管理同类型数据,比如用 int
类型数组存班级学生成绩,用 char
类型数组存字符串 。
语法:类型 数组名[常量表达式];
,如:
// 存 5 个 int 型数据,元素默认随机值
int arr1[5];
// 存 10 个 char 型数据
char arr2[10];
#define
定义的符号常量或字面常量(如5
、10
),C99 支持变长数组(后续讲),但旧编译器可能不支持。// 明确元素值,依次为 1、2、3、4、5
int arr1[5] = {1, 2, 3, 4, 5};
// 只给前 2 个赋值,剩余元素默认 0
int arr2[5] = {1, 2};
int arr[5];
// 从键盘给数组赋值
for (int i = 0; i < 5; i++) {
scanf("%d", &arr[i]);
}
0 ~ 数组长度 - 1
,通过 数组名[下标]
访问元素,如:int arr[5] = {1, 2, 3, 4, 5};
// 访问第 3 个元素(值为 3 )
printf("%d\n", arr[2]);
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
// 依次打印 1 2 3 4 5
printf("%d ", arr[i]);
}
scanf
赋值:int arr[3];
for (int i = 0; i < 3; i++) {
// 输入 3 个数存到数组
scanf("%d", &arr[i]);
}
sizeof
应用数组元素在内存连续存放,地址随下标增大而增大,且每个元素占字节数由类型决定(如 int
占 4 字节 )。代码验证:
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
// 打印元素地址,差值为 4(int 占 4 字节)
printf("&arr[%d] = %p\n", i, &arr[i]);
}
sizeof
计算元素个数公式:元素个数 = sizeof(数组名) / sizeof(数组元素类型)
,示例:
int arr[5] = {1, 2, 3, 4, 5};
// 总字节数 / 单个 int 字节数 → 5
int count = sizeof(arr) / sizeof(int);
printf("元素个数:%d\n", count);
sizeof(数组名)
会退化为计算指针大小(通常 4/8 字节,取决于系统)。二维数组可看作数组的数组,用于存储表格类数据(如行表示学生,列表示科目成绩 )。
创建语法:类型 数组名[行常量表达式][列常量表达式];
,如:
// 3 行 4 列,存 int 型数据
int arr[3][4];
0
,如:// 第一行:1、2、3、0;第二行:4、5、0、0;第三行:0、0、0、0
int arr[3][4] = {{1, 2, 3}, {4, 5}};
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 自动算 2 行(6 个元素 ÷ 3 列 )
int arr[][3] = {{1, 2, 3}, {4, 5, 6}};
数组名[行下标][列下标]
访问,行、列下标均从 0
开始,如:int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 访问第二行第三列元素(值为 6 )
printf("%d\n", arr[1][2]);
int arr[2][3];
// 输入
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
scanf("%d", &arr[i][j]);
}
}
// 输出
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
二维数组在内存连续存储,按行优先方式排布,即先存第一行元素,再存第二行…… 可通过打印地址验证:
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
// 地址连续,差值为 4(int 占 4 字节)
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
C99 支持创建时用变量指定数组长度(运行时确定大小 ),如:
int n;
scanf("%d", &n);
// 变长数组,长度由 n 决定
int arr[n];
需求:在有序(升序)数组中,用二分法找目标值,找到返回下标,否则返回 -1 。
代码:
#include
int binarySearch(int arr[], int size, int target) {
int left = 0;
int right = size - 1;
while (left <= right) {
// 防止溢出,等价 (left + right)/2
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
// 目标在右半段
left = mid + 1;
} else {
// 目标在左半段
right = mid - 1;
}
}
return -1;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int target = 7;
int index = binarySearch(arr, sizeof(arr)/sizeof(int), target);
if (index != -1) {
printf("找到,下标:%d\n", index);
} else {
printf("未找到\n");
}
return 0;
}
关键逻辑:
mid
分割区间,缩小查找范围;left
和 right
边界,确保覆盖所有可能下标。需求:将字符串内容从两端向中间逐步替换到另一个字符串,动态展示过程(类似动画效果 )。
代码:
#include
#include
#include // 用于 Sleep 和 system 函数
int main() {
char arr1[] = "welcome to bit!!!!!!";
char arr2[] = "******************";
int left = 0;
int right = strlen(arr1) - 1;
while (left <= right) {
arr2[left] = arr1[left];
arr2[right] = arr1[right];
// 打印当前 arr2 状态
printf("%s\n", arr2);
// 暂停 100 毫秒,营造动态效果
Sleep(100);
// 清理屏幕,下次输出覆盖
system("cls");
left++;
right--;
}
// 最后再打印一次最终结果(避免被清屏)
printf("%s\n", arr2);
return 0;
}
动态效果实现:
Sleep(100)
控制每次更新间隔,让变化肉眼可见;system("cls")
清屏,使每次输出位置固定,模拟动画;system("cls")
在 Windows 环境生效,Linux/Mac 需替换为 system("clear")
。知识点 | 核心要点 | 易错点/注意事项 |
---|---|---|
数组创建 | 类型 + 数组名 + 常量表达式(C99 支持变长数组 ) | 变长数组不能初始化,旧编译器可能不支持 |
数组初始化 | 静态、动态初始化,可不完全赋值(剩余默认 0 ) | 字符数组初始化字符串时,注意 '\0' 自动添加(如 char str[] = "abc" 实际存 'a' 'b' 'c' '\0' ) |
数组下标 | 从 0 开始,范围 0 ~ 长度-1 |
下标越界无编译报错,但会引发运行时未定义行为(如修改未知内存 ) |
sizeof 计算 |
可算数组总字节数、元素个数;数组传参后失效 | 函数传数组本质传地址,sizeof(数组名) 结果是指针大小(4/8 字节 ) |
二维数组操作 | 行优先存储,支持省略行数初始化;通过双下标访问 | 初始化时列数必须明确,否则无法确定元素布局;嵌套循环处理输入输出时,注意行列边界 |
二分查找 | 依赖有序数组,通过缩小范围查找;需处理边界和 mid 计算 |
数组无序时不能用;left <= right 条件不能漏,否则漏判元素;mid 计算用 left + (right-left)/2 防溢出 |
动态字符串效果 | 结合 Sleep 和清屏函数,实现可视化过程 |
清屏函数(cls /clear )依赖操作系统,跨平台需适配;注意最终结果打印避免被清屏覆盖 |
通过对数组基础语法、内存布局、实战练习的梳理,相信你已掌握数组核心用法。多结合实际场景(如数据统计、算法实现 )练习,就能更灵活地运用数组解决问题啦~ 后续可拓展学习数组排序(冒泡、选择等 )、多维数组复杂操作等内容 。