news 2026/3/23 21:12:14

CSP-J教程——第一阶段第九、十课:数组与字符串

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CSP-J教程——第一阶段第九、十课:数组与字符串

课程目标

  • 理解数组的概念和用途
  • 掌握一维数组的定义、初始化和访问
  • 学会数组遍历和经典应用
  • 掌握字符串的基本操作
  • 理解批量数据处理的思想
  • 为后续算法学习打下基础

第一部分:数组的概念(40分钟)

1.1 什么是数组?

生活比喻:

  • 储物柜:一排编号的储物格,每个格子可以放东西
  • 学生座位表:按学号排列的座位,每个位置坐一个学生
  • 火车车厢:连续的车厢,每节车厢有编号和乘客

1.2 为什么需要数组?

没有数组的困境:

// 要存储5个学生的成绩intscore1,score2,score3,score4,score5;cin>>score1>>score2>>score3>>score4>>score5;// 要计算平均分doubleaverage=(score1+score2+score3+score4+score5)/5.0;// 如果要处理100个学生呢?需要100个变量!

使用数组的便利:

// 使用数组存储5个学生的成绩intscores[5];for(inti=0;i<5;i++){cin>>scores[i];}// 计算平均分intsum=0;for(inti=0;i<5;i++){sum+=scores[i];}doubleaverage=sum/5.0;

1.3 数组的特点

  1. 相同类型:数组中所有元素的数据类型相同
  2. 连续存储:元素在内存中连续存放
  3. 固定大小:数组一旦创建,大小不能改变
  4. 索引访问:通过下标(索引)访问元素

第二部分:一维数组的基本操作(60分钟)

2.1 数组的定义和初始化

定义数组:

数据类型 数组名[数组大小];

示例:

#include<iostream>usingnamespacestd;intmain(){// 定义数组的不同方式intnumbers1[5];// 定义包含5个整数的数组(未初始化)intnumbers2[5]={1,2,3,4,5};// 定义并初始化intnumbers3[]={1,2,3,4,5};// 自动推断大小为5intnumbers4[5]={1,2};// 前两个元素初始化,其余为0// 访问数组元素numbers1[0]=10;// 给第一个元素赋值cout<<numbers2[2]<<endl;// 输出第三个元素:3return0;}

2.2 数组的访问和遍历

数组索引:

  • 索引从0开始,不是从1开始!
  • 有效索引范围:0 到 数组大小-1
  • 访问越界是常见错误
#include<iostream>usingnamespacestd;intmain(){intscores[5]={85,92,78,96,88};// 逐个访问cout<<"第一个学生成绩: "<<scores[0]<<endl;cout<<"第三个学生成绩: "<<scores[2]<<endl;// 使用循环遍历数组cout<<"所有成绩: ";for(inti=0;i<5;i++){cout<<scores[i]<<" ";}cout<<endl;// 修改数组元素scores[1]=95;// 修改第二个学生的成绩cout<<"修改后的第二个成绩: "<<scores[1]<<endl;return0;}

2.3 数组大小和边界检查

#include<iostream>usingnamespacestd;intmain(){constintSIZE=5;// 使用常量定义数组大小intnumbers[SIZE]={10,20,30,40,50};// 正确遍历cout<<"正确遍历: ";for(inti=0;i<SIZE;i++){cout<<numbers[i]<<" ";}cout<<endl;// 错误:访问越界(危险!)// cout << numbers[5] << endl; // 索引5不存在!// cout << numbers[-1] << endl; // 索引-1不存在!// 使用sizeof计算数组大小intbyteSize=sizeof(numbers);// 整个数组的字节数intelementSize=sizeof(numbers[0]);// 每个元素的字节数intelementCount=byteSize/elementSize;// 元素个数cout<<"数组总字节数: "<<byteSize<<endl;cout<<"每个元素字节数: "<<elementSize<<endl;cout<<"元素个数: "<<elementCount<<endl;return0;}

第三部分:数组的经典应用(80分钟)

3.1 求最大值和最小值

