谭浩强C程序设计课件第5章

上传人:san****019 文档编号:20651588 上传时间:2021-04-08 格式:PPT 页数:84 大小:532.31KB
收藏 版权申诉 举报 下载
谭浩强C程序设计课件第5章_第1页
第1页 / 共84页
谭浩强C程序设计课件第5章_第2页
第2页 / 共84页
谭浩强C程序设计课件第5章_第3页
第3页 / 共84页
资源描述:

《谭浩强C程序设计课件第5章》由会员分享,可在线阅读,更多相关《谭浩强C程序设计课件第5章(84页珍藏版)》请在装配图网上搜索。

1、第 5章 数组 5.1 数组的概念 5.2 一维数组的定义和引用 5.3 二维数组的定义和引用 5.4 用数组名作函数参数 5.5 字符数组 *5.6 C+处理字符串的方法 字符串类与字 符串变量 概括地说: 数组是有序数据的集合。要寻找一个 数组中的某一个元素必须给出两个要素,即数组名 和下标。数组名和下标惟一地标识一个数组中的一 个元素。 数组是有类型属性的。同一数组中的每一个元素都 必须属于同一数据类型。一个数组在内存中占一片 连续的存储单元。如果有一个整型数组 a, 假设数 组的起始地址为 2000,则该数组在内存中的存储情 况如图 5.1所示。 5.1 数组的概念 图 5.1 引入数

2、组就不需要在程序中定义大量的变量,大大 减少程序中变量的数量,使程序精炼,而且数组含 义清楚,使用方便,明确地反映了数据间的联系。 许多好的算法都与数组有关。熟练地利用数组,可 以大大地提高编程和解题的效率,加强了程序的可 读性。 C+用方括号来表示下标,如用 s 1 ,s 2 ,s 3 分别代表 s1,s2,s3。 定义一维数组的一般格式为 类型标识符 数组名常量表达式; 例如 int a 10 ; 它表示数组名为 a, 此数组为整型,有 10个元素。 说明: (1) 数组名定名规则和变量名相同,遵循标识符定 名规则。 5.2 一维数组的定义和引用 5.2.1 定义一维数组 (2) 用方括号

3、括起来的常量表达式表示下标值,如 下面的写法是合法的: int a 10 ; int a 2*5 ; int a n*2 ; /假设前面已定义了 n为常变量 (3) 常量表达式的值表示元素的个数,即数组长度。 例如,在 “ int a 10 ;”中, 10表示 a数组有 10个 元素 ,下标从 0开始 ,这 10个元素是: a 0 ,a 1 ,a 2 ,a 3 ,a 4 ,a 5 ,a 6 ,a 7 , a 8 ,a 9。 注意最后一个元素是 a 9 而不 是 a 10。 (4) 常量表达式中可以包括常量、常变量和符号常 量,但不能包含变量。也就是说, C+不允许对数 组的大小作动态定义,即数

4、组的大小不依赖于程序 运行过程中变量的值。例如,下面这样定义数组是 不行的: int n; cinn; /输入 a数组的长度 int a n ; /企图根据 n的值决定数组的长度 如果把第 1, 2行改为下面一行就合法了 : const int n=5; 数组必须先定义,然后使用。只能逐个引用数组元 素的值而不能一次引用整个数组中的全部元素的值。 数组元素的表示形式为 数组名下标 下标可以是整型常量或整型表达式。例如 a 0 = a 5 + a 7 - a 2*3 5.2.2 引用一维数组的元素 例 5.1 数组元素的引用。 #include using namespace std; int

5、main( ) int i,a 10 ; for (i=0;i=0;i-) couta i ; coutendl; return 0; 运行结果如下: 9 8 7 6 5 4 3 2 1 0 程序使 a 0 a 9 的值为 09,然后按逆序输出。 (1) 在定义数组时分别对数组元素赋予初值。例如 int a 10 =0, 1, 2, 3, 4, 5, 6, 7, 8, 9; (2) 可以只给一部分元素赋值。例如 int a 10 =0,1,2,3,4; (3) 如果想使一个数组中全部元素值为 1,可以写成 int a 10 =1, 1, 1, 1, 1, 1, 1, 1, 1, 1; 不能写成

