内容正文:
山东省计算机类高考技能教学
数组的定义及引用
一、教学目标
【知识目标】
1.掌握阐述一维数组和二维数组的概念,清晰理解数组在内存中的存储方式。
2.掌握一维数组和二维数组的定义、初始化方法。
3.掌握数组元素引用的方法,理解数组下标从 0 开始的意义及使用规则。
【能力目标】
1. 能根据实际需求,在 C 语言程序中正确定义和初始化一维数组、二维数组。
2. 具备通过引用数组元素,实现对数组数据的读取、修改、运算等操作的能力,能够运用数组解决简单的实际编程问题,如数据排序、矩阵运算等。
【素养目标】
1. 培养学生严谨的编程思维和逻辑分析能力,提高学生在编程过程中发现问题、分析问题和解决问题的能力。
2. 增强学生对编程学习的兴趣和自信心,培养学生团队协作和自主探究学习的良好习惯。
二、基本知识讲解
一维数组:
1. 概念定义
一维数组是由相同数据类型的元素组成的线性序列,通过一个下标(索引)访问元素,下标从 0 开始。
语法格式:
1
数据类型 数组名[元素个数];
例:
int scores[5]; // 定义5个整数的数组,未初始化时元素值为随机数
float prices[10]; // 定义10个浮点数的数组
char name[20]; // 定义20个字符的数组(常用于存储字符串)
关键说明:
· 数据类型:可以是int、float、char等任意 C 语言合法类型。
· 数组名:遵循变量命名规则(字母、数字、下划线,不能以数字开头)。
· 元素个数:必须是常量(或常量表达式),不能是变量,且个数≥1。
初始化方法
· 方式 1:完全初始化(指定所有元素值)
int arr[3] = {10, 20, 30}; // 定义3个元素,依次为10、20、30
特点:数组长度由{}内的值个数决定,与[]中的数字必须一致,否则报错。
· 方式 2:部分初始化(只赋前 n 个元素值)
int nums[5] = {1, 2}; // 前2个元素为1、2,后3个自动初始化为0
float values[4] = {3.14}; // 第一个元素为3.14,后三个为0.0
特点:未赋值的元素自动初始化为 0(数值型)
· 方式 3:省略长度初始化(编译器自动计算长度)
int data[] = {5, 6, 7, 8}; // 数组长度为4
注意:省略长度时必须给出初始化值,否则无法确定数组大小。
· 方式 4:动态初始化(通过循环赋值)
int arr[5];
for (int i = 0; i < 5; i++) {
arr[i] = i * 2; // 数组元素为0, 2, 4, 6, 8
}
适用场景:当元素值需通过计算生成时(如等差数列)。
初始化注意事项:
· 数组长度与初始化值数量
若[]中指定长度,{}内的值个数不能超过长度,否则编译错误。
int arr[3] = {1, 2, 3, 4}; // 错误:值个数(4)超过长度(3)
核心特点:
所有元素类型相同,占用内存大小一致;
元素在内存中连续存储,可通过下标快速访问。
2. 内存存储方式(以 int 数组为例)
假设定义int arr[3] = {10, 20, 30};,内存存储如下:
内存地址(假设从 1000 开始)
存储内容
下标
1000
10
0
1004
20
1
1008
30
2
关键说明
· 连续存储:每个 int 元素占 4 字节,相邻元素地址差 4 字节(地址 = 首地址 + 下标 × 元素字节数)。
· 下标计算:元素arr[i]的内存地址 = 数组首地址 + i × 4。
· 逻辑与物理:一维数组在逻辑上是 “线性排列”,物理上严格连续存储,符合数组 “随机访问” 的特性。
代码示例(C 语言):
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
printf("arr[0]地址:%p,值:%d
", &arr[0], arr[0]);
printf("arr[1]地址:%p,值:%d
", &arr[1], arr[1]);
printf("arr[2]地址:%p,值:%d
", &arr[2], arr[2]);
return 0;
}
输出(假设首地址为 0x7fff):
arr[0]地址:0x7fff,值:10
arr[1]地址:0x7fff+4,值:20
arr[2]地址:0x7fff+8,值:30
一维数组元素引用
语法:数组名[下标]
示例:
int arr[5] = {10, 20, 30, 40, 50};
printf("%d
", arr[0]); // 输出第1个元素:10
arr[2] = 300; // 修改第3个元素的值为300
二维数组:
二维数组:逻辑上的 “矩阵” 结构
1. 概念定义
二维数组可视为 “数组的数组”,通过两个下标(行和列)访问元素,本质上仍是线性存储结构。
语法格式:
数据类型 数组名[行数][列数];
例:
int matrix[2][3]; // 2行3列的整型数组,共6个元素
float table[3][5]; // 3行5列的浮点型数组
char grid[4][4]; // 4行4列的字符型数组
关键说明:
· 行数和列数:均为常量(或常量表达式),例如int matrix[2][3]表示 2 行 3 列的数组。
· 本质:二维数组是 “数组的数组”,如matrix[2][3]可视为包含 2 个一维数组,每个一维数组有 3 个元素。
初始化方法:
· 方式 1:按行完全初始化(用嵌套花括号)
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
/* 等价于:
arr[0][0]=1, arr[0][1]=2, arr[0][2]=3
arr[1][0]=4, arr[1][1]=5, arr[1][2]=6
*/
特点:每一行的元素用{}括起来,清晰表示行与列的关系。
· 方式 2:按行部分初始化
int arr[2][3] = {{1}, {4, 5}};
/* 初始化结果:
arr[0][0]=1, arr[0][1]=0, arr[0][2]=0
arr[1][0]=4, arr[1][1]=5, arr[1][2]=0
*/
规则:未赋值的元素自动补 0,每行内未赋值的元素也补 0。
· 方式 3:省略行数初始化(必须保留列数)
int arr[][3] = {{1, 2, 3}, {4, 5, 6}}; // 行数由初始化的行数决定(2行)
注意:
必须保留列数[3],行数由{}内的行数决定。
不能同时省略行数和列数,如int arr[][]是错误的。
· 方式 4:不按行初始化(按线性顺序赋值)
int arr[2][3] = {1, 2, 3, 4, 5, 6}; // 与按行初始化效果相同
/* 赋值顺序:
arr[0][0]=1, arr[0][1]=2, arr[0][2]=3
arr[1][0]=4, arr[1][1]=5, arr[1][2]=6
*/
适用场景:当二维数组逻辑上接近一维时(如矩阵转一维),但可读性较差,建议优先按行初始化。
· 方式 5:动态初始化(通过双重循环赋值)
int matrix[3][4];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
matrix[i][j] = i * 4 + j; // 生成0-11的序列
}
}
应用场景:生成有规律的矩阵(如单位矩阵、等差数列矩阵)。
初始化注意事项
· 行列数与初始化值数量:
按行初始化时,每行的元素个数不能超过列数,否则报错。
int arr[2][3] = {{1, 2, 3, 4}, {5, 6}}; // 错误:第一行元素个数(4)超过列数(3)
· 省略行数的限制:
必须通过初始化值的行数确定数组行数,且列数必须明确指定。
int arr[][3] = {{1}, {2}}; // 正确:行数为2,列数为3
int arr[][] = {{1,2}, {3,4}}; // 错误:未指定列数
逻辑理解:
二维数组常被用于表示矩阵、表格等二维结构,如:
matrix[0][0] matrix[0][1] matrix[0][2]
matrix[1][0] matrix[1][1] matrix[1][2]
内存存储方式(行优先原则)
以int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}}为例,内存存储如下:
内存地址(假设从 2000 开始)
存储内容
逻辑位置
2000
1
[0][0]
2004
2
[0][1]
2008
3
[0][2]
2012
4
[1][0]
2016
5
[1][1]
2020
6
[1][2]
关键说明
· 行优先(Row-major Order):C 语言中二维数组按行存储,先存第一行所有元素,再存第二行,依此类推。
· 地址计算:元素matrix[i][j]的地址 = 首地址 + (i× 列数 + j) × 元素字节数。
例:matrix[1][1]的地址 = 2000 + (1×3 + 1)×4 = 2016。
· 本质线性:二维数组在内存中仍是一维连续空间,“二维” 是通过下标计算逻辑实现的抽象。
示例代码:
#include <stdio.h>
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 打印所有元素的地址和值
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("matrix[%d][%d]地址:%p,值:%d
",
i, j, &matrix[i][j], matrix[i][j]);
}
}
return 0;
}
输出(部分示例,假设首地址为 0x2000):
matrix[0][0]地址:0x2000,值:1
matrix[0][1]地址:0x2004,值:2
matrix[1][0]地址:0x2012,值:4 // 注意:第一行存完才存第二行
二维数组元素引用
语法:数组名[行下标][列下标]
示例:
int matrix[2][3] = {{1,2,3}, {4,5,6}};
printf("%d
", matrix[0][1]); // 输出第1行第2列元素:2
matrix[1][2] = 60; // 修改第2行第3列元素为60
一维数组与二维数组的对比:
维度
一维数组
二维数组
逻辑结构
线性序列(一排抽屉)
矩阵结构(行列表格)
下标数量
1 个(如 arr [5])
2 个(如 matrix [2][3])
内存存储
严格连续线性存储
按行优先原则线性存储
地址计算
首地址 + 下标 × 字节数
首地址 + (行 × 列数 + 列)× 字节数
典型应用
存储单列数据(如成绩列表)
存储矩阵、表格数据
· 一维数组:像一排按顺序编号的邮箱,每个邮箱大小相同,通过编号(下标)直接找到对应邮箱。
· 二维数组:像一栋两层的公寓楼,每层有 3 个房间,用 “楼层号 + 房间号”(行下标 + 列下标)定位房间,但整栋楼在地面上是线性排列的(行优先存储)。
三、例题讲解
例题 1:一维数组元素逆序
题目描述:输入一个包含 5 个整数的一维数组,将数组元素逆序后输出。
输入示例:1 2 3 4 5
输出示例:5 4 3 2 1
#include <stdio.h>
int main() {
int arr[5];
// 输入数组元素
for (int i = 0; i < 5; i++) {
scanf("%d", &arr[i]);
}
// 逆序处理:交换首尾元素
for (int i = 0; i < 2; i++) { // 只需遍历到中间位置
int temp = arr[i];
arr[i] = arr[4 - i];
arr[4 - i] = temp;
}
// 输出逆序后的数组
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
例题 2:二维数组行列求和
题目描述:输入一个 3 行 4 列的二维数组,分别计算每行和每列的元素和并输出。
输入示例:
1 2 3 4
5 6 7 8
9 10 11 12
输出示例:
行和:10 26 42
列和:15 18 21 24
#include <stdio.h>
int main() {
int arr[3][4];
// 输入二维数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
scanf("%d", &arr[i][j]);
}
}
// 计算并输出每行的和
printf("行和:");
for (int i = 0; i < 3; i++) {
int row_sum = 0;
for (int j = 0; j < 4; j++) {
row_sum += arr[i][j];
}
printf("%d ", row_sum);
}
printf("
");
// 计算并输出每列的和
printf("列和:");
for (int j = 0; j < 4; j++) {
int col_sum = 0;
for (int i = 0; i < 3; i++) {
col_sum += arr[i][j];
}
printf("%d ", col_sum);
}
return 0;
}
例题3:杨辉三角(二维数组应用)
题目描述:输入一个正整数 n(n≤10),输出 n 行的杨辉三角。
输入示例:5
输出示例:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int triangle[10][10] = {0}; // 初始化为0
// 构建杨辉三角
for (int i = 0; i < n; i++) {
triangle[i][0] = 1; // 每行第一个元素为1
triangle[i][i] = 1; // 对角线元素为1
// 计算内部元素
for (int j = 1; j < i; j++) {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
}
// 输出杨辉三角
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
printf("%d ", triangle[i][j]);
}
printf("
");
}
return 0;
}
四、课堂小结
· 一维数组
定义:类型 数组名[长度](长度为常量)
初始化:int a[3]={1,2,3} 或部分赋值
引用:a[0](下标从 0 开始,范围 0~ 长度 - 1)
· 二维数组
定义:类型 数组名[行][列]
初始化:int a[2][3]={{1,2},{3,4}}(按行赋值)
引用:a[1][0](行列下标均从 0 开始)
· 核心规则
下标从 0 开始,对应内存偏移量
严禁越界访问(下标≥长度)
二维数组按行优先存储(先存第一行)
原创精品资源学科网独家享有版权,侵权必究!
学科网(北京)股份有限公司
$$