#include<iostream>usingnamespacestd;intmain(){constintSIZE=7;inttemperatures[SIZE]={25,28,30,22,26,29,27};// 找最高温度intmaxTemp=temperatures[0];// 假设第一个是最大值for(inti=1;i<SIZE;i++){if(temperatures[i]>maxTemp){maxTemp=temperatures[i];}}// 找最低温度intminTemp=temperatures[0];// 假设第一个是最小值for(inti=1;i<SIZE;i++){if(temperatures[i]<minTemp){minTemp=temperatures[i];}}cout<<"一周温度: ";for(inti=0;i<SIZE;i++){cout<<temperatures[i]<<"°C ";}cout<<endl;cout<<"最高温度: "<<maxTemp<<"°C"<<endl;cout<<"最低温度: "<<minTemp<<"°C"<<endl;return0;}

3.2 求和与平均值

#include<iostream>usingnamespacestd;intmain(){constintSIZE=5;doubleexpenses[SIZE]={45.5,28.0,63.2,19.8,52.1};// 计算总支出doubletotal=0;for(inti=0;i<SIZE;i++){total+=expenses[i];}// 计算平均支出doubleaverage=total/SIZE;// 找出高于平均值的支出cout<<"所有支出: ";for(inti=0;i<SIZE;i++){cout<<expenses[i]<<"元 ";}cout<<endl;cout<<"总支出: "<<total<<"元"<<endl;cout<<"平均支出: "<<average<<"元"<<endl;cout<<"高于平均值的支出: ";for(inti=0;i<SIZE;i++){if(expenses[i]>average){cout<<expenses[i]<<"元 ";}}cout<<endl;return0;}

3.3 计数和统计

#include<iostream>usingnamespacestd;intmain(){constintSIZE=10;intscores[SIZE]={85,92,78,45,96,88,62,75,91,53};intexcellent=0;// 优秀(90-100)intgood=0;// 良好(80-89)intpass=0;// 及格(60-79)intfail=0;// 不及格(0-59)// 统计各个等级的人数for(inti=0;i<SIZE;i++){if(scores[i]>=90){excellent++;}elseif(scores[i]>=80){good++;}elseif(scores[i]>=60){pass++;}else{fail++;}}cout<<"成绩统计结果:"<<endl;cout<<"优秀(90-100): "<<excellent<<"人"<<endl;cout<<"良好(80-89): "<<good<<"人"<<endl;cout<<"及格(60-79): "<<pass<<"人"<<endl;cout<<"不及格(0-59): "<<fail<<"人"<<endl;// 计算百分比cout<<"优秀率: "<<(excellent*100.0/SIZE)<<"%"<<endl;cout<<"及格率: "<<((excellent+good+pass)*100.0/SIZE)<<"%"<<endl;return0;}

3.4 数组排序(选择排序)

#include<iostream>usingnamespacestd;intmain(){constintSIZE=6;intnumbers[SIZE]={64,25,12,22,11,5};cout<<"排序前: ";for(inti=0;i<SIZE;i++){cout<<numbers[i]<<" ";}cout<<endl;// 选择排序算法for(inti=0;i<SIZE-1;i++){// 找到从i到末尾的最小元素的索引intminIndex=i;for(intj=i+1;j<SIZE;j++){if(numbers[j]<numbers[minIndex]){minIndex=j;}}// 交换当前元素和最小元素inttemp=numbers[i];numbers[i]=numbers[minIndex];numbers[minIndex]=temp;// 显示每一轮排序的结果cout<<"第"<<i+1<<"轮: ";for(intk=0;k<SIZE;k++){cout<<numbers[k]<<" ";}cout<<endl;}cout<<"排序后: ";for(inti=0;i<SIZE;i++){cout<<numbers[i]<<" ";}cout<<endl;return0;}

3.5 数组搜索

#include<iostream>usingnamespacestd;intmain(){constintSIZE=8;intnumbers[SIZE]={23,45,67,12,89,34,56,78};inttarget;cout<<"数组内容: ";for(inti=0;i<SIZE;i++){cout<<numbers[i]<<" ";}cout<<endl;cout<<"请输入要查找的数字: ";cin>>target;// 线性搜索boolfound=false;intposition=-1;for(inti=0;i<SIZE;i++){if(numbers[i]==target){found=true;position=i;break;// 找到后立即退出循环}}if(found){cout<<"找到了!数字 "<<target<<" 在数组中的位置是: "<<position<<endl;}else{cout<<"没有找到数字 "<<target<<endl;}return0;}