6、 int a 10 =1*10; 不能给数组整体赋初值。 (4) 在对全部数组元素赋初值时,可以不指定数组 长度。例如 int a 5 =1, 2, 3, 4, 5; 可以写成 int a =1, 2, 3, 4, 5; 5.2.3 一维数组的初始化 例 5.2 用数组来处理求 Fibonacci数列问题。 可以用 20个元素代表数列中的 20个数,从第 3个数 开始,可以直接用表达式 f i =f i-2 +f i-1 求出各数。 程序如下: #include #include using namespace std; int main( ) int i; int f 20 =1,1; /f

7、 0 =1,f 1 =1 for(i=2;i20;i+) 5.2.4 一维数组程序举例 f i =f i-2 +f i-1 ; /在 i的值为 2时, f 2 =f 0 +f 1, 依此类推 for(i=0;i20;i+) /此循环的作用是输出 20个数 if(i%5=0) coutendl; /控制换行,每行输出 5个数据 coutsetw(8)f i ; /每个数据输出时占 8列宽度 coutendl; /最后执行一次换行 return 0; 运行结果如下: (空一行) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 418

8、1 6765 例 5.3 编写程序,用起泡法对 10个数排序 (按由小到 大顺序 )。 起泡法的思路是:将相邻两个数比较,将小的调到 前头。见图 5.2。 然后进行第 2趟比较,对余下的前面 5个数按上法进 行比较,见图 5.3。 图 5.2 图 5.3 可以推知,如果有 n个数,则要进行 n-1趟比较 (和 交换 )。在第 1趟中要进行 n-1次两两比较,在第 j趟 中要进行 n-j次两两比较。 根据以上思路写出程序,今设 n=10, 本例定义数组 长度为 11, a 0 不用,只用 a 1 a 10, 以 符合人们的习惯。从前面的叙述可知,应该进行 9 趟比较和交换。 #include u

