1、第5章 数组,C+程序设计,Logo,本章主要内容,1,2,3,4,5,5.2 一维数组的定义和引用,5.3 二维数组的定义和引用,5.4 用数组名作函数参数,5.5 字符数组,*5.6 C+处理字符串的方法,字符串类与字符串变量,6,5.1数组的概念,Logo,5.1 数组的概念,数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。数组必须包含两个要素:数组名和下标。 数组名和下标惟一地标识一个数组中的一个元素,如a1、a2 等。 一个数组在内存中占一片连续的存储单元。,short int a10; 假设数组的起始地址为2000,则该数组在内存中的存储情况如图所
2、示。,cout a+i endl; 输出数组第i个元素ai的地址。,要输出数组第i个元素的值,必须用ai:cout ai endl;,数组名a为数组的起始地址:cout a endl; 输出数组a的起始地址。,有关数组的输出问题,Logo,5.2 一维数组的定义和引用,5.2.1 定义一维数组,定义一维数组:类型标识符 数组名常量表达式; 例如 int a10; /名为a的整型数组,有10个元素。,10表示a数组有10个元素,下标从0开始,这10个元素分别是: a0,a1,a2,a3,a4,a5,a6,a7, a8,a9。,注意:最后一个元素是a9,而不是a10。,Logo,5.2 一维数组的
3、定义和引用,2.常量表达式常量表达式可以包括常量、常变量和符号常量,但不能包含变量。C+不允许动态定义数组的大小。,下列数组定义是否正确:,Logo,5.2 一维数组的定义和引用,5.2.2 引用一维数组的元素,数组必须先定义,后使用。 只能逐个引用数组元素,不能一次引用整个数组中的全部元素。如:a=1 , 2 , 3 数组元素的表示形式: 数组名下标 下标可以是整型常量/变量或整型表达式。,Logo,例5.1 将数组元素的值逆序输出。,#include using namespace std; int main( ) int i , a10;for ( i = 0 ; i ai;for (
4、i = 9 ; i = 0 ; i-)cout ai “ “;cout endl;return 0; ,Logo,5.2.3 一维数组的初始化,(1)在定义数组时给数组元素全部赋予初值。 例如:int a10 = 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9; (2) 可以只给部分元素赋初值。例如int a10 = 0 , 1 , 2 , 3 , 4;,(3) 如果想使一个数组中全部元素值为1,可以写成int a10 = 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1; 不能写成: int a10 = 1*10; 或 int a10 =
5、 1;不能用一个值给数组所有元素赋初值。,Logo,5.2.3 一维数组的初始化,(4) 在对全部数组元素赋初值时,可以不指定数组长度。例如int a5 = 0 , 1 , 2 , 3 , 4 ; 可写成: int a = 0 , 1 , 2 , 3 , 4 ;,注意:若定义的数组长度与初值个数不相符, 则不能省略数组长度。,Logo,例题:5.2 一维数组程序举例,有一对兔子从出生后第3个月起每个月都生一对兔子。小兔子到第3个月又生一对兔子。假设所有兔子都不死,求第20个月的兔子对数。,求Fibonacci数列问题,用数组处理:,#include using namespace std; i
6、nt main( ) int i;int f20= 1 , 1;for ( i = 2 ; i 20 ; i+ )fi = fi-2+ fi-1 ;cout f19endl;return 0; ,不用数组处理:,#include using namespace std; int main( ) int i , num;int f1 , f2;f1 = f2 = 1;for ( i = 3 ; i = 20 ; i+ )num = f1 + f2;f1 = f2;f2 = num;cout num endl;return 0; ,用递归处理:,#include using namespace s
7、td; int main( ) int fib(int n);cout fib(20) endl;return 0; int fib(int n) int num;if(n=1 | n=2) num = 1;else num = fib(n-1) + fib(n-2);return num; ,Logo,5.3 二维数组的定义和引用,有些数据要依赖于两个因素才能惟一地确定,例如有3个学生,每个学生有4门课的成绩。 可用二维数组表示: int stu_score34; 其中s23表示第3个学生第4门课的成绩。,Logo,5.3.1 定义二维数组,定义二维数组的一般形式: 类型标识符 数组名常量表
8、达式常量表达式 例如:float a34 ; 定义a为34(3行4列)的单精度数组,共12个元素。 注意: float a3,4;,Logo,5.3.1 定义二维数组,二维数组中元素存放的顺序是:按行存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素。例如:int a34;数组存放的顺序。,Logo,5.3.1 定义二维数组,a为二维数组的首地址; a0,a1,a2分别为第0、1、2行元素的首地址。,Logo,5.3.2 二维数组的引用,二维数组元素的表示形式为:数组名下标下标 使用数组元素时,应该注意下标值不要越界。 int a34; /定义3行4列的数组a34=15; /引用a34
9、元素,错误 定义a为34的数组,它可用的行下标值最大为2,列坐标值最大为3。最多可以用到a23,a34就超过了数组的范围。,Logo,5.3.3 二维数组的初始化,初始化方法: (1)分行给二维数组赋初值。如: int a34=1 ,2 ,3 ,4,5 ,6 ,7 ,8, 9 ,10 ,11 ,12;第1个花括号内的数据赋给第0行的元素,第2个花括号内的数据赋给第1行的元素即按行赋初值。,Logo,5.3.3 二维数组的初始化,初始化方法: (2) 将所有数据写在一个花括号内,按数组排列的顺序对各元素赋初值。如: int a34=1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
10、9 , 10 , 11 , 12;用第2种方法如果数据多,写成一大片,容易遗漏,也不易检查。,Logo,5.3.3 二维数组的初始化,初始化方法: (3) 对部分元素赋初值。如: int a34=1 , 0 , 5 , 0 , 0 , 9; 它的作用是只对各行某些列的元素赋初值,其余元素值自动置为0。赋初值后数组各元素为:1 0 0 00 5 0 00 0 9 0,对非0元素少时比较方便,Logo,5.3.3 二维数组的初始化,初始化方法: (4) 如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。如 int a 4=1 , 2 , 3 , 4 , 5 , 6
11、 , 7 , 8 , 9 , 10 , 11 , 12;,表示定义了34的数组a,行数=总个数/ 列数。,Logo,5.3.3 二维数组的初始化,注意: 如果定义时只对部分元素赋初值而省略第一维的长度,则必须分行赋初值。如: int a 4=1 , 0,5 , 0 , 0,9; /数组共有3行。,Logo,5.3.4 二维数组程序举例,例5.5 有一个34的矩阵,要求编程序求出所有元素的最大值,以及其所在的行号和列号。要求用函数处理。 编程思想:按照行和列逐个比较元素,#include using namespace std; int main( ) int i,j,row=0,colum=0
12、,max;int a34=5,12,23,56,19,28,37,46,-12,-34,6,8;max=a00; for (i=0;imax) max=aij; row=i; colum=j; coutmax=max,row=row,colum=columendl;return 0; ,Logo,5.4 用数组名作函数参数,1. 用数组元素作函数实参 用数组元素作函数实参与用变量作实参一样,将数组元素的值传送给形参变量。形参是变量,而不是数组。,int add(int x,int y) x=2*x;y=2*y;return x+y; int main( ) int a2=3,4;int sum
13、;sum=add( a0,a1 );coutsum endl;couta0endl;couta1endl;return 0; ,Logo,5.4 用数组名作函数参数,2. 用数组名作函数参数 用数组名作函数参数,此时实参与形参都用数组名。实参与形参的数组为同一个数组。,Logo,5.4 用数组名作函数参数,例5.7 用选择法对数组中10个整数按由小到大排序。 所谓选择法:就是先将10个数中最小的数与a0对换;再将a1到a9中最小的数与a1对换每比较一轮,找出一个未经排序的数中最小的一个。共比较9轮。,int main( ) void select_sort( int array ,int n)
14、; int a10,i;coutai;coutendl;select_sort(a,10); /函数调用,数组名作实参coutthe sorted array:endl;for(i=0;i10;i+) /输出10个已排好序的数coutai ;coutendl;return 0; ,void select_sort(int array,int n) /形参array是数组名 int i,j,k,t;for(i=0;in-1;i+) k=i;for(j=i+1;jn;j+) if(arrayjarrayk) k=j;t=arrayk;arrayk=arrayi;arrayi=t; ,Logo,5.
15、4 用数组名作函数参数,例5.3 编写程序,用冒泡法对n(n=10)个数排序(按由小到大顺序)。冒泡法的思路是:将相邻两个数比较,将大的调到后面。,void bubble_sort( int b , int n) int i,j,temp;bool flags;for(i=n-1 ;i=1;i-) flags=true;for(j=0;jbj+1) flags=false;temp=bj;bj=bj+1;bj+1=temp;if(flags) break; ,int main( ) int a10,i,n;cinn;for(i=0;iai;bubble_sort(a,n);for(i=0;in
16、;i+)coutai ;coutendl;return 0; ,Logo,5.4 用数组名作函数参数,说明: (1) 如果函数实参是数组名,形参也应为数组名,形参不能声明为普通变量(如int array;)。实参数组与形参数组类型应一致(如都为int型),如不一致,结果将出错。 (2) 数组名代表数组首元素的地址,并不代表数组中的全部元素。因此用数组名作函数实参时,不是把实参数组的值传递给形参,而只是将实参数组首元素的地址传递给形参.,Logo,5.4 用数组名作函数参数,3. 用多维数组名作函数参数 如果用二维数组名作为实参和形参,在对形参数组声明时,必须指定第二维(即列)的大小,且应与实参
17、的第二维的大小相同。第一维的大小可以指定,也可以不指定。如 int array310; /形参数组的两个维都指定 int array 10; /第一维大小省略 下面的形参数组写法不合法: int array ; /不能确定数组的每一行有多少列元素 int array3 ; /不指定列数就无法确定数组的结构,Logo,5.4 用数组名作函数参数,3. 用多维数组名作函数参数 例5.8 有一个34的矩阵,要求编程序求出所有元素的最大值,以及其所在的行号和列号。要求用数组处理。,#include using namespace std; int main( ) int max_value( int
18、array 4);int a34=11,32,45,67,22,44,66,88,15,72,43,37;coutmax) max=arrayij;return max; ,Logo,5.5 字符数组,存放字符数据的数组是字符数组,字符数组中的一个元素存放一个字符。 字符数组具有数组的共同属性。 字符数组又具有特殊的属性。,Logo,5.5.1 字符数组的定义和初始化,一维字符数组定义: char c10; 一维字符数组初始化:char c10=I, ,a,m, ,h,a,p,p,y; 上面定义了c为字符数组,包含10个元素。,Logo,5.5.1 字符数组的定义和初始化,二维字符数组定义:
19、char stu510;包含有5*10个元素(5行10列)。 二维字符数组初始化: char stu510=J,o,h,n,M,i,k,e;,赋初值个数大于数组长度,编译出错; 赋初值个数小于数组长度,未赋初值元素的值自动为空(0)。,int main() int i,j,upper,lower,digit,space,other; char text310;upper=lower=digit=space=other=0;for (i=0;i=A,P162 第10题,Logo,*5.6 C+处理字符串的方法,C+提供了一种新的数据类型字符串类型(string类型)。 string不是C+的基本
20、类型,它是在C+标准库中声明的一个字符串类。使用string类型时,必须有#include 。,Logo,5.6.1 字符串变量的定义和引用,1. 定义字符串变量 用类名string定义字符串变量。如 string string1; string string2 = “China”; /定义string2同时初始化,定义和使用与标准数据类型相同。,Logo,5.6.1 字符串变量的定义和引用,2. 对字符串变量的赋值 可用赋值语句对它赋予一个字符串常量,如string2 = “China”; 用一个字符串变量给另一个字符串变量赋值,如 : string2=string1; /string2和s
21、tring1为字符串变量 在定义字符串变量时不需指定长度,长度随其中的字符串长度而改变。,Logo,5.6.1 字符串变量的定义和引用,对字符串变量中某一字符进行操作,如 : string word = “Then“; word2 = e;,word 变量中的值为:“Then”,Logo,5.6.1 字符串变量的定义和引用,3. 字符串变量的输入输出 可以在输入输出语句中用字符串变量名,输入输出字符串,如cin string1; cout string2; 例:将输入的一串字符简单译码后输出。 译码规则:每个字符均译成其后面的第4个字符。,#include #include using nam
22、espace std; int main( ) string string1;cin string1; for(int i=0;istring1.length( );i+)string1i=string1i + 4;cout string1endl; return 0; ,Logo,5.6.2 字符串变量的运算,在以字符数组存放字符串时,字符串的运算要用字符串函数,如strcat(连接)、strcmp(比较)、strcpy(复制),而对string类对象,可以不用这些函数,而直接用简单的运算符。 (1) 字符串复制用赋值号string1=string2; 例如:str1= “student”;
23、 其作用与strcpy(str1,str2);strcpy(str1,“student“);相同。,Logo,5.6.2 字符串变量的运算,(2) 字符串连接用加号(两个字符串变量相加) string string1=“C+ ”; string string2=“Language”; string1=string1 + string2; /连接string1和string2 连接后string1为“C+ Language”。 等价于: strcat(string1, string2)、,Logo,5.6.2 字符串变量的运算,Logo,5.6.2 字符串变量的运算,(3) 字符串比较直接用关系
24、运算符直接用 =(等于)、(大于)、=(大于或等于)、=(小于或等于)比较字符串。 使用这些运算符比使用字符串函数直观而方便。,Logo,5.6.3 字符串数组,不仅可以用string定义字符串变量,也可以用string定义字符串数组。如 string name5; String name5=“Zhang“,“Li“,“Fun“,“Wang“,“Tan“;,Logo,5.6.3 字符串数组,(1) 在一个字符串数组中包含若干个(现为5个)元素,每个元素相当于一个字符串变量。 (2) 字符串数组的每一个元素存放一个字符串,而不是一个字符。字符串数组相当于二维的字符数组。 (3) 但每个字符串元素
25、不要求具有相同的长度,即使对同一个元素,当向其重新赋值时,其长度可能发生变化。 (4) 每一个字符串元素中只包含字符串本身的字符而不包括0。,Logo,5.6.4 字符串运算举例,例5.12 一个班有n个学生,需要把每个学生的简单材料(姓名、学号)输入计算机保存。然后可以通过输入某一学生的姓名查找其有关资料。当输入一个姓名后,程序就查找该班中有无此学生,如果有,则输出他的姓名和学号,如果查不到,则输出“查无此人”。,#include #include using namespace std; string name50,num50; /定义两个字符串数组,分别存放姓名和学号 int n; /n
26、是实际的学生数 void input_data( ) int i;for (i=0;inameinumi; ,void search(string find_name) int i;bool flag=false;for(i=0;in;i+)if(namei=find_name) /如果要找的姓名与本班某一学生姓名相同 coutnamei 已找到, 他的学号是 numiendl; flag=true; break; if(flag=false) cout查无此人; ,int main( ) string find_name; /定义字符串变量coutn; /输入学生数input_data( )
27、; coutfind_name; search(find_name); /调用search函数,寻找学生姓名return 0; ,Logo,5.6.3 字符串数组,C+对字符串的处理有两种方法: 用字符数组的方法,这是C语言采取的方法。 用string类定义字符串变量,称为string方法。string方法概念清楚,使用方便,最好采用这种方法。C+保留字符数组方法主要是为了与C兼容,使以前用C写的程序能用于C+环境。,#include using namespace std; int main() const n=10;int i;char an;coutai;for(i=n-1;i=0;i-)coutai;coutendl;return 0; ,P163 第16题(1),#include #include using namespace std; int main() string a;int i,n;couta;n=a.size();for(i=n-1;i=0;i-)coutai;return 0; ,P163 第16题(2),Thank you,