第四部分:字符串基础(60分钟)

4.1 什么是字符串?

字符串的概念:

  • 字符串是字符的序列
  • 在C++中,字符串可以用字符数组或string类表示
  • 字符串以空字符\0结尾

4.2 字符数组表示字符串

#include<iostream>usingnamespacestd;intmain(){// 方式1:字符数组(C风格字符串)charstr1[6]={'H','e','l','l','o','\0'};charstr2[]="Hello";// 自动添加\0charname[20];cout<<"str1: "<<str1<<endl;cout<<"str2: "<<str2<<endl;// 输入字符串cout<<"请输入你的名字: ";cin>>name;cout<<"你好, "<<name<<"!"<<endl;// 遍历字符数组cout<<"字符串字符: ";for(inti=0;str2[i]!='\0';i++){cout<<str2[i]<<" ";}cout<<endl;return0;}

4.3 string类的基本使用

#include<iostream>#include<string>// 必须包含string头文件usingnamespacestd;intmain(){// string类的定义和初始化string str1="Hello";stringstr2("World");string str3;// 字符串赋值str3="C++";// 字符串连接string greeting=str1+" "+str2+"!";cout<<greeting<<endl;// 字符串输入string name;cout<<"请输入你的全名: ";cin>>name;// 遇到空格停止cout<<"你好, "<<name<<"!"<<endl;// 使用getline读取整行cin.ignore();// 清除之前的换行符cout<<"请重新输入你的全名: ";getline(cin,name);cout<<"你好, "<<name<<"!"<<endl;return0;}

4.4 字符串常用操作

#include<iostream>#include<string>usingnamespacestd;intmain(){string text="Hello C++ Programming";// 字符串长度cout<<"字符串: "<<text<<endl;cout<<"长度: "<<text.length()<<endl;// 访问单个字符cout<<"第一个字符: "<<text[0]<<endl;cout<<"最后一个字符: "<<text[text.length()-1]<<endl;// 字符串比较string str1="apple";string str2="banana";if(str1==str2){cout<<str1<<" 等于 "<<str2<<endl;}elseif(str1<str2){cout<<str1<<" 在 "<<str2<<" 前面"<<endl;}else{cout<<str1<<" 在 "<<str2<<" 后面"<<endl;}// 子字符串string substring=text.substr(6,3);// 从位置6开始,取3个字符cout<<"子字符串: "<<substring<<endl;// 查找子字符串intposition=text.find("C++");if(position!=string::npos){cout<<"找到 'C++' 在位置: "<<position<<endl;}else{cout<<"没有找到 'C++'"<<endl;}return0;}

第五部分:字符串应用示例(60分钟)

5.1 字符串统计

#include<iostream>#include<string>usingnamespacestd;intmain(){string text;cout<<"请输入一段文本: ";getline(cin,text);intletterCount=0,digitCount=0,spaceCount=0,otherCount=0;// 统计各种字符的个数for(inti=0;i<text.length();i++){charch=text[i];if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){letterCount++;}elseif(ch>='0'&&ch<='9'){digitCount++;}elseif(ch==' '){spaceCount++;}else{otherCount++;}}cout<<"\n=== 字符统计结果 ==="<<endl;cout<<"总字符数: "<<text.length()<<endl;cout<<"字母个数: "<<letterCount<<endl;cout<<"数字个数: "<<digitCount<<endl;cout<<"空格个数: "<<spaceCount<<endl;cout<<"其他字符: "<<otherCount<<endl;return0;}

5.2 字符串反转