9、sing namespace std; int main( ) int a 11 ; int i,j,t; coutinput 10 numbers : endl; for (i=1;ia i ; coutendl; for (j=1;j=9;j+) /共进行 9趟比较 for(i=1;ia i+1 ) /如果前面的数大于后面的数 t=a i ;a i =a i+1 ;a i+1 =t; /交换两个数的位置,使小数上浮 coutthe sorted numbers : endl; for(i=1;i11;i+) /输出 10个数 couta i ; coutendl; return 0; 运行

10、情况如下: input 10 numbers: 3 5 9 11 33 6 -9 -76 100 123 the sorted numbers: -76 -9 3 5 6 9 11 33 100 123 具有两个下标的数组称为二维数组。有些数据要依 赖于两个因素才能惟一地确定,例如有 3个学生, 每个学生有 4门课的成绩,显然,成绩数据是一个 二维表,如书中表 5.1所示。 想表示第 3个学生第 4门课的成绩,就需要指出学生 的序号和课程的序号两个因素,在数学上以 S3,4表 示。在 C+中以 s 3 4 表示,它代表数据 73。 5.3 二维数组的定义和引用 定义二维数组的一般形式为 类型标

11、识符 数组名常量表达式常量表达式 例如 float a 3 4 ,b 5 10; 定义 a为 3 4(3行 4列 )的单精度数组, b为 5 10(5行 10列 )的单精度数组。注意不能写成 “ float a 3,4, b 5,10 ;”。 C+对二维数组采用这样 的定义方式,使我们可以把二维数组看作是一种特 殊的一维数组:它的元素又是一个一维数组。例如, 可以把 a看作是一个一维数组,它有 3个元素: a 0 ,a 1 ,a 2, 每个元素又是一个包含 4个 元素的一维数组,见图 5.4。 a 0 ,a 1 ,a 2 是 3个一维数组的名字。 5.3.1 定义二维数组 图 5.4 上面定义

12、的二维数组可以理解为定义了 3个一维数 组,即相当于 float a 0 4 ,a 1 4 ,a 2 4 此处把 a 0 ,a 1 ,a 2 作一维数组名。 C+ 的这种处理方法在数组初始化和用指针表示时显得 很方便,这在以后会体会到。 C+中,二维数组中元素排列的顺序是:按行存放, 即在内存中先顺序存放第一行的元素,再存放第二 行的元素。图 5.5表示对 a 3 4 数组存放的顺 序。 图 5.5 C+允许使用多维数组。有了二维数组的基础,再 掌握多维数组是不困难的。例如,定义三维数组的 方法是 float a 2 3 4 ; 定义 float型三维数组 a, 它有 2 3 4=24个元素。

13、 多维数组元素在内存中的排列顺序:第一维的下标 变化最慢,最右边的下标变化最快。例如,上述三 维数组的元素排列顺序为 a 0 0 0 a 0 0 1 a 0 0 2 a 0 0 3 a 0 1 0 a 0 1 1 a 0 1 2 a 0 1 3 a 0 2 0 a 0 2 1 a 0 2 2 a 0 2 3 a 1 0 0 a 1 0 1 a 1 0 2 a 1 0 3 a 1 1 0 a 1 1 1 a 1 1 2 a 1 1 3 a 1 2 0 a 1 2 1 a 1 2 2 a 1 2 3 二维数组的元素的表示形式为 数组名 下标下标 如 a 2 3。 下标可以是整型表达式,如 a 2-

14、 1 2*2-1。 不要写成 a 2,3 ,a 2-1,2*2-1 形式。 数组元素是左值,可以出现在表达式中,也可以被 赋值,例如 b 1 2 =a 2 3 /2; 在使用数组元素时,应该注意下标值应在已定义的 数组大小的范围内。常出现的错误是 5.3.2 二维数组的引用 int a 3 4 ; /定义 3行 4列的数组 a 3 4 =15; /引用 a 3 4 元素 定义 a为 3 4的数组,它可用的行下标值最大为 2, 列坐标值最大为 3。最多可以用到 a 2 3, a 3 4 就超过了数组的范围。 请严格区分在定义数组时用的 a 3 4 和引用 元素时的 a 3 4 的区别。前者 a

15、3 4 用 来定义数组的维数和各维的大小,后者 a 3 4 中的 3和 4是下标值, a 3 4 代表某一个元素。 可以用下面的方法对二维数组初始化: (1) 分行给二维数组赋初值。如 int a 3 4 =1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 这种赋初值方法比较直观,把第 1个花括号内的数 据赋给第 1行的元素,第 2个花括号内的数据赋给第 2行的元素 即按行赋初值。 (2) 可以将所有数据写在一个花括号内,按数组排 列的顺序对各元素赋初值。如 int a 3 4 =1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 效果与前

16、相同。但以第 1种方法为好,一行对一行, 界限清楚。用第 2种方法如果数据多,写成一大片, 容易遗漏,也不易检查。 5.3.3 二维数组的初始化 (3) 可以对部分元素赋初值。如 int a 3 4 =1, 5, 9; 它的作用是只对各行第 1列的元素赋初值,其余元 素值自动置为 0。赋初值后数组各元素为 1 0 0 0 5 0 0 0 9 0 0 0 也可以对各行中的某一元素赋初值: int a 3 4 =1,0, 6,0,0,11; 初始化后的数组元素如下: 1 0 0 0 0 6 0 0 0 0 11 0 这种方法对非 0元素少时比较方便,不必将所有的 0 都写出来,只需输入少量数据。也

17、可以只对某几行 元素赋初值: int a 3 4 =1, 5, 6; 数组元素为 1 0 0 0 5 6 0 0 0 0 0 0 第 3行不赋初值。也可以对第 2行不赋初值: int a 3 4 =1, , 9; (4) 如果对全部元素都赋初值 (即提供全部初始数据 ), 则定义数组时对第一维的长度可以不指定,但第二 维的长度不能省。如 int a 3 4 =1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 可以写成 int a 4 =1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 系统会根据数据总个数分配存储空间,一共 12个数 据,

18、每行 4列,当然可确定为 3行。 在定义时也可以只对部分元素赋初值而省略第一维 的长度,但应分行赋初值。如 int a 4 =0, 0, 3, , 0, 10; 这样的写法,能通知编译系统: 数组共有 3行。数 组各元素为 0 0 3 0 0 0 0 0 0 10 0 0 C+在定义数组和表示数组元素时采用 a 这种两个方括号的方式,对数组初始化时十分有用, 它使概念清楚,使用方便,不易出错。 例 5.4 将一个二维数组行和列元素互换,存到另一 个二维数组中。例如 a= 1 2 3 b= 1 4 4 5 6 2 5 3 6 程序如下: #include using namespace std;

19、 int main( ) int a 2 3 =1,2,3,4,5,6; int b 3 2 ,i,j; 5.3.4 二维数组程序举例 coutarray a: endl; for (i=0;i=1;i+) for (j=0;j=2;j+) couta i j ; b j i =a i j ; coutendl; coutarray b: endl; for (i=0;i=2;i+) for(j=0;j=1;j+) coutb i j ; coutendl; return 0; 运行结果如下: array a: 1 2 3 4 5 6 array b: 1 4 2 5 3 6 例 5.5 有一

20、个 3 4的矩阵,要求编程序求出其中值 最大的那个元素的值,以及其所在的行号和列号。 开始时把 a 0 0 的值赋给变量 max, 然后让 下一个元素与它比较,将二者中值大者保存在 max 中,然后再让下一个元素与新的 max比,直到最后 一个元素比完为止。 max最后的值就是数组所有元 素中的最大值。 程序如下: #include using namespace std; int main( ) int i,j,row=0,colum=0,max; int a 3 4 =5,12,23,56,19,28,37,46,-12,-34,6,8; max=a 0 0 ; /使 max开始时取 a

21、0 0 的值 for (i=0;i=2;i+) /从第 0行 第 2行 for (j=0;jmax) /如果某元素大于 max max=a i j ; /max将取该元素的值 row=i; /记下该元素的行号 i colum=j; /记下该元素的列号 j coutmax=max,row=row,colum=columendl; return 0; 输出结果为 max=56, row=0, colum=3 常量和变量可以用作函数实参,同样数组元素也可 以作函数实参,其用法与变量相同。数组名也可以 作实参和形参,传递的是数组的起始地址。 1. 用数组元素作函数实参 由于实参可以是表达式,而数组元素

22、可以是表达式 的组成部分,因此数组元素当然可以作为函数的实 参,与用变量作实参一样,将数组元素的值传送给 形参变量。 5.4 用数组名作函数参数 例 5.6 用函数处理例 5.5。 算法和例 5.5是一样的,今设一函数 max_value, 用 来进行比较并返回结果。可编写程序如下: #include using namespace std; int main( ) int max_value(int x,int max); /函数声明 int i,j,row=0,colum=0,max int a 3 4 =5,12,23,56,19,28,37,46,-12,-34,6,8; /数组初始

23、化 max=a 0 0 ; for (i=0;i=2;i+) for (j=0;j=3;j+) max=max_value(a i j ,max); /调用 max_value函数 if(max=a i j ) /如果函数返回的是 a i j 的值 row=i; /记下该元素行号 i colum=j; /记下该元素列号 j coutmax=max,row=row,colum=colummax) return x; /如果 xmax, 函数返回值为 x else return max; /如果 xmax, 函数返回值为 max 2. 用数组名作函数参数 可以用数组名作函数参数,此时实参与形参都用

