C/C++ 第六讲 二维数组、字符数组
6.1 二维数组的定义和初始化
定义
1 | 变量名 数组名[常量表达式1][常量表达式2]; |
- 表达式1代表行,表达式2代表列;元素个数为行、列长度的乘积。
- 行、列下标均由0始。
- 二维数组按行存放(一行存满再下一行)
序号=当前行号*每行列数+当前列号
(二维数组作参数时可用)
存储
1 | float a[2][3]; |
若系统分配的首地址为1000,则:
a[0][0]:1000; a[0][1]:1004; a[0][2]:1008
a[1][0]:100C; a[1][1]:1010; a[1][2]:1014
初始化
- 按存放顺序对所有元素赋初值。
1 | int a[2][3]={1,2,3,4,5,6}; |
- 全部元素初始化能省略且只能省略第一维长度。(三维、四维etc)
- 按行给元素赋初值,每行元素组织在一对花括号内。
1 | int a[2][3]={{1,2,3},{4,5,6}} |
- 按行给部分元素赋初值,未赋值元素自动为0.
1 | int a[3][4]={{1,2,3},{0,1,3},{2,6,4}} |
- 按行赋初值也可省略第一维长度:
1 | int a[][3]={{1},{},{3}} |
1 |
|
基本操作
- 对于数值型数组,程序中只能使用其元素。
数组名 [行下标][列下标]
- 输入、输出、批量处理时需使用双循环,外循环控制行变化,内循环控制列变化。例如:
1 | for(i=0;i<2;i++) |
例
- 求3*3方阵的最大元素集下标
1 | max=a[0][0]; |
6.2 二维数组应用–矩阵转置、杨辉三角
矩阵转置
注意:
- 方阵转置就是以主对角线对称;
- 一次对调
a[i][j]
和a[j][i]
两个元素,故只能以下三角/上三角元素做参照,去和上三角/下三角元素对调。
1 | for(i=0;i<3;i++) |
杨辉三角
输出n(n<10)行的杨辉三角形
1 | //第一列和主对角线 |
完整程序:
1 |
|
二维数组应用–最短路径
A, B, C, D四个城市相互之间有8条单向公路,编程求任意两个城市间的最短距离。
数据存储:4行4列二维数组
e[4][4]
数据表示:
- 与自己的距离为0,不连通城市间距离为∞;
- 行下标代表起点,列下标代表终点,元素值代表距离。
数据处理:弗洛伊德算法求
算法核心:对每一对I和j,检查是否存在顶点k,使得i–>k–>j的距离比原有路径短。如存在,则更新原有路径。
以A作中转点为例:
1 | for(i=0;ie[i][0]+e[0][j]) |
Floyd算法:
1 | for(k=0;k<N;k++) |
完整代码
1 |
|
输入有问题,暂不知为何
6.3 字符数组
例:如何将任意长度的英文句子中的所有小写字母转换成大写字母?
实际操作将整个句子以字符串形式处理
字符串概念
- 双引号引起的一串字符,如
"ab123"
- 若有定义char s[20],通过特殊的初始化、输入、处理、输出可用来处理可变的字符串。
特点:
系统自动在有效字符末尾加'\0'
(字符串结束符)
初始化
- 用字符串为字符数组初始化
1 | char s[10]={"I am fine"}; |
- 字符串数组初始化
1 | char a[3][8]={"COBOL","FORTRAN","PASCAL"}; |
输入输出
char s[100]
1 | //字符串的整体输入 |
例:
1 |
|
cin()
不能提取空格符.
1 |
|
附:
在VS2015中,stdio.h头文件中已经不存在gets()
函数定义,而被更安全的get_s()
函数和fgets()
函数所替代。故直接用gets()会出现未定义的错误。
cin
以三大分隔符分隔gets()
以回车键为分隔
字符串处理原则
- 整体输入、整体输出
- 不用数组长度控制循环,而是通过当前字符**是否达到
'\0'
**判断循环结束与否 - 构造字符串时需保证结尾有
'\0'
例:如何将任意长度的英文句子中的所有小写字母转换成大写字母?
1 |
|
6.4 字符数组的应用:字符串处理
例1 **重要
例:将字符串s的内容复制到字符串t中
- 数组名是地址常量,不能被复制
- 逐元素复制
1 | int i; |
注意:
字符数组需要逐个元素处理
例2
例:逐个比较两个字符串对应位置的字符大小,输出“两字符完全相等”的提示或第一个不相等字符的ASCII码差。
关键:
- 找出持续比较的条件:
- 对应位置的字符相等且串还未结束。
- 退出循环后的再判断:如何退出的?
1 |
|
常用字符串处理函数
strlen(str)
求字符串str的长度,不包含’\0’在内。
strlwr
将str中的大写字母转换为小写字母。
strupr(str)
将str中的小写字母转换为大写字母。
strcpy(str1,str2)
将str2所指的字符串复制到str1中。
str1只能是字符数组名字或字符指针代表的字符串;
str2可以是字符数组名字、字符指针变量、字符串常量。
strcat(str1,str2)–>strcat_s()
将字符串str2的内容连接到str1内容的后面。
strcmp(str1,str2)
比较字符串str1和str2的大小。
从左至右逐字符比较ASCII码的大小,直到出现不相同字符或遇到'\0'
为止。
str1 小于 str2 返回-1
str1 等于 str2 返回0
str1 大于 str2 返回1
例:strcmp("ABCD", "BD")
:
B大于A,∴返回-1
说明
- 上述函数原型在中
- 除strcpy和strcat两个函数的第一个参数不能取字符串常量外,其他参数都可以为字符数组、字符指针变量或字符串常量。
例:字符串处理函数示例
1 |
|
数组应用-古诗接龙程序分析
程序功能及要求
- 可通过菜单选择五言诗和七言诗并进行连句测试
- 机器给出诗的上句,要求用户给出下句。正确提示“答对了,你真棒!”,答错提示“很遗憾,继续努力!”
- 若五言诗或七言诗库中的诗句全都测试完毕,则做出相应提示。
数据结构
二位字符数组(N:已定义过的符号常量)或字符指针数组。
char s5[N][30]
//存放N个五言诗的上下句(实21)
char s7[N][30]
//存放N个七言诗的上下句(实29)
获取数据
可在字符数组初始化时将诗的上下句存放在一个字符数组中
改进:读文件的方式将诗句读入字符数组
程序流程
- 菜单选择:五言、七言、退出;
- 随机产生一个五言诗或七言诗库中现有诗句个数内的不重复随机数;
- 以该随机数为下标取出相应字符串的前半段显示,后半段复制到一个代表答案的字符串中;(上下句在一个字符串里)
- 从键盘输入用户的接龙字符串并比较,根据结果做相应提示
- 重复直到退出
代码组织
目前:所有代码组织在一个主函数中;
改进:模块化管理,将代码组织在多个自定义函数中
程序功能完善
- 下接上
- 加入分数系统
- 记录打错诗句,今后重点训练