第五章 数组
第一节 一维数组
概述
本节内容主要介绍C语言中的一维数组,包括一维数组的定义、初始化、访问及其在程序设计中的应用。通过学习本节,考生将掌握如何正确使用一维数组存储和处理多个相同类型的数据,理解数组在内存中的存储方式,并能够运用一维数组解决实际编程问题。
核心概念
数组(Array):数组是一种数据结构,用于存储一组类型相同的数据元素,元素在内存中连续存储。数组使得程序能够通过索引访问这些数据。
一维数组(One-dimensional Array):一维数组是线性排列的元素集合,可以看作是元素的一条直线排列,元素通过单一的下标索引访问。
下标(Index):下标是用于访问数组中元素的位置标识,C语言中数组下标从0开始。
数组名:数组名代表数组首元素的地址,不能被赋值。
初始化(Initialization):为数组元素赋予初始值的过程。
原理分析
一维数组在内存中是连续分配的一块空间,每个元素占用相同大小的存储单元。访问数组元素时,计算公式为:
元素地址 = 数组首地址 + (下标 × 元素大小)
这保证了数组访问的高效性。由于数组名代表首地址,数组元素可以通过指针运算实现访问。
C语言数组的下标从0开始,意味着第一个元素的下标是0,最后一个元素的下标是数组长度减1。
详细内容
1. 一维数组的定义和声明
在C语言中,定义一维数组的基本格式为:
类型名 数组名[元素个数];
- 类型名:数组中元素的数据类型,如int、float、char等。
- 数组名:标识数组的变量名。
- 元素个数:数组中元素的数量,必须是常量表达式。
示例:
int scores[5];
这条语句定义了一个包含5个整型元素的一维数组scores。
2. 一维数组的初始化
数组在定义时可以初始化,常见的初始化方式有:
int a[5] = {1, 2, 3, 4, 5};
int b[5] = {0}; // 所有元素初始化为0
int c[] = {1, 2, 3}; // 元素个数由初始化列表决定
注意:
- 初始化列表中元素个数不能超过数组长度。
- 如果初始化列表元素少于数组长度,剩余元素默认初始化为0。
3. 访问数组元素
数组元素通过下标访问,下标范围为0到数组长度-1。
访问格式:
数组名[下标]
示例:
int x = scores[2]; // 访问第三个元素
scores[4] = 100; // 修改第五个元素的值
4. 数组与指针的关系
数组名代表数组首元素的地址,因此可以用指针访问数组元素。
int *p = scores;
int val = *(p + 3); // 访问第四个元素
这说明数组和指针之间存在紧密联系,但它们并不完全相同,数组名不能作为左值赋值。
5. 遍历数组
遍历数组常用for循环:
for (int i = 0; i < 5; i++) {
printf("%d ", scores[i]);
}
该循环依次访问并打印数组所有元素。
6. 数组作为函数参数
数组名作为参数传递给函数时,实际传递的是指向数组首元素的指针。
函数定义示例:
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
}
调用时传入数组名和元素个数:
printArray(scores, 5);
注意,函数内部无法获取数组长度,必须显式传递。
实例分析
实例1:求一组整数的平均值
背景:统计学生的成绩,求平均分。
#include <stdio.h>
int main() {
int scores[5] = {85, 90, 78, 92, 88};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += scores[i];
}
double average = sum / 5.0;
printf("平均分:%.2f\n", average);
return 0;
}
分析:利用一维数组存储成绩,循环累加求和,计算平均值。
结论:一维数组方便存储多个数据,实现批量处理。
实例2:数组元素逆序输出
背景:输入5个整数,逆序打印。
#include <stdio.h>
int main() {
int arr[5];
printf("请输入5个整数:\n");
for (int i = 0; i < 5; i++) {
scanf("%d", &arr[i]);
}
printf("逆序输出:\n");
for (int i = 4; i >= 0; i--) {
printf("%d ", arr[i]);
}
return 0;
}
分析:先顺序输入数组元素,再逆序遍历输出。
结论:数组支持任意顺序访问元素。
实例3:判断数组中是否存在某元素
背景:判断数组中是否包含指定数字。
#include <stdio.h>
int contains(int arr[], int size, int key) {
for (int i = 0; i < size; i++) {
if (arr[i] == key) {
return 1; // 找到
}
}
return 0; // 未找到
}
int main() {
int data[6] = {3, 5, 7, 9, 11, 15};
int target = 7;
if (contains(data, 6, target)) {
printf("数组包含%d\n", target);
} else {
printf("数组不包含%d\n", target);
}
return 0;
}
分析:通过遍历数组检查元素是否存在。
结论:数组适合实现简单的查找操作。
常见误区
误区1:数组下标越界访问
- 错误:访问数组下标小于0或大于等于数组大小。
- 正确:确保访问下标在[0, 数组长度-1]范围内。
误区2:数组未初始化导致访问垃圾值
- 错误:定义数组后不初始化,直接使用。
- 正确:定义时初始化或使用前赋值。
误区3:数组名赋值操作
- 错误:尝试给数组名赋值,如
arr = anotherArr;。 - 正确:数组名不可作为左值,需逐元素复制。
- 错误:尝试给数组名赋值,如
误区4:误解数组大小
- 错误:在函数中使用
sizeof(arr)得到数组大小。 - 正确:函数中数组退化为指针,需显式传递数组大小。
- 错误:在函数中使用
误区5:初始化元素不够导致未定义行为
- 错误:未全部初始化,期待所有元素自动有意义的值。
- 正确:不足元素自动初始化为0,仅限于静态或全局数组,局部未初始化为0。
应用场景
数据批量存储与处理:如保存考试成绩、传感器数据等。
实现简单的线性表结构:支持顺序存取。
作为函数传递参数,处理多组数据。
实现基本算法如排序、查找等的基础数据结构。
缓存临时数据,方便循环操作和批量计算。
知识拓展
多维数组:二维及多维数组用于表示矩阵、表格等复杂数据结构。
动态数组:通过指针和动态内存分配实现可变长度数组。
数组与指针深度理解:理解数组名、指针变量和指针运算的区别。
字符串数组:字符数组用于处理字符串。
数组与结构体结合:存储复杂数据类型的集合。
总结回顾
本节详细介绍了C语言一维数组的定义、初始化、访问及其内存原理,强调数组下标从0开始,展示了数组与指针的紧密联系。一维数组是存储和处理多个同类型数据的基础结构,广泛应用于数据处理和算法实现。
通过实例演示了数组的基本操作,包括求平均值、逆序输出和元素查找。还指出了常见错误及正确用法,避免数组越界和未初始化等问题。
理解一维数组是学习C语言数据结构的基础,为后续学习多维数组和动态数组打下坚实基础。
关键知识点
- 数组定义及元素个数必须为常量表达式
- 数组下标从0开始,访问范围严格限制
- 数组初始化方法及默认初始化规则
- 数组名表示首元素地址,数组与指针的关系
- 数组遍历、访问及修改元素的正确方式
- 数组作为函数参数传递时的特点
- 常见数组使用误区及避免方法
- 一维数组在实际程序中的典型应用
- 数组内存连续分配的原理和计算方法
- 数组与其他数据结构的关系与拓展