24、数 组名(也可以用指针变量,见第 6章)。 例 5.7 用选择法对数组中 10个整数按由小到大排序。 所谓选择法就是先将 10个数中最小的数与 a 0 对 换 ;再将 a 1 到 a 9 中最小的数与 a 1 对 换 每比较一轮 ,找出一个未经排序的数中最小 的一个。共比较 9轮。 根据此思路编写程序如下: #include using namespace std; int main( ) void select_sort(int array ,int n); /函数声明 int a 10 ,i; coutenter the originl array: endl; for(i=0;ia i

25、; coutendl; select_sort(a,10); /函数调用,数组名作实参 coutthe sorted array: endl; for(i=0;i10;i+) /输出 10个已排好序的数 couta i ; 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(array j array k ) k=j; t=array k ;array k =array i ;array i =t;

26、运行情况如下: enter the originl array: 6 9 -2 56 87 11 -54 3 0 77 /输入 10个数 the sorted array: -54 -2 0 3 6 9 11 56 77 87 关于用数组名作函数参数有两点要说明: (1) 如果函数实参是数组名,形参也应为数组名 (或 指针变量,关于指针见第 5章 ),形参不能声明为普 通变量 (如 int array;)。 实参数组与形参数组类型应 一致(现都为 int型),如不一致,结果将出错。 (2) 需要特别说明的是: 数组名代表数组首元素的 地址,并不代表数组中的全部元素。因此用数组名 作函数实参时

27、,不是把实参数组的值传递给形参, 而只是将实参数组首元素的地址传递给形参。 形参可以是数组名,也可以是指针变量,它们用来 接收实参传来的地址。如果形参是数组名,它代表 的是形参数组首元素的地址。在调用函数时,将实 参数组首元素的地址传递给形参数组名。这样,实 参数组和形参数组就共占同一段内存单元。见图 5.6。 图 5.6 在用变量作函数参数时,只能将实参变量的值传给 形参变量,在调用函数过程中如果改变了形参的值, 对实参没有影响,即实参的值不因形参的值改变而 改变。而用数组名作函数实参时 ,改变形参数组元 素的值将同时改变实参数组元素的值。在程序设计 中往往有意识地利用这一特点改变实参数组元

