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