#include<iostream>#include<string>usingnamespacestd;intmain(){string str;cout<<"请输入一个字符串: ";getline(cin,str);cout<<"原始字符串: "<<str<<endl;// 方法1:创建新字符串string reversed1;for(inti=str.length()-1;i>=0;i--){reversed1+=str[i];}cout<<"反转字符串(方法1): "<<reversed1<<endl;// 方法2:原地反转string reversed2=str;// 复制原字符串intleft=0,right=reversed2.length()-1;while(left<right){// 交换左右字符chartemp=reversed2[left];reversed2[left]=reversed2[right];reversed2[right]=temp;left++;right--;}cout<<"反转字符串(方法2): "<<reversed2<<endl;return0;}

5.3 回文判断

#include<iostream>#include<string>#include<cctype>// 用于tolower函数usingnamespacestd;intmain(){string str;cout<<"请输入一个字符串: ";getline(cin,str);// 预处理:转换为小写,移除非字母数字字符string processed;for(charch:str){if(isalnum(ch)){// 如果是字母或数字processed+=tolower(ch);}}// 判断是否是回文boolisPalindrome=true;intleft=0,right=processed.length()-1;while(left<right){if(processed[left]!=processed[right]){isPalindrome=false;break;}left++;right--;}cout<<"\""<<str<<"\" ";if(isPalindrome){cout<<"是回文!"<<endl;}else{cout<<"不是回文。"<<endl;}return0;}

5.4 简单加密解密

#include<iostream>#include<string>usingnamespacestd;intmain(){string text;intkey;cout<<"请输入要加密的文本: ";getline(cin,text);cout<<"请输入加密密钥(1-25): ";cin>>key;// 加密string encrypted=text;for(inti=0;i<encrypted.length();i++){charch=encrypted[i];if(isalpha(ch)){charbase=islower(ch)?'a':'A';encrypted[i]=(ch-base+key)%26+base;}}cout<<"加密结果: "<<encrypted<<endl;// 解密string decrypted=encrypted;for(inti=0;i<decrypted.length();i++){charch=decrypted[i];if(isalpha(ch)){charbase=islower(ch)?'a':'A';decrypted[i]=(ch-base-key+26)%26+base;}}cout<<"解密结果: "<<decrypted<<endl;return0;}

第六部分:综合应用项目(60分钟)

6.1 学生成绩管理系统