28、素的 值。 实际上,声明形参数组并不意味着真正建立一个包 含若干元素的数组,在调用函数时也不对它分配存 储单元,只是用 array 这样的形式表示 array是 一维数组名,以接收实参传来的地址。因此 array 中方括号内的数值并无实际作用,编译系统对 一维数组方括号内的内容不予处理。形参一维数组 的声明中可以写元素个数,也可以不写。 函数首部的下面几种写法都合法,作用相同。 void select_sort(int array 10 ,int n) /指定元素个数与实参数组相同 void select_sort(int array ,int n) /不指定元素个数 void select_

29、sort(int array 5 ,int n) /指定元素个数与实参数组不同 在学习第 6章时可以进一步知道, C+实际上只把 形参数组名作为一个指针变量来处理,用来接收从 实参传过来的地址。前面提到的一些现象都是由此 而产生的。 3. 用多维数组名作函数参数 如果用二维数组名作为实参和形参,在对形参数组 声明时,必须指定第二维 (即列 )的大小,且应与实 参的第二维的大小相同。第一维的大小可以指定, 也可以不指定。如 int array 3 10 ; /形参数组的两个维都指定 或 int array 10 ; /第一维大小省略 二者都合法而且等价。但是不能把第二维的大小省 略。下面的形参数

30、组写法不合法: int array ; /不能确定数组的每一行有多少列元素 int array 3 ; /不指定列数就无法确定数组的结构 在第二维大小相同的前提下,形参数组的第一维可 以与实参数组不同。例如,实参数组定义为 int score 5 10 ; 而形参数组可以声明为 int array 3 10 ; /列数与实参数组相同,行数不同 int array 8 10 ; 这时形参二维数组与实参二维数组都是由相同类型 和大小的一维数组组成的,实参数组名 score代表 其首元素 (即第一行 )的起始地址,系统不检查第一 维的大小。 如果是三维或更多维的数组,处理方法是类似的。 例 5.8

31、有一个的矩阵,求矩阵中所有元素中 的最大值。要求用函数处理。 解此题的算法已在例 5.5中介绍。 程序如下: #include using namespace std; int main( ) int max_value(int array 4 ); int a 3 4 =11,32,45,67,22,44,66,88,15,72,43,37; coutmax value is max_value(a)endl; return 0; int max_value(int array 4 ) int i,j,max; max=array 0 0 ; for( i=0;i3;i+) for(j=0;

32、jmax) max=array i j ; return max; 运行结果如下: max value is 88 读者可以将 max_value函数的首部改为以下几种情 况,观察编译情况: int max_value(int array ) int max_value(int array 3 ) int max_value(int array 3 4 ) int max_value(int array 10 10 ) int max_value(int array 12 ) 用来存放字符数据的数组是字符数组,字符数组中 的一个元素存放一个字符。字符数组具有数组的共 同属性。由于字符串应用广泛

33、, C和 C+专门为它 提供了许多方便的用法和函数。 5.5 字符数组 定义字符数组的方法与前面介绍的类似。例如 char c 10 ; c 0 =I;c 1 = ;c 2 =a;c 3 =m;c 4 = ;c 5 =h;c 6 =a;c 7 =p;c 8 =p; c 9 =y; 上面定义了 c为字符数组,包含 10个元素。在赋值 以后数组的状态如图 5.7所示。 图 5.7 5.5.1 字符数组的定义和初始化 对字符数组进行初始化,最容易理解的方式是逐个 字符赋给数组中各元素。如 char c 10 =I, ,a,m, ,h,a,p,p,y; 把 10个字符分别赋给 c 0 c 9 这 10

34、个元素。 如果花括号中提供的初值个数大于数组长度,则按 语法错误处理。如果初值个数小于数组长度,则只 将这些字符赋给数组中前面那些元素,其余的元素 自动定为空字符。如果提供的初值个数与预定的数 组长度相同,在定义时可以省略数组长度,系统会 自动根据初值个数确定数组长度。如 char c =I, ,a,m, ,h,a,p,p,y; 也可以定义和初始化一个二维字符数组,如 char diamond 5 5 = , ,*, , *, , *, *, , , , *, , *, , *, , , *; 只能对字符数组的元素赋值,而不能用赋值语句对 整个数组赋值。如 char c 5 ; c=C,h,i

