一、数组是什么?为什么需要数组?
想象一下你需要存储100个学生的成绩。如果没有数组,你需要声明100个变量:score1, score2, score3, … score100。这显然非常麻烦!数组就是为了解决这类问题而设计的。
数组是一组相同类型数据的集合,这些数据在内存中连续存储,可以通过索引(下标)快速访问。
二、数组基础知识
1. 数组的声明和初始化
基本语法:
数据类型 数组名[元素个数];
示例:
#include <stdio.h>
int main() {
// 方法一:声明后逐个赋值
int scores[5];
scores[0] = 90;
scores[1] = 85;
scores[2] = 78;
scores[3] = 92;
scores[4] = 88;
// 方法二:声明时初始化
int numbers[5] = {1, 2, 3, 4, 5};
// 方法三:自动计算数组大小
int primes[] = {2, 3, 5, 7, 11, 13}; // 编译器自动计算为6个元素
return 0;
}
2. 数组的特点
- 类型一致:数组中所有元素的数据类型相同
- 内存连续:数组元素在内存中连续存储
- 固定大小:数组一旦声明,大小就固定了
- 下标访问:通过下标(从0开始)访问元素
3. 访问数组元素
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
// 访问单个元素
printf("第一个元素: %d\n", arr[0]); // 10
printf("第三个元素: %d\n", arr[2]); // 30
// 修改元素值
arr[1] = 25;
printf("修改后的第二个元素: %d\n", arr[1]); // 25
// 遍历数组
printf("所有元素: ");
for(int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
三、多维数组
当数组的元素也是数组时,就形成了多维数组。最常见的是二维数组,可以理解为表格或矩阵。
1. 二维数组的声明和初始化
#include <stdio.h>
int main() {
// 声明并初始化二维数组
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 访问二维数组元素
printf("matrix[1][2] = %d\n", matrix[1][2]); // 6
// 遍历二维数组
printf("矩阵内容:\n");
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
2. 二维数组的内存布局
二维数组在内存中仍然是一维连续存储的,只是逻辑上分为行和列。
matrix[0][0] → matrix[0][1] → matrix[0][2] →
matrix[1][0] → matrix[1][1] → matrix[1][2] →
matrix[2][0] → matrix[2][1] → matrix[2][2]
四、字符数组与字符串
字符数组是元素为char类型的数组,常用于存储字符串。
1. 字符数组的基本使用
#include <stdio.h>
#include <string.h> // 字符串操作函数头文件
int main() {
// 方法一:逐个字符初始化
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 方法二:字符串字面量初始化
char str2[6] = "Hello";
// 方法三:自动计算大小
char str3[] = "Hello World!";
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
printf("str3: %s\n", str3);
printf("str3长度: %lu\n", strlen(str3));
return 0;
}
2. 字符串输入输出
#include <stdio.h>
int main() {
char name[50];
printf("请输入你的名字: ");
scanf("%49s", name); // 限制输入长度,防止缓冲区溢出
printf("你好, %s!\n", name);
return 0;
}
五、数组进阶知识
1. 数组名的真正含义
在C语言中,数组名在不同上下文中有不同含义:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
// 情况1:代表整个数组
printf("数组大小: %zu bytes\n", sizeof(arr)); // 20 bytes (5 * 4)
// 情况2:代表首元素地址
printf("首元素地址: %p\n", (void*)arr);
printf("首元素值: %d\n", *arr); // 1
// 数组名和指针的关系
printf("arr[2] = %d\n", arr[2]); // 3
printf("*(arr+2) = %d\n", *(arr+2)); // 3
printf("2[arr] = %d\n", 2[arr]); // 3 (不推荐,但语法正确)
return 0;
}
2. 数组与指针的关系
数组下标操作实际上是指针运算的语法糖:
arr[i] 等价于 *(arr + i)
示例:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // 指向数组首元素
// 通过指针访问数组元素
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d, *(ptr+%d) = %d\n",
i, arr[i], i, *(ptr+i));
}
return 0;
}
六、特殊类型的数组
1. 零长度数组
零长度数组主要用于结构体的可变长度成员:
#include <stdio.h>
#include <stdlib.h>
struct dynamic_array {
int length;
int data[0]; // 零长度数组
};
int main() {
int size = 5;
// 分配内存,包含结构体本身和数组元素
struct dynamic_array *da = malloc(sizeof(struct dynamic_array) + size * sizeof(int));
da->length = size;
// 使用数组成员
for(int i = 0; i < size; i++) {
da->data[i] = i * 10;
}
// 打印数组内容
for(int i = 0; i < da->length; i++) {
printf("data[%d] = %d\n", i, da->data[i]);
}
free(da);
return 0;
}
2. 变长数组(C99标准)
#include <stdio.h>
int main() {
int size;
printf("请输入数组大小: ");
scanf("%d", &size);
// 变长数组(C99特性)
int vla[size];
// 初始化数组
for(int i = 0; i < size; i++) {
vla[i] = (i + 1) * 10;
}
// 打印数组
printf("数组内容: ");
for(int i = 0; i < size; i++) {
printf("%d ", vla[i]);
}
printf("\n");
return 0;
}
七、数组的常见错误与注意事项
1. 数组越界访问
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
// 错误:越界访问
printf("arr[5] = %d\n", arr[5]); // 未定义行为,可能崩溃或输出随机值
return 0;
}
2. 数组初始化问题
#include <stdio.h>
int main() {
// 部分初始化,未初始化的元素自动设为0
int arr[5] = {1, 2, 3};
printf("arr[3] = %d, arr[4] = %d\n", arr[3], arr[4]); // 0, 0
return 0;
}
3. 数组大小计算
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 计算数组元素个数
int size = sizeof(arr) / sizeof(arr[0]);
printf("数组元素个数: %d\n", size); // 10
return 0;
}
八、实战应用
1. 查找数组中的最大值和最小值
#include <stdio.h>
int main() {
int numbers[] = {23, 45, 12, 67, 89, 34, 56};
int size = sizeof(numbers) / sizeof(numbers[0]);
int max = numbers[0];
int min = numbers[0];
for(int i = 1; i < size; i++) {
if(numbers[i] > max) {
max = numbers[i];
}
if(numbers[i] < min) {
min = numbers[i];
}
}
printf("最大值: %d\n", max);
printf("最小值: %d\n", min);
return 0;
}
九、总结与建议
数组是C语言中最基本也是最重要的数据结构之一。通过本文的学习,你应该已经掌握了:
- 数组的基本概念和声明方法
- 一维数组和多维数组的使用
- 字符数组与字符串的处理
- 数组与指针的关系
- 特殊类型数组的应用
- 数组的常见操作和算法
学习建议:
- 多练习数组的基本操作,如遍历、查找、排序
- 理解数组与指针的关系,这是C语言的核心概念
- 注意数组越界问题,这是最常见的错误之一
- 尝试用数组解决实际问题,如学生成绩管理、数据统计等
1128

被折叠的 条评论
为什么被折叠?