#include<iostream>#include<string>#include<iomanip>usingnamespacestd;constintMAX_STUDENTS=50;intmain(){string names[MAX_STUDENTS];intscores[MAX_STUDENTS];intstudentCount=0;intchoice;do{// 显示菜单cout<<"\n=== 学生成绩管理系统 ==="<<endl;cout<<"1. 添加学生成绩"<<endl;cout<<"2. 显示所有成绩"<<endl;cout<<"3. 查找学生成绩"<<endl;cout<<"4. 统计成绩分析"<<endl;cout<<"5. 成绩排序"<<endl;cout<<"0. 退出系统"<<endl;cout<<"请选择操作: ";cin>>choice;switch(choice){case1:{// 添加学生成绩if(studentCount>=MAX_STUDENTS){cout<<"学生数量已满!"<<endl;break;}cout<<"请输入学生姓名: ";cin>>names[studentCount];cout<<"请输入"<<names[studentCount]<<"的成绩: ";cin>>scores[studentCount];studentCount++;cout<<"添加成功!"<<endl;break;}case2:{// 显示所有成绩if(studentCount==0){cout<<"还没有学生数据!"<<endl;break;}cout<<"\n=== 所有学生成绩 ==="<<endl;cout<<left<<setw(15)<<"姓名"<<setw(10)<<"成绩"<<"等级"<<endl;cout<<string(35,'-')<<endl;for(inti=0;i<studentCount;i++){string grade;if(scores[i]>=90)grade="优秀";elseif(scores[i]>=80)grade="良好";elseif(scores[i]>=70)grade="中等";elseif(scores[i]>=60)grade="及格";elsegrade="不及格";cout<<left<<setw(15)<<names[i]<<setw(10)<<scores[i]<<grade<<endl;}break;}case3:{// 查找学生成绩if(studentCount==0){cout<<"还没有学生数据!"<<endl;break;}string searchName;cout<<"请输入要查找的学生姓名: ";cin>>searchName;boolfound=false;for(inti=0;i<studentCount;i++){if(names[i]==searchName){cout<<"找到学生: "<<names[i]<<endl;cout<<"成绩: "<<scores[i]<<endl;found=true;break;}}if(!found){cout<<"没有找到学生: "<<searchName<<endl;}break;}case4:{// 统计成绩分析if(studentCount==0){cout<<"还没有学生数据!"<<endl;break;}intsum=0,maxScore=scores[0],minScore=scores[0];intexcellent=0,good=0,medium=0,pass=0,fail=0;for(inti=0;i<studentCount;i++){sum+=scores[i];if(scores[i]>maxScore)maxScore=scores[i];if(scores[i]<minScore)minScore=scores[i];if(scores[i]>=90)excellent++;elseif(scores[i]>=80)good++;elseif(scores[i]>=70)medium++;elseif(scores[i]>=60)pass++;elsefail++;}doubleaverage=static_cast<double>(sum)/studentCount;cout<<"\n=== 成绩统计分析 ==="<<endl;cout<<"学生总数: "<<studentCount<<endl;cout<<"平均分: "<<fixed<<setprecision(2)<<average<<endl;cout<<"最高分: "<<maxScore<<endl;cout<<"最低分: "<<minScore<<endl;cout<<"优秀(90-100): "<<excellent<<"人 ("<<(excellent*100.0/studentCount)<<"%)"<<endl;cout<<"良好(80-89): "<<good<<"人 ("<<(good*100.0/studentCount)<<"%)"<<endl;cout<<"中等(70-79): "<<medium<<"人 ("<<(medium*100.0/studentCount)<<"%)"<<endl;cout<<"及格(60-69): "<<pass<<"人 ("<<(pass*100.0/studentCount)<<"%)"<<endl;cout<<"不及格(0-59): "<<fail<<"人 ("<<(fail*100.0/studentCount)<<"%)"<<endl;break;}case5:{// 成绩排序(按成绩降序)if(studentCount==0){cout<<"还没有学生数据!"<<endl;break;}// 使用选择排序按成绩降序排列for(inti=0;i<studentCount-1;i++){intmaxIndex=i;for(intj=i+1;j<studentCount;j++){if(scores[j]>scores[maxIndex]){maxIndex=j;}}// 交换成绩inttempScore=scores[i];scores[i]=scores[maxIndex];scores[maxIndex]=tempScore;// 交换姓名string tempName=names[i];names[i]=names[maxIndex];names[maxIndex]=tempName;}cout<<"成绩排序完成!"<<endl;break;}case0:cout<<"感谢使用学生成绩管理系统!"<<endl;break;default:cout<<"无效选择,请重新输入!"<<endl;}}while(choice!=0);return0;}

练习与作业

基础练习(必做)

练习1:数组基础操作
创建一个包含10个整数的数组,完成以下操作:

  1. 从键盘输入10个数字
  2. 计算数组元素的总和和平均值
  3. 找出最大值和最小值及其位置
  4. 将数组元素逆序存放

练习2:字符串处理
编写程序处理字符串:

  1. 输入一个字符串,统计其中元音字母的个数
  2. 将字符串中的所有空格替换为下划线
  3. 判断字符串是否包含数字
  4. 将字符串中的大写字母转换为小写

练习3:成绩分析
使用数组存储一个班级的成绩(最多50人):

  1. 输入成绩(输入-1结束)
  2. 计算平均分、最高分、最低分
  3. 统计各分数段人数
  4. 按成绩从高到低排序

挑战练习(选做)

挑战1:矩阵运算
实现3×3矩阵的基本运算:

  • 矩阵加法
  • 矩阵乘法
  • 矩阵转置
  • 求矩阵对角线元素和

挑战2:字符串压缩
实现简单的字符串压缩算法:

  • 将连续重复的字符压缩为"字符+次数"
  • 例如:“aaabbc"压缩为"a3b2c1”
  • 实现解压缩功能

挑战3:简单投票系统
模拟选举投票系统:

  • 存储候选人姓名和得票数
  • 实现投票功能
  • 统计投票结果
  • 找出获胜者