35、,n,a; /错误,不能对整个数组一次赋值 c 0 =C; c 1 =h;c 2 =i;c 3 =n;c 4 =a; /对数组元素赋值, 正确 如果已定义了 a和 b是具有相同类型和长度的数组, 且 b数组已被初始化,请分析: a=b; /错误,不能对整个数组整体赋值 a 0 =b 0 ; /正确,引用数组元素 5.5.2 字符数组的赋值与引用 例 5.9 设计和输出一个钻石图形。 #include using namespace std; void main( ) char diamond 5 = , ,*, ,*, ,*,*, , , ,*, ,*, ,*, , ,*; int i,j;

36、for (i=0;i5;i+) for (j=0;j5;j+) coutdiamond i j ; /逐个引用数组元素,每次输出一个字符 coutendl; 运行结果为 * * * * * * * * 用一个字符数组可以存放一个字符串中的字符。如 char str 12 =I, ,a,m, ,h,a,p,p,y; 用一维字符数组 str来存放一个字符串 I am happy 中的字符。字符串的实际长度 (10)与数组长度 (12) 不相等,在存放上面 10个字符之外,系统对字符数 组最后两元素自动填补空字符 0。 为了测定字符串的实际长度, C+规定了一个 “ 字 符串结束标志 ” ,以字符

37、0代表。在上面的数组 中,第 11个字符为 0,就表明字符串的有效字符 为其前面的 10个字符。也就是说,遇到字符 0就 表示字符串到此结束,由它前面的字符组成字符串。 5.5.3 字符串和字符串结束标志 对一个字符串常量,系统会自动在所有字符的后面 加一个 0作为结束符。例如字符串 I am happy 共有 10个字符,但在内存中它共占 11个字节,最后 一个字节 0是由系统自动加上的。 在程序中往往依靠检测 0的位置来判定字符串是 否结束,而不是根据数组的长度来决定字符串长度。 当然,在定义字符数组时应估计实际字符串长度, 保证数组长度始终大于字符串实际长度。如果在一 个字符数组中先后存

38、放多个不同长度的字符串,则 应使数组长度大于最长的字符串的长度。 说明: 0只是一个供辨别的标志。 如果用以下语句输出一个字符串: coutstr; /用字符数组名输入字符串 coutstr; /用字符数组名输出字符串 在运行时输入一个字符串,如 China 在内存中,数组 str的状态如图 5.9所示,在 5个字符 的后面自动加了一个结束符 0。 5.5.4 字符数组的输入输出 图 5.9 输出时,逐个输出字符直到遇结束符 0,就停止 输出。输出结果为 China 如前所述,字符数组名 str代表字符数组第一个元素 的地址,执行 “ coutstr;”的过程是从 str所指向的 数组第一个元

39、素开始逐个输出字符,直到遇到 0 为止。 请注意: (1) 输出的字符不包括结束符 0。 (2) 输出字符串时, cout流中用字符数组名,而不 是数组元素名。 (3) 如果数组长度大于字符串实际长度,也只输出 到遇 0结束。 (4) 如果一个字符数组中包含一个以上 0,则遇 第一个 0时输出就结束。 (5) 用 cin从键盘向计算机输入一个字符串时,从键 盘输入的字符串应短于已定义的字符数组的长度, 否则会出现问题。 C+提供了 cin流中的 getline函数,用于读入一行字 符 (或一行字符中前若干个字符 ),使用安全又方便, 请参阅第 13章 13.3.2节。 由于字符串使用广泛, C

40、和 C+提供了一些字符串 函数,使得用户能很方便地对字符串进行处理。几 乎所有版本的 C+都提供下面这些函数,它们是放 在函数库中的,在 string和 string.h头文件中定义。 如果程序中使用这些字符串函数,应该用 #include 命令把 string.h或 string头文件包含到本文件中。下 面介绍几种常用的函数。 5.5.5 字符串处理函数 1. 字符串连接函数 strcat 其函数原型为 strcat(char ,const char ); strcat是 string catenate( 字符串连接)的缩写。该 函数有两个字符数组的参数,函数的作用是:将第 二个字符数组中的

