第6篇:数组和列表——存储多个数据
**作者:**中文编程倡导者—— 李金雨
联系方式:wbtm2718@qq.com
**目标读者:**编程入门(零基础)
核心理念:使用华为仓颉原生中文编程,体验真正的国产编程语言
一、开篇引入
1.1 生活中的"列表"
生活中到处都有"列表":
- 📋 班级花名册(50个同学的名字)
- 🛒 购物清单(要买的东西)
- 📱 通讯录(几百个好友)
- 📰 新闻列表(几十条新闻)
1.2 程序中的"列表"
如果让你一个个写出来,那太麻烦了!
笨方法(不要这样做):
let 学生1 = "张三" let 学生2 = "李四" let 学生3 = "王五" // ... 重复50次!聪明方法:
let 学生列表 = ["张三", "李四", "王五", ...] // 一行代码搞定!1.3 关于数组语法的思考
在学习数组之前,我们再聊聊仓颉的语法设计。
仓颉的数组定义是:
let 学生列表: Array<String> = ["张三", "李四", "王五"]这里又出现了类型后置的问题!Array<String>表示"字符串数组",但它放在了变量名后面。
如果仓颉能像C#那样:
// C#风格string[]学生列表={"张三","李四","王五"};或者:
// 设想中的中文风格 字符串数组 学生列表 = ["张三", "李四", "王五"]这样读起来就像是"字符串数组学生列表",而不是"学生列表字符串数组",更符合中国人的定语前置习惯!
不过,仓颉的数组操作语法还是比较简洁的,我们接着学习吧!
1.4 本课目标
今天我们要学习:
- 数组的创建和使用
- 数组的遍历
- 数组的增删改查
- 动态列表(ArrayList)
- 做一个班级管理系统
二、概念讲解
2.1 数组基础
什么是数组?
数组就是相同类型数据的集合,就像一排储物柜,每个格子存一个数据。
创建数组
// 方式1:直接赋值 let 成绩列表: Array<Int64> = [85, 92, 78, 96, 88] // 方式2:空数组 let 空数组: Array<String> = [] // 方式3:指定大小(初始值为默认值) let 固定数组 = Array<Int64>(10, { 0 })再次吐槽类型后置:
Array<Int64>这种写法,意思是"整数数组",但它放在了变量名后面。
我们中国人习惯说"整数数组成绩列表",而不是"成绩列表整数数组"。
这就像:
- 我们习惯说:“红色的苹果”
- 仓颉的写法像是:“苹果红色的”
希望华为能在未来版本中改进!
访问数组元素
let 成绩列表 = [85, 92, 78, 96, 88] // 获取第1个元素(索引从0开始) let 第一个成绩 = 成绩列表[0] // 85 // 获取第2个元素 let 第二个成绩 = 成绩列表[1] // 92 // 获取最后一个元素 let 最后一个成绩 = 成绩列表[成绩列表.size - 1] // 88注意:索引从0开始,不是从1开始!
2.2 数组的遍历
方式1:使用for循环
let 学生列表 = ["张三", "李四", "王五", "赵六"] // 遍历数组 for (i in 0..学生列表.size) { println("第${i + 1}个学生:${学生列表[i]}") }方式2:使用for-in(如果仓颉支持)
for (学生 in 学生列表) { println("学生:${学生}") }2.3 数组的操作
获取数组长度
let 长度 = 成绩列表.size修改元素
成绩列表[0] = 90 // 把第1个成绩改为90添加元素(动态数组)
import std.collection.* main() { let 动态列表 = ArrayList<String>() // 添加元素 动态列表.append("张三") 动态列表.append("李四") 动态列表.append("王五") println("列表内容:${动态列表}") println("列表大小:${动态列表.size}") }删除元素
动态列表.removeAt(0) // 删除第1个元素2.4 常用数组操作
求和、平均值、最大最小值
main() { let 成绩列表 = [85, 92, 78, 96, 88] // 求和 var 总分: Int64 = 0 for (成绩 in 成绩列表) { 总分 = 总分 + 成绩 } // 平均值 let 平均分 = Float64(总分) / Float64(成绩列表.size) // 最大值和最小值 var 最高分 = 成绩列表[0] var 最低分 = 成绩列表[0] for (成绩 in 成绩列表) { if (成绩 > 最高分) { 最高分 = 成绩 } if (成绩 < 最低分) { 最低分 = 成绩 } } println("总分:${总分}") println("平均分:${平均分}") println("最高分:${最高分}") println("最低分:${最低分}") }三、动手实践
3.1 基础练习:班级成绩统计
// 班级成绩统计 main() { println("=== 班级成绩统计 ===") println("") // 学生成绩列表 let 学生成绩 = [ ("张三", 85), ("李四", 92), ("王五", 78), ("赵六", 96), ("孙七", 88) ] println("学生成绩列表:") for ((姓名, 成绩) in 学生成绩) { println("${姓名}:${成绩}分") } println("") // 计算统计信息 var 总分: Int64 = 0 var 最高分: Int64 = 0 var 最低分: Int64 = 100 var 优秀人数: Int64 = 0 var 及格人数: Int64 = 0 for ((姓名, 成绩) in 学生成绩) { 总分 = 总分 + 成绩 if (成绩 > 最高分) { 最高分 = 成绩 } if (成绩 < 最低分) { 最低分 = 成绩 } if (成绩 >= 90) { 优秀人数 = 优秀人数 + 1 } if (成绩 >= 60) { 及格人数 = 及格人数 + 1 } } let 平均分 = Float64(总分) / Float64(学生成绩.size) let 及格率 = Float64(及格人数) / Float64(学生成绩.size) * 100.0 println("【统计结果】") println("总人数:${学生成绩.size}人") println("总分:${总分}分") println("平均分:${平均分}分") println("最高分:${最高分}分") println("最低分:${最低分}分") println("优秀人数:${优秀人数}人") println("及格人数:${及格人数}人") println("及格率:${及格率}%") }3.2 进阶练习:学生信息管理系统
// 学生信息管理系统 import std.collection.* class 学生 { var 姓名: String var 年龄: Int64 var 班级: String var 成绩: Int64 init(姓名: String, 年龄: Int64, 班级: String, 成绩: Int64) { this.姓名 = 姓名 this.年龄 = 年龄 this.班级 = 班级 this.成绩 = 成绩 } func 显示信息() { println("姓名:${姓名},年龄:${年龄},班级:${班级},成绩:${成绩}") } } main() { println("=== 学生信息管理系统 ===") println("") // 创建学生列表 let 学生列表 = ArrayList<学生>() // 添加学生 学生列表.append(学生("张三", 15, "初三(1)", 85)) 学生列表.append(学生("李四", 16, "初三(1)", 92)) 学生列表.append(学生("王五", 15, "初三(1)", 78)) 学生列表.append(学生("赵六", 16, "初三(1)", 96)) // 显示所有学生 println("【所有学生信息】") for (学生 in 学生列表) { 学生.显示信息() } println("") // 查找优秀学生(成绩>=90) println("【优秀学生】") for (学生 in 学生列表) { if (学生.成绩 >= 90) { 学生.显示信息() } } println("") // 计算平均年龄 var 年龄总和: Int64 = 0 for (学生 in 学生列表) { 年龄总和 = 年龄总和 + 学生.年龄 } let 平均年龄 = Float64(年龄总和) / Float64(学生列表.size) println("平均年龄:${平均年龄}岁") }3.3 挑战练习:通讯录管理
// 通讯录管理 import std.collection.* class 联系人 { var 姓名: String var 电话: String var 邮箱: String init(姓名: String, 电话: String, 邮箱: String) { this.姓名 = 姓名 this.电话 = 电话 this.邮箱 = 邮箱 } } main() { println("=== 通讯录 ===") println("") let 通讯录 = ArrayList<联系人>() // 添加联系人 通讯录.append(联系人("张三", "13800138000", "zhangsan@qq.com")) 通讯录.append(联系人("李四", "13900139000", "lisi@qq.com")) 通讯录.append(联系人("王五", "13700137000", "wangwu@qq.com")) // 显示所有联系人 println("【所有联系人】") for ((索引, 联系人) in 通讯录) { println("${索引 + 1}. ${联系人.姓名} - ${联系人.电话}") } println("") println("共${通讯录.size}位联系人") }四、知识总结
4.1 核心概念回顾
- 数组:相同类型数据的集合
- 索引:从0开始访问数组元素
- 遍历:逐个访问数组元素
- 动态列表:可以增删元素的列表
4.2 关于语法设计的总结
仓颉的数组类型声明Array<Int64>又出现了类型后置的问题:
let 成绩列表: Array<Int64> = [85, 92, 78]如果仓颉能改进:
// 设想中的改进 Int64[] 成绩列表 = [85, 92, 78] // 像Java/C# // 或者 整数数组 成绩列表 = [85, 92, 78] // 纯中文希望华为能在未来版本中考虑这种更符合中国人习惯的语法!
4.3 关键代码速查
// 创建数组 let 数组 = [1, 2, 3, 4, 5] // 访问元素 let 元素 = 数组[0] // 获取长度 let 长度 = 数组.size // 遍历数组 for (元素 in 数组) { // 处理元素 } // 动态列表 import std.collection.* let 列表 = ArrayList<String>() 列表.append("元素") 列表.removeAt(0)4.4 常见错误提醒
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
| 索引越界 | 访问了不存在的索引 | 检查索引范围 |
| 类型不匹配 | 数组类型和元素类型不一致 | 确保类型一致 |
| 空数组访问 | 数组为空 | 先检查数组长度 |
五、课后作业
5.1 巩固练习(必做)
练习1:数组排序
对一个整数数组进行排序(冒泡排序或选择排序)。
练习2:查找元素
在一个数组中查找指定元素,返回其索引。
练习3:数组合并
合并两个数组,并去重。
5.2 创意编程(选做)
创意1:待办事项列表
实现增删改查功能。
创意2:简易数据库
用数组实现简单的数据存储和查询。
创意3:抽奖程序
从名单中随机抽取获奖者。
5.3 下篇预习
下一篇,我们将学习功能封装——方法,学习如何封装可复用的代码。
恭喜你完成了第6篇的学习!🎉
现在你已经掌握了数组和列表,可以存储和操作多个数据了!
下节课,我们将学习方法,封装可复用的代码!