第五章 数组 - 第一节 数组的基本概念与应用
概述
数组是C语言中最基本且最重要的数据结构之一,在程序设计中广泛应用。本节内容主要介绍数组的定义、声明、初始化及基本操作。通过学习本节内容,考生将掌握如何使用数组存储和管理多个同类型数据,理解数组在程序中的作用和特点,为后续复杂数据结构的学习打下坚实基础。
学习目标:
- 理解数组的概念和作用
- 掌握数组的声明与初始化方法
- 掌握数组元素的访问和常见操作
- 能够编写基本的数组应用程序
核心概念
1. 数组的定义
数组是由相同类型的数据元素按照一定顺序排列组成的集合。在C语言中,数组是一块连续的内存空间,用来存储多个同类型的数据。
2. 数组元素和下标
数组中的每个数据称为元素,元素的位置由下标(索引)表示,下标从0开始递增。
3. 数组的类型与长度
数组的类型由元素类型决定,长度指数组中元素的个数,数组长度必须是整型常量表达式。
4. 一维数组与多维数组
一维数组是线性排列的数据集合,多维数组是数组元素本身也是数组,形成二维或多维结构。
原理分析
1. 内存布局
数组在内存中占用一块连续的空间,数组名代表数组首元素的地址。数组元素通过下标偏移访问,地址计算公式为:
地址 = 数组首地址 + (下标 × 元素大小)
连续内存的特点使得数组访问效率高,适合快速随机访问。
2. 数组与指针的关系
数组名在表达式中通常转换为指向首元素的指针,指针算术运算可以实现数组元素访问,但数组名本身不可修改。
3. 越界访问的风险
访问数组时若下标越界,程序行为未定义,可能导致数据错误或程序崩溃。
详细内容
1. 数组的声明
声明数组需要指定元素类型和数组长度,格式如下:
类型名 数组名[长度];
示例:
int scores[5]; // 声明一个包含5个整数元素的数组
注意:长度必须为整型常量,且长度一旦定义不可更改。
2. 数组的初始化
数组可以在声明时进行初始化,初始化方式有多种:
- 完全初始化:为每个元素指定初值
int a[3] = {1, 2, 3};
- 部分初始化:未指定的元素自动初始化为0
int a[5] = {1, 2}; // 等价于{1, 2, 0, 0, 0}
- 不指定长度初始化:根据初始值自动确定长度
int a[] = {1, 2, 3, 4}; // 数组长度为4
3. 访问数组元素
通过数组名和下标访问元素,下标从0开始。例如:
int val = a[2]; // 访问第三个元素
可以对元素进行赋值或读取。
4. 数组元素的遍历
使用循环结构遍历数组,常用for循环:
for (int i = 0; i < 5; i++) {
printf("%d\n", a[i]);
}
5. 数组与函数
数组作为参数传递时,实际传递的是指向数组首元素的指针。函数内无法获知数组长度,需额外传入长度信息。
示例:
void printArray(int arr[], int len) {
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
}
6. 多维数组基础
二维数组的声明和访问示例:
int matrix[3][4]; // 3行4列二维数组
matrix[1][2] = 10; // 访问第2行第3列元素
实例分析
实例一:统计学生成绩的平均分
背景:有5个学生的成绩,求平均分。
代码示例:
#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 avg = sum / 5.0;
printf("平均分是:%.2f\n", avg);
return 0;
}
分析:
- 使用数组存储多个成绩
- 通过循环遍历求和
- 计算平均值,体现数组的实用性
结论:数组能方便地存储和处理多个数据,提高程序结构清晰度。
实例二:查找数组中的最大值
背景:给定一组整数,找出最大元素。
代码示例:
#include <stdio.h>
int main() {
int nums[6] = {23, 45, 12, 67, 34, 89};
int max = nums[0];
for (int i = 1; i < 6; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
printf("最大值是:%d\n", max);
return 0;
}
分析:
- 利用数组访问元素
- 循环比较更新最大值
结论:数组遍历结合条件判断,实现数据筛选功能。
实例三:数组元素逆序输出
背景:输入一组数,逆序输出。
代码示例:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
printf("逆序输出:\n");
for (int i = 4; i >= 0; i--) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
分析:
- 逆序遍历数组
结论:数组元素访问灵活,可实现多种操作。
常见误区
- 数组下标越界访问
- 错误:访问下标小于0或大于等于数组长度的元素
- 正确:确保下标范围在0到数组长度-1
- 数组长度未初始化或使用变量定义长度
- 错误:数组长度非整型常量表达式
- 正确:使用常量或宏定义数组长度
- 数组名赋值错误
- 错误:尝试将数组名赋值给另一个数组
- 正确:数组名不可作为左值,需逐元素赋值或使用指针
- 数组初始化不完整导致垃圾值
- 错误:部分元素未初始化且未全部置零
- 正确:未初始化元素自动置零或显式初始化
- 忽视数组作为函数参数的指针性质
- 错误:以为函数内能获知数组长度
- 正确:函数需额外传入数组长度
应用场景
- 存储和处理多组数据:如成绩、温度、库存数量等
- 实现线性数据结构:如队列、栈的底层存储
- 批量数据计算:统计、排序、查找等算法的基础
- 图像、矩阵处理:二维数组模拟图形像素或数学矩阵
- 字符串处理基础:字符数组用于存储字符串
知识拓展
- 多维数组深入:二维、三维数组及其内存布局
- 指针与数组的关系:指针运算、数组指针、函数指针传递
- 动态数组:使用指针和动态内存分配实现可变长度数组
- 结构体数组:存储复杂数据类型集合
- 数组与字符串:字符数组与字符串操作函数
总结回顾
本节重点讲解了数组的基本定义、声明、初始化及访问方法。数组是一种连续存储的同类型数据集合,支持通过下标随机访问元素。理解数组的内存布局和指针关系,有助于避免越界访问等常见错误。掌握数组的遍历、初始化和作为函数参数传递的用法,为后续学习多维数组、动态数组和复杂数据结构奠定基础。
通过实例演练,考生能够熟练编写使用数组的程序,解决实际问题。掌握这些基础内容,是全国计算机等级考试二级C语言程序设计部分的重要内容。
参考文献
- 《C程序设计语言》第2版,Brian W. Kernighan、Dennis M. Ritchie
- 《C语言入门经典》,谭浩强