41、字符串连接到前面字符数组的字 符串的后面。第二个字符数组被指定为 const, 以 保证该数组中的内容不会在函数调用期间修改。连 接后的字符串放在第一个字符数组中,函数调用后 得到的函数值,就是第一个字符数组的地址。例如 char str1 30 =Peoples Republic of ; char str2 =China; cout字符串 2,函数值为一正整数。 (3) 如果字符串 1str2) cout0) coutyes; 4. 字符串长度函数 strlen 函数原型为 strlen(const char ); strlen是 string length( 字符串长度)的缩写。它是 测

42、试字符串长度的函数。其函数的值为字符串中的 实际长度,不包括 0在内。如 char str 10 =China; coutstrlen(str); 输出结果不是 10,也不是 6,而是 5。 以上是几种常用的字符串处理函数,除此之外还有 其他一些函数。 例 5.10 有 3个字符串 ,要求找出其中最大者。要求用 函数调用。 程序如下: #include #include using namespace std; int main( ) void max_string(char str 30 ,int i); /函数声明 int i; char country_name 3 30 ; for(i

43、=0;icountry_name i ; /输入 3个国家名 max_string(country_name,3); /调用 max_string函数 return 0; 5.5.6 字符数组应用举例 void max_string(char str 30 ,int n) int i; char string 30 ; strcpy(string,str 0 ); /使 string的值为 str 0 的值 for(i=0;i0) /如果 str i string strcpy(string,str i ); /将 str i 中的字符串复制到 string coutendlthe large

44、st string is: stringendl; 运行结果如下: CHINA GERMANY FRANCH the largest string is: GERMANY 用字符数组来存放字符串并不是最理想和最安全的 方法。 C+提供了一种新的数据类型 字符串类型 (string类型 ),在使用方法上,它和 char、 int类型 一样,可以用来定义变量,这就是字符串变量 用一个名字代表一个字符序列。 实际上, string并不是 C+语言本身具有的基本类 型,它是在 C+标准库中声明的一个字符串类,用 这种类可以定义对象。每一个字符串变量都是 string类的一个对象。 *5.6 C+处理字

45、符串的方法 字符串类 与字符串变量 1. 定义字符串变量 和其他类型变量一样,字符串变量必须先定义后使 用,定义字符串变量要用类名 string。 如 string string1; /定义 string1为字符串变量 string string2=China; /定义 string2同时对其初始化 应当注意: 要使用 string类的功能时,必须在本文 件的开头将 C+标准库中的 string头文件包含进来, 即应加上 #include /注意头文件名不是 string.h 5.6.1 字符串变量的定义和引用 2. 对字符串变量的赋值 在定义了字符串变量后,可以用赋值语句对它赋予 一个字符串

46、常量,如 string1=Canada; 既可以用字符串常量给字符串变量赋值,也可以用 一个字符串变量给另一个字符串变量赋值。如 string2=string1; /假设 string2和 string1均已定义为字符串变量 不要求 string2和 string1长度相同,假如 string2原来 是 China, string1原来是 Canada, 赋值后 string2也变成 Canada。 在定义字符串变量时不 需指定长度,长度随其中的字符串长度而改变。 可以对字符串变量中某一字符进行操作,如 string word=Then; /定义并初始化字符串变量 word word 2 =a

47、; /修改序号为 2的字符,修改后 word的值为 Than 3. 字符串变量的输入输出 可以在输入输出语句中用字符串变量名,输入输出 字符串,如 cin string1; /从键盘输入一个字符串给字符串变量 string1 cout(大于 )、 =(大于或等于 )、 =(小于或等于 )等关系运算 符来进行字符串的比较。 使用这些运算符比使用 5.5.5节中介绍的字符串函数 直观而方便。 不仅可以用 string定义字符串变量,也可以用 string 定义字符串数组。如 string name 5 ; /定义一个字符串数组,它包含 5个字符串元素 string name 5 =Zhang,Li

48、,Fun,Wang,Tan; /定义一个字符串数组并初始化 此时 name数组的状况如图 5.11所示。 图 5.11 5.6.3 字符串数组 可以看到: (1) 在一个字符串数组中包含若干个 (现为 5个 )元素, 每个元素相当于一个字符串变量。 (2) 并不要求每个字符串元素具有相同的长度,即 使对同一个元素而言,它的长度也是可以变化的, 当向某一个元素重新赋值,其长度就可能发生变化。 (3) 在字符串数组的每一个元素中存放一个字符串, 而不是一个字符,这是字符串数组与字符数组的区 别。如果用字符数组存放字符串,一个元素只能存 放一个字符,用一个一维字符数组存放一个字符串。 (4) 每一个

