C:字符串和指针.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《C:字符串和指针.pdf》由会员分享,可在线阅读,更多相关《C:字符串和指针.pdf(71页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、第二章数组、字符串和指针迄今为止,我们已经学习了所有重要的基木数据类型,对于如何在程序中执行计算和进行判断也有了基本的了解。本章将扩展前面所学的基本编程技术的应用范围,从此前使用单独的数据项扩展到处理数据项的整个集合。木章将讲述以下内容:数组及其使用方法 如何声明和初始化不同类型的数组 如何声明和使用多维数组 指针及其使用方法 如何声明和初始化不同类型的指针 数组和指针之间的关系 引用的概念及声明方法,关于使用引用的几点初步建议 如何在本地C+程序中给变量动态分配内存 如何在CLR程序中动态分配内存 跟踪句柄和跟踪引用的概念,CLR程序中需要它们的原因 如何在C+/CLI程序中处理字符串和数组
2、 内部指针的概念,创建和使用内部指针的方法本章将更多地使用对象,我们还没有详细分析如何创建对象,因此即使对此一无所知也不必担心。我们将从第7章开始详细学习类和对象。4.1 处理多个相同类型的数据值我们已经知道如何声明和初始化那些仅容纳单项信息的各种类型的变量一本书称之为数据元素。我们知道如何在char类型的变量中创建一个字符,如何在short、int或long类型的变量中创建一个整数,如何在float或double类型的变量中创建一个浮点数。最容易想到的对这些技术的扩展是用单个变量名引用特定类型的多个数据元素,这样我们将能够处理更宽范围的应用问题。在下面这个例子中,我们就需要这种技术。假设需要
3、编写工资计算程序。为每个人的工资、应缴税款等信息使用单独命名的变量,这是一项艰巨的任务。处理此类问题的简便方法是使用第4章 数组、字符串和指针某种类属名(比如employeeName)来引用员工,用其他类属名来引用与各个员工有关的数据,比如工资、应缴税款等。当然,我们还需要一种从全体员工中挑选出个别员工的方法,以及从相关的同类变量中挑选出数据的方法。这种需求随着程序中出现要处理的相似实体的集合而出现,这些实体可能是棒球运动员,也可能是战舰。自然,C+给我们提供了处理集合的方法。4.1.1 数组在 ISO/ANSI C+中,数组是所有此类问题解决方案的基础。数组就是一组名为数组元素或简称元素的存
4、储单元,各个存储单元可以存储相同数据类型的数据项,而我们可以用相同的变量名引用所有存储单元。工资计算程序中员工姓名就可以存储在一个数组中,各员工的工资可以存储在另一个数组中,而应缴税款可存储在第三个数组中。数组中各个数据项用索引值进行标识;索引值就是表示数组元素编号的整数。第一个元素的编号是0,第二个是1,依此类推。我们也可以将数组元素的索引值视为相对于数组中第一个元素的偏移量。第一个元素的偏移量是0,因此其索引值是0,索引值3 指的是第四个数组元素。对工资计算程序来说,我们应该这样安排那3 个数组:如果某个员工的姓名存储在employeeName数组中特定索引值标识的单元,则 pay和 ta
5、x数组应该在相同索引值引用的数组位置存储该员工的工资和应缴税款数据。数组的基本结构如图4所示。第2个元素的索引值-第5个元素的索引值-数 姐 名 一 数 组 名 一hcigit0 heightO heiglitO heigh t0 heightO heightfO736251424134height数组包含6个元素图4-1图4-1是一个数组的结构图。数组height有 6 个元素,各元素存储不同的数值。这些数值是某个家庭中所有成员的身高(精确到英寸)。因为有6 个元素,所以索引值为05。如果要引用某个元素,则应该先写出数组名称,然后在方括号内写上该元素的索引值。例如,height将引用第三个元
6、素。如果将索引值看作相对于第一个元素的偏移量,则很容易理解第四个元素的索引值是3。存储各个元素所需存储单元的数量取决于元素的类型,数组的所有元素都存储在连续的内存区域中。4.1.2 声明数组数组的声明方法基本上与此前所看到的变量声明的方法相同,唯区别是应该在紧跟数组135Visual C+2008 入门经典名的方括号内指出数组元素的数量。例如,我们可以用下面这条声明语句,声明图4-1中的整数数组height:long height6;因为每个long数值在内存中要占用4个字节,所以整个数组共需24个字节。数组长度只受运行该程序的计算机上内存总量的限制。数组可以被声明成任意类型。例如,我们可以用
7、下面这条语句,声明两个用来存储一组发动机的体积和功率的数组:double cubic_inches10;double horsepower10;/Engine size/Engine power output这两个数组可存储10台发动机的体积和功率,其索引值为0-9.正如前面在其他变量的声明语句中所看到的那样,我们可以用条语句声明多个同类型的数组,但实践中在分开的语句中声明变量往往更合适。试一试:使用数组为练习如何使用数组,假设我们需要记录每次给汽车购买的汽油量和相应的里程表读数。我们可以编写程序来分析这些数据,以了解不同时间段的汽油消耗情况。/Ex4_01.cpp/Calculating g
8、as mileage#include#include using std:cin;using std:cout;using std:endl;using std:setw;int main()(const int MAX=20;double gas MAX;long miles MAX;int count=0;char indicator=*y ;while(indicator=y|/Maximum number of values/Gas quantity in gallons/Odometer readings/Loop counter/Input indicatorindicator=Y
9、,)&count MAX)cout endl gascount;/Read gas quantitycout milescount;/Read odometer value+count;cout indicator;if(count=1)/count=1 after 1 entry completed/.we need at least 2136第4 章 数组、字符串和指针cout endl nSorry-at least two readings are necessary.n;return 0;/Output results from 2nd entry to last entryfor(
10、int i=1;i count;i+)cout endl setw(2)i /Output sequence number Gas purchased=gas i gallons,1/Output gas n resulted in*/Output miles per gallon (milesi -milesi-1)/gasi miles per gallon.;cout endl;return 0;程序假设每次都给油箱加满汽油,下面是本程序产生的输出:Enter gas quantity:12.8Enter odometer reading:25832Do you want to ente
11、r another(yEnter gas quantity:14.9Enter odometer reading:26337Do you want to enter another(y因此购买的汽油量就是行驶的里程所需的汽油消耗量。or n)?yor n)?yEnter gas quantity:11.8Enter odometer reading:26598Do you want to enter another(y1.Gas purchased=14.9 gallons resulted in 33.8926 miles per gallon.2 .Gas purchased=11.8 g
12、allons resulted in 22.1186 miles per gallon.示例说明因为必须得到两次里程表读数的差值,才能计算用掉的汽油所能行驶的里程,所以我们只使用第一对输入值的里程表读数,而忽略第一次购买的汽油量,这些汽油是在以前行驶的路程中消耗掉的。在输出中显示的第二段时间内,交通状况必定相当糟糕,或者是经常踩刹车。用来存储输入数据的两个数组gas和miles的大小取决于常量MAX。通过改变MAX的值,我们即可使该程序适应最大数量不同的输入值集合。这种技术经常用来使程序灵活地适应要处理的信息量。当然,编写程序代码时必须考虑到const变量指定的数组大小或任何其他参数。不过,上
13、述要求增加的难度不算大,因此没有任何理由不采用这种技术。我们稍后还将学习如何在程序执行时动态分配内存,从而不必再预先给数据分配固定数量的内存。输入数据while循环读取数据值。因为循环变量的范围是从0到MAX-L所以该程序不允许其用户输入超过数组容量的数据量。程序分别将变量count和indicator初始化为0和y,因此while循环至少执行-次。程序提示用户输入要求的各个数值,然后将输入值读入适当的数组元素中。用来存储具体数值的元素由变量count确定,第一次输入时该变量是0。我们以count作为索引值,在cin语句中指定数组元素,然后使count力 口 1,从而为下次输入做好准备。137
14、Visual C+2008 入门经典输入各个数值之后,程序提示用户确认是否要输入另外的数值。输入的字符被读入indicator变量中,然后在循环条件中进行测试。如果没有输入y 或 Y,则循环终止,变量count小于指定的最大值MAX。输入循环结束以后(无论通过什么方法),count的值将比每个数组中最后输入的元素的索引值大1(记住,我们每次输入新元素之后都使该变量加1)。检查该变量可以验证是否至少输入了两对数值。如果不是,则程序将以一条适当的消息结束,因为计算里程至少需要两个里程表读数。生成结果输出是在for循环中产生的。控制变量i 从 1变化到count-I,使程序计算当前元素milesi和
15、前一个元素milesi-1之间的差值,以作为本次行驶的里程。注意,数组的索引值可以是任何结果为整数的表达式,前提是该整数是相应数组的合法索引值一即从0 到数组元素的数量减 lo如果索引表达式的值不在对应于合法数组元素的范围之内,那么程序将引用一个错误的存储单元,其中可能包含其他数据、无用信息甚至程序代码。如果对错误元素的引用出现在表达式中,则程序将使用随机的一个数据值进行计算,这当然会产生意外结果。如果需要将某种结果存储在数组元素中,但使用的是非法索引值,则将覆盖位于该存储单元的任何数据。如果被破坏的数据是程序代码的组成部分,则结果是灾难性的。当我们使用非法索引值时,编译或运行过程中并没有任何
16、警告产生。唯一能够避免此类错误的方法是用程序代码来防止其发生。cout语句为除第一对以外的所有输入值生成输出。程序还使用循环控制变量i,为每行输出生成一个行号。每加仑汽油行驶的英里数是在输出语句中直接计算的。在表达式中使用数组元素的方式与使用任何其他变量完全相同。4.1.3 初始化数组为了在声明时初始化数组,我们应该将逗号分开的初始化数值放入大括号内,然后将这样的初值集合放在数组名后面的等号之后。卜面是声明并初始化数组的示例:int cubic_inches5=(200,250,300,350,400);该数组的名称是cubijinches,包括5 个元素,各存储一个int型数值。大括号内初始
17、化列表中的数值对应于连续的数组索引值,因此cubijinches 的值是200,cubic_inchesl的值是250,cubic_inches2的值是 3 0 0,依此类推。指定的初始化数值不能比数组的元素多,但可以比数组的元素少。如果少,则列表中的初值被分配给从第一个元素(对应于索引值0)开始的连续元素。那些没有得到初值的数组元素被初始化为0。如果根本没有提供初始化列表,则情况就不是这样。如果没有初始化列表,数组元素包含的将是无用数据。另外,如果我们使用初始化列表,则列表内必须至少包括一个初值,否则编译器将生成条出错消息。下面这个示例用来说明数组的初始化方法。试一试:初始化数组/Ex4_0
18、2.cpp/Demonstrating array initialization#include 138第4章 数组、字符串和指针#include using std:cout;using std:endl;using std:setw;int main()Iint value5=1,2,3;int junk 5;cout endl;for(int i=0;i 5;i+)cout setw(12)valuei;cout endl;for(int i=0;i 5;i+)cout setw(12)junk i;cout endl;return 0;该示例声明了两个数组。第一个数组value被部分初
19、始化,但第二个数组junk完全没有被初始化。该程序生成两行输出,笔者计算机上的输出结果如下:1 2 3 0 0-858993460-858993460-858993460-858993460-858993460在您的计算机上,第二行值(对应于junkOJ到junk4的值)可能完全不同。示例说明数组value的前3 个数值是初值,后两个是默认值0。在junk数组中,所有数值都是荒谬的,因为我们根本没有提供任何初值。那些数组元素保留着上次使用这些存储单元的程序遗留下来的内容。将整个数组初始化为0 的便捷方法是仅指定个初值0。例如:long data100 =0;/Initialize all el
20、ements to zero这条语句声明数组d ata,并将全部100个元素初始化为0。第一个元素是用大括号内的数值初始化的,其余元素因语句中省略了相应的初值而被初始化为0.倘若提供初值的话,我们还可以省略数值型数组的长度。数组元素的数量由指定的初值数量决定。例如,数组声明语句int value =2,3,4 ;定义的数组有3 个元素,初值分别是2、3 和 4。4.1.4 字符数组和字符串处理char类型的数组被称作字符数组,通常用来存储字符串。字符串是附加有特殊字符(串尾标志)的字符序列。串终止字符表明字符串已经结束,该字符由转义序列 0 定义,有时被称为139Visual C+2008 入
21、门经典空字符,占用一个字节,其中8位全为0。这种形式的字符串经常被称作C型字符串,因为以这样的方式定义字符串是在C语言中推出的,后来Bjarne Stroustrup以C语言为基础开发出了C+。这不是唯一能用的字符串表示法,本书稍后将介绍其他表示方法。特别需要指出的是,C+/CLI程序使用一种不同的字符串表示法,而MFC定义了表示字符串的CString类。C型字符串在内存中的表不如图4-2所不。name4字符串终止字符字符串中的每个字符占用1个字节 Al ber t E i n s t e i n 0char name 尸Albert Einstein”图4-2图4-2说明了内存中字符的表示形
22、式,同时给出 种我们即将讨论的的字符串声明形式。注意:字符串中每个字符占用一个字节,因此算上最后的空字符,字符串需要的字节数要比包含的字符数多一个。我们可以用字符串字面值来声明并初始化字符数组。例如:char movie_star15=Marilyn Monroe;注意,终止字符 0 是编译器自动添加的。如果在该字面值中显式添加 0,则最终将得到两个空字符。但是,我们给字符数组指定元素数量时必须考虑到终止字符的存在。如图4-1所示,我们可以让编译器来算出已初始化的数组的长度。下面是另一个示例:char president =Ulysses Grant;因为长度没有指定,所以编译器将分配足够的内
23、存空间来容纳该初始化字符串及终止字符。在本例中,编译器将给数组president分 配14个元素。当然,如果希望稍后使用该数组来存储另一个字符串,则其长度(包括终止空字符)不能超过14个字节。通常,确保数组足以存储随后希望存储的任何字符串是编程人员的职责。我们也可以创建由Unicode字符组成的字符串,字符串中的字符类型为w chajt。下面是一个创建Unicode字符串的语句:wchar_t president =LUlysses Grant;前缀L表示字符串字面值是一个宽字符串,因此字符串中的每个字符(包括终止空字符)都会占两个字节。当然,对字符串的索引会引用字符,而不是字节,因此pres
24、ident对应于字符L/o140第4章 数组、字符串和指针1.字符串输入头文件包含许多从键盘上读取字符的函数定义。下面将看到的是getline()函数,该函数读取从键盘输入的字符序列,并将其以字符串形式(以0字符终止)存入字符数组中。我们通常像下面这样使用getline。函数:c o n st in t MAX=80;/Maximum s tr in g le n g th in c lu d in g 0ch ar nameMAX;/A rray to s to r e a s tr in gc in.g e tlin e(n a m e,MAX,*n );/Read in p u t li
25、n e as a s tr in g这些语句首先声明个有MAX个元素的char型数组nam e,然后使用getline。函数从cin中读取字符。如上所示,数据源cin与函数名称之间有一个句点。句点表示我们在调用的getline。函数属于cin对 象 之-o getline。函数中各参数的意义在图4-3中给出。charQ类型数组的名称.从 cin读取的字符存储在该数组中要读取的字符的最大数量.当读取了最大数量的字符数后,停止输入cin.getline(name.MAX.W);图4-3结束输入过程的字符.在此可以指定任一字符,且该字符在首次出现时就将结束输入过程因为getline()函数的最后一个
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 字符串 指针
![提示](https://www.deliwenku.com/images/bang_tan.gif)
限制150内