实验任务

任务1:数组边界测试
测试数组越界访问的后果:

intarr[5]={1,2,3,4,5};// 尝试访问arr[5], arr[6], arr[-1]等// 观察程序行为并记录结果

任务2:字符串内存测试
测试不同字符串初始化方式的内存使用:

charstr1[]="Hello";charstr2[10]="Hello";string str3="Hello";// 使用sizeof测试各字符串的大小

任务3:排序算法比较
实现冒泡排序和选择排序,比较:

  • 代码复杂度
  • 执行效率
  • 交换次数

学习总结

今天学到了:

  • 数组概念:相同类型元素的集合
  • 数组操作:定义、初始化、访问、遍历
  • 数组应用:求最值、求和、计数、排序
  • 字符串基础:字符数组和string类
  • 字符串操作:长度、连接、比较、查找
  • 批量处理:使用循环处理数组和字符串

关键技能:

  • 数组设计:合理选择数组大小和数据类型
  • 循环遍历:使用循环处理数组元素
  • 算法思维:实现排序、搜索等基本算法
  • 字符串处理:文本数据的各种操作

下一课预告:

下一节课我们将学习函数与递归初步,包括函数的定义、调用、参数传递,让代码更加模块化和可复用!


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/19 16:00:39

基于C#的FTP客户端实现方案

基于C#的FTP客户端实现方案&#xff0c;整合了多种协议特性和工程优化&#xff0c;支持文件传输、目录操作及异常处理&#xff1a;一、核心类实现&#xff08;支持被动模式/二进制传输&#xff09; using System; using System.IO; using System.Net; using System.Net.Sockets…

作者头像 李华
网站建设 2026/3/22 20:12:29

深入理解 C# 中 new 关键字的三重核心语义

在 C# 编程中&#xff0c;new 是一个几乎每天都会用到的关键字&#xff0c;但它的职责并不单一。根据使用场景的不同&#xff0c;new 在语言层面承担着 三种完全不同的语义角色&#xff1a; 1. 作为运算符&#xff1a; 创建对象或结构体实例 2. 作为修饰符&#xff1a; 隐藏基类…

作者头像 李华
网站建设 2026/3/19 13:38:42

Android防撤回终极指南:免Root永久告别消息撤回烦恼

还在为错过重要消息而懊恼吗&#xff1f;当同事撤回工作安排、朋友撤回关键信息时&#xff0c;你是否感到无比困扰&#xff1f;Anti-recall防撤回工具正是为解决这一痛点而生&#xff0c;让你从此不再错过任何被撤回的内容。作为一款免Root的Android防撤回工具&#xff0c;它能…

作者头像 李华
网站建设 2026/3/21 0:29:46

告别低效详情:A+页面重构亚马逊转化逻辑

在亚马逊平台上&#xff0c;A页面正在成为品牌差异化竞争的核心战场&#xff0c;这一工具已从简单的图文展示&#xff0c;演变为集智能创作、交互体验与数据优化于一体的品牌中枢系统&#xff0c;每一次功能升级&#xff0c;都标志着电商沟通从“信息告知”向“价值感知”的深度…

作者头像 李华
网站建设 2026/3/21 6:19:12

汇编语言全接触-30.Win32调试API三

在本章中&#xff0c;我们将继续探讨win32调试api。特别地&#xff0c;我们将学习如何去跟踪被调试程序.下载 例子. 理论:如果你以前使用过调试器&#xff0c;那么你应对跟踪比较熟悉。当"跟踪"一个程序时&#xff0c;程序在每执行一条指令后将会停止&#xff0c;这使…

作者头像 李华
网站建设 2026/3/20 4:42:33

LobeChat做市场调研分析可行吗?真实案例验证

LobeChat做市场调研分析可行吗&#xff1f;真实案例验证 在企业越来越依赖数据驱动决策的今天&#xff0c;市场调研早已不再是“发问卷、看报表”的简单流程。面对社交媒体评论、竞品发布会纪要、行业白皮书等海量非结构化文本&#xff0c;传统人工分析方式不仅耗时费力&#x…

作者头像 李华