49、字符串元素中只包含字符串本身的字符 而不包括 0。 可见用字符串数组存放字符串以及对字符串进行处 理是很方便的。 在定义字符串数组时怎样给数组分配存储空间呢? 实际上,编译系统为每一个字符串变量分配 4个字 节,在这个存储单元中,并不是直接存放字符串本 身,而是存放字符串的地址。在本例中,就是把字 符串 Zhang的地址存放在 name 0, 把字符串 Li 的地址存放在 name 1, 把字符串 Fun的 地址存放在 name 2 图 5.11只是一个示意图。 在字符串变量中存放的是字符串的指针 (字符串的 地址 )。 例 5.11 输入 3个字符串,要求将字母按由小到大的 顺序输出。 #i

50、nclude #include using namespace std; int main( ) string string1,string2,string3,temp; coutstring1string2string3; /输入 3个字符串 if(string2string3) temp=string2;string2=string3;string3=temp; /使串 2串 3 if(string1=string2) coutstring1 string2 string3endl; /如果串 1串 2,则串 1串 2串 3 5.6.4 字符串运算举例 else if(string1=st

51、ring3) coutstring2 string1 string3endl; /如果串 1串 2,且串 1串 3,则串 2串 1串 3 else coutstring2 string3 string1endl; /如果串 1串 2,且串 1串 3,则串 2串 3串 1 运行情况如下: please input three strings: China U.S.A. Germany China Germany U.S.A. 例 5.12 一个班有 n个学生,需要把每个学生的简单 材料 (姓名和学号 )输入计算机保存。然后可以通过 输入某一学生的姓名查找其有关资料。当输入一个 姓名后,程序就查找

52、该班中有无此学生,如果有, 则输出他的姓名和学号,如果查不到,则输出 “ 本 班无此人 ” 。 为解此问题,可以分别编写两个函数,函数 input_data用来输入 n个学生的姓名和学号,函数 search用来查找要找的学生是否在本班。 程序可编写如下: #include #include using namespace std; string name 50 ,num 50 ; /定义两个字符串数组,分别存放姓名和学号 int n; /n是实际的学生数 int main( ) void input_data( ); /函数声明 void search(string find_name); /

53、函数声明 string find_name; /定义字符串变量, find_name是要找的学生 coutn; /输入学生数 input_data( ); /调用 input_data函数,输入学生数据 coutfind_name; /输入要找的学生的姓名 search(find_name); /调用 search函数,寻找该学生姓名 return 0; void input_data( ) /函数首部 int i; for (i=0;in;i+) coutinput name and NO. of student i+1name i num i ; /输入 n个学生的姓名和学号 void s

54、earch(string find_name) /函数首部 int i; bool flag=false; for(i=0;in;i+) if(name i =find_name) /如果要找的姓名与本班某一学生姓名相同 coutname i has been found, his number is num i endl; /输出姓名与学号 flag=true; break; if(flag=false) coutcant find this name;/如找不到,输出 “ 找不到 ” 的信息 运行情况如下: please input number of this class: 5 inpu

55、t name and number of student 1: Li 1001 input name and number of student 2: Zhang 1002 input name and number of student 3: Wang 1003 input name and number of student 4: Tan 1004 input name and number of student 5: Fun 1005 please input name you want find: Wang Wang has been found, his number is 1003

56、 请考虑: (1) 程序第 3行定义全局变量时,数组的大小不指定 为 50,而用变量 n, 即 string name n ,num n ;n在运行时输入,行不行?为什么? (2) search函数 for循环中最后有一个 break语句,它 起什么作用?不要行不行? (3) 如果不使用全局变量,把变量 n和数组 name, num都作为局部变量,通过虚实结合的方法在函数 间传递数据,这样行不行?请思考并上机试一下。 通过以上两个例子可以看到,用 string定义字符串 变量,简化了操作,把原来复杂的问题简单化了, 这是 C+对 C的一个发展。 归纳起来, C+对字符串的处理有两种方法: 一种 是用字符数组的方法,这是 C语言采取的方法, 一般称为 C string方法;一种是用 string类定义字 符串变量,称为 string方法。显然, string方法概念 清楚,使用方便,最好采用这种方法。 C+保留 C- string方法主要是为了与 C兼容,使以前用 C写的程 序能用于 C+环境。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!