第四章 指针与引用.ppt_第1页
第四章 指针与引用.ppt_第2页
第四章 指针与引用.ppt_第3页
第四章 指针与引用.ppt_第4页
第四章 指针与引用.ppt_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章指针与引用 03 34 56 2 106 数组的概念一维数组的声明和使用一维数组的存储顺序一维数组的初始化二维数组的声明和使用二维数组的初始化数组作为函数参数对象数组 指针变量的定义 初始化指针运算指针数组指向对象的指针 字符串指针引用变量向对象传递引用 返回引用引用与指针的关系引用的常用方法 03 34 56 3 106 数组的概念 数组是具有一定顺序关系的若干相同类型变量的集合体 组成数组的变量称为该数组的元素 数组属于构造类型 数组 03 34 56 4 106 一维数组的声明与引用 一维数组的声明类型说明符数组名 常量表达式 例如 inta 10 表示a为整型数组 有10个元素 a 0 a 9 引用必须先声明 后使用 只能逐个引用数组元素 而不能一次引用整个数组例如 a 0 a 5 a 7 a 2 3 数组 03 34 56 5 106 例1一维数组的声明与引用 includeusingnamespacestd intmain intA 10 B 10 inti for i 0 i 10 i A i i 2 1 B 10 i 1 A i for i 0 i 10 i cout A i A i cout B i B i endl 03 34 56 6 106 一维数组的存储顺序 数组元素在内存中顺次存放 它们的地址是连续的 例如 具有10个元素的数组a 在内存中的存放次序如下 数组名字是数组首元素的内存地址 数组名是一个常量 不能被赋值 数组 03 34 56 7 106 一维数组的初始化 可以在编译阶段使数组得到初值 在声明数组时对数组元素赋以初值 例如 inta 10 0 1 2 3 4 5 6 7 8 9 可以只给一部分元素赋初值 例如 inta 10 0 1 2 3 4 在对全部数组元素赋初值时 可以不指定数组长度 例如 inta 1 2 3 4 5 数组 03 34 56 8 106 Fibonacci数列 Fn 其中F0 F1 1 Fn 1 Fn Fn 1 n 1 2 includeusingnamespacestd intmain inti staticintf 20 1 1 初始化第0 1个数for i 2 i 20 i f i f i 2 f i 1 求第2 19个数for i 0 i 20 i 输出 每行5个数if i 5 0 cout endl cout width 12 设置输出宽度为12cout f i 例2 用数组来处理求Fibonacci数列问题 03 34 56 9 106 例2 续 用数组来处理求Fibonacci数列问题 运行结果 11235813213455891442333776109871597258441816765 03 34 56 10 106 一维数组应用举例 循环从键盘读入若干组选择题答案 计算并输出每组答案的正确率 直到输入ctrl z为止 每组连续输入5个答案 每个答案可以是 a b c d 数组 03 34 56 11 106 includeusingnamespacestd intmain charkey a c b a d charc intques 0 numques 5 numcorrect 0 cout Enterthe numques questiontests endl while cin get c if c n if c key ques numcorrect cout elsecout 11 03 34 56 12 106 else cout Score float numcorrect numques 100 ques 0 resetvariablesnumcorrect 0 cout endl continue ques 12 03 34 56 13 106 运行结果 acbba Score60 acbad Score100 abbda Score40 bdcba Score0 13 03 34 56 14 106 二维数组的声明及引用 数据类型标识符 常量表达式1 常量表达式2 例 inta 5 3 表示a为整型二维数组 其中第一维有5个下标 0 4 第二维有3个下标 0 2 数组的元素个数为15 可以用于存放5行3列的整型数据表格 数组 存储顺序按行存放 上例中数组a的存储顺序为 二维数组的声明类型说明符数组名 常量表达式1 常量表达式2 例如 floata 3 4 引用例如 b 1 2 a 2 3 2 下标不要越界 二维数组的声明及引用 数组 15 将所有数据写在一个 内 按顺序赋值例如 inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 分行给二维数组赋初值例如 inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 可以对部分元素赋初值例如 inta 3 4 1 0 6 0 0 11 二维数组的初始化 数组 16 03 34 56 17 106 数组作为函数参数 数组元素作实参 与单个变量一样 数组名作参数 形 实参数都应是数组名 类型要一样 传送的是数组首地址 对形参数组的改变会直接影响到实参数组 数组 03 34 56 18 106 例3使用数组名作为函数参数 主函数中初始化一个矩阵并将每个元素都输出 然后调用子函数 分别计算每一行的元素之和 将和直接存放在每行的第一个元素中 返回主函数之后输出各行元素的和 数组 03 34 56 19 106 includeusingnamespacestd voidRowSum intA 4 intnrow intsum for inti 0 i nrow i sum 0 for intj 0 j 4 j sum A i j cout Sumofrow i is sum endl A i 0 sum 19 03 34 56 20 106 intmain intTable 3 4 1 2 3 4 2 3 4 5 3 4 5 6 for inti 0 i 3 i for intj 0 j 4 j cout Table i j cout endl RowSum Table 3 for inti 0 i 3 i cout Table i 0 20 03 34 56 21 106 运行结果 123423453456Sumofrow0is10Sumofrow1is14Sumofrow2is18101418 21 03 34 56 22 106 对象数组 声明 类名数组名 元素个数 访问方法 通过下标访问数组名 下标 成员名 数组 03 34 56 23 106 对象数组初始化 数组中每一个元素对象被创建时 系统都会调用类构造函数初始化该对象 通过初始化列表赋值 例 PointA 2 Point 1 2 Point 3 4 如果没有为数组元素指定显式初始值 数组元素便使用默认值初始化 调用默认构造函数 数组 03 34 56 24 106 数组元素所属类的构造函数 不声明构造函数 则采用默认构造函数 各元素对象的初值要求为相同的值时 可以声明具有默认形参值的构造函数 各元素对象的初值要求为不同的值时 需要声明带形参的构造函数 当数组中每一个对象被删除时 系统都要调用一次析构函数 数组 03 34 56 25 106 例4对象数组应用举例 Point h if defined POINT H define POINT HclassCPoint public CPoint CPoint intxx intyy CPoint voidMove intx inty intGetX returnX intGetY returnY private intX Y endif 03 34 56 26 106 Point cpp includeusingnamespacestd include Point h CPoint CPoint X Y 0 cout DefaultConstructorcalled endl CPoint CPoint intxx intyy X xx Y yy cout Constructorcalled endl CPoint CPoint cout Destructorcalled endl voidCPoint Move intx inty X x Y y 26 03 34 56 27 106 include include Point h usingnamespacestd intmain cout Enteringmain endl CPointA 2 for inti 0 i 2 i A i Move i 10 i 20 cout Exitingmain endl return0 27 03 34 56 28 106 运行结果 Enteringmain DefaultConstructorcalled DefaultConstructorcalled Exitingmain Destructorcalled Destructorcalled 28 03 34 56 29 106 关于内存地址 内存空间的访问方式通过变量名访问通过地址访问地址运算符 则 var表示变量var在内存中的起始地址 03 34 56 30 106 声明例 inti int i pointer 指向整型变量的指针 指针变量的概念 概念指针 内存地址 用于间接访问内存单元指针变量 用于存放地址的变量 引用例1 i 3 例2 i pointer 3 指针 03 34 56 31 106 指针变量的初始化 语法格式存储类型数据类型 指针名 初始地址 例 inta 0 int pa 注意事项用变量地址作为初值时 该变量必须在指针初始化之前已说明过 且变量类型应与指针类型一致 可以用一个已赋初值的指针去初始化另一个指针变量 不要用一个内部auto变量去初始化static指针 指针 03 34 56 32 106 指针变量的赋值运算 格式 指针名 地址 地址 中存放的数据类型与指针类型必须相符 向指针变量赋的值必须是地址常量或变量 不能是普通整数 但可以赋值为整数0 或NULL 表示空指针 指针的类型是它所指向变量的类型 而不是指针本身数据值的类型 任何一个指针本身的数据值都是unsignedlongint型 允许声明指向void类型的指针 该指针可以被赋予任何类型对象的地址 但不能参与任何运算 例 void general 指针 03 34 56 33 106 例5指针的声明 赋值与使用 includeusingnamespacestd intmain int i pointer 声明int型指针i pointerinti 声明int型数ii pointer 输出int型指针所指地址的内容 Theoutputlookslikethis Outputinti 10Outputintpointeri 10 03 34 56 34 106 例6void类型指针的使用 voidvObject 错 不能声明void类型的变量void pV 对 可以声明void类型的指针int pInt i intmain pV 03 34 56 35 106 指向常量的指针 不能通过指针来改变所指对象的值 但指针本身可以改变 可以指向另外的对象 示例1char pName John pName是一般指针 pName A 编译正确 运行出错示例2constchar pName John 指向常量的指针chars abc pName s 正确 pName本身的值可以改变 pName 1 编译时指出错误 指针 03 34 56 36 106 指针类型的常量 若声明指针常量 则指针本身的值不能被改变 例 char constname John name abc 错误 指针常量值不能改变 指针 03 34 56 37 106 指针变量的算术运算 指针与整数的加减运算指针p加上或减去整数n 其意义是指针当前指向位置的前方或后方第n个数据的地址 这种运算的结果值取决于指针指向的数据类型 指针加一 减一运算指向下一个或前一个数据 例如 y px 相当于y px 和 优先级相同 自右向左运算 指针 03 34 56 38 106 38 03 34 56 39 106 03 34 56 40 106 关系运算指向相同类型数据的指针之间可以进行各种关系运算 指向不同数据类型的指针 以及指针与一般整数变量之间的关系运算是无意义的 指针可以和零之间进行等于或不等于的关系运算 例如 p 0 或NULL p 0 或NULL 赋值运算向指针变量赋的值必须是地址常量或变量 不能是普通整数 但可以赋值为整数0 或NULL 表示空指针 指针变量的关系运算 指针 03 34 56 41 106 指向数组元素的指针 声明与赋值例 inta 10 pa pa 通过指针引用数组元素经过上述声明及赋值后 pa就是a 0 pa 1 就是a 1 pa i 就是a i a i pa i a i pa i 都是等效的 不能写a 因为a是数组首地址是常量 指针 03 34 56 42 106 对指向数组元素的指针允许作有限的运算 例如 int p q a 100 p 1 当两个指针指向同一个数组的元素时 这两个指针可以作关系比较 若p q表示p q指向数组的同一个元素 pq表示p所指向的数组元素的下标大于q所指向的数组元素的下标 03 34 56 43 106 2 指向数组元素的指针可与整数进行加减运算 由于数组元素在内存中顺序连续存放 因此表达式a 1为a 1 的地址 a 2为a 2 的地址 若指针p 则 p i 表示a i p i 也可写成p i 03 34 56 44 106 用数组名与指针的区别 指针变量的值可改变 例如p 数组名只代表数组首元素的指针 是不可改变的 是常量 03 34 56 45 106 inta 10 b 10 p q 利用指针遍历数组 输入数组的全部元素for p a p p 利用指针遍历数组 输出数组的全部元素for p a p 03 34 56 46 106 例7 设有一个int型数组a 有10个元素 用三种方法输出各元素 使用数组名和下标使用数组名和指针运算使用指针变量 03 34 56 47 106 intmain inta 10 inti for i 0 i a i cout endl for i 0 i 10 i cout a i 使用数组名和下标 47 03 34 56 48 106 intmain inta 10 inti for i 0 i a i cout endl for i 0 i 10 i cout a i 使用数组名指针运算 03 34 56 49 106 使用指针变量 intmain inta 10 int p i for i 0 i a i cout endl for p a p a 10 p cout p 03 34 56 50 106 指针数组 数组的元素是指针型例 Point pa 2 由pa 0 pa 1 两个指针组成 指针 03 34 56 51 106 例8利用指针数组存放单位矩阵 includeusingnamespacestd intmain intline1 1 0 0 声明数组 矩阵的第一行intline2 0 1 0 声明数组 矩阵的第二行intline3 0 0 1 声明数组 矩阵的第三行int p line 3 声明整型指针数组p line 0 line1 初始化指针数组元素p line 1 line2 p line 2 line3 指针 03 34 56 52 106 输出单位矩阵cout Matrixtest endl for inti 0 i 3 i 对指针数组元素循环 for intj 0 j 3 j 对矩阵每一行循环 cout p line i j cout endl 输出结果为 Matrixtest 1 0 00 1 00 0 1 03 34 56 53 106 例9二维数组举例 includeusingnamespacestd intmain intarray2 2 3 11 12 13 21 22 23 for inti 0 i 2 i cout array2 i endl for intj 0 j 3 j cout array2 i j 或者cout array2 i j cout endl 指针 在某次运行之后 程序的输出结果为 0X0065FDE011 12 130X0065FDEC21 22 23 03 34 56 54 106 以指针作为函数参数 以地址方式传递数据 可以用来返回函数处理结果 实参是数组名时形参可以是指针 指针与函数 03 34 56 55 106 例10 题目 读入三个浮点数 将整数部分和小数部分分别输出 includeusingnamespacestd voidsplitfloat floatx int intpart float fracpart 形参intpart fracpart是指针 intpart int x 取x的整数部分 fracpart x intpart 取x的小数部分 指针与函数 03 34 56 56 106 intmain inti n floatx f cout x splitfloat x 56 03 34 56 57 106 运行结果 Enterthree 3 floatingpointnumbers4 7IntegerPartis4FractionPartis0 78 913IntegerPartis8FractionPartis0 913 4 7518IntegerPartis 4FractionPartis 0 7518 57 03 34 56 58 106 例11 输出数组元素的内容和地址 include includeusingnamespacestd voidArray Ptr long P intn inti cout Infunc addressofarrayis unsignedlong P endl cout Accessingarrayinthefunctionusingpointers endl for i 0 i n i cout Addressforindex i is unsignedlong P i cout Valueis P i endl 指针与函数 03 34 56 59 106 intmain longlist 5 50 60 70 80 90 cout Inmain addressofarrayis unsignedlong list endl cout endl Array Ptr list 5 03 34 56 60 106 运行结果 Inmain addressofarrayis6684132Infunc addressofarrayis6684132AccessingarrayinthefunctionusingpointersAddressforindex0is6684132Valueis50Addressforindex1is6684136Valueis60Addressforindex2is6684140Valueis70Addressforindex3is6684144Valueis80Addressforindex4is6684148Valueis90 60 03 34 56 61 106 指向常量的指针做形参 includeusingnamespacestd constintN 6 voidprint constint p intn intmain intarray N for inti 0 i array i print array N 指针 03 34 56 62 106 voidprint constint p intn cout p for inti 1 i n i cout p i cout endl 62 03 34 56 63 106 指针型函数 当函数的返回值是地址时 该函数就是指针形函数 声明形式 存储类型数据类型 函数名 指针与函数 03 34 56 64 106 声明形式 存储类型数据类型 函数指针名 含义 数据指针指向数据存储区 而函数指针指向的是程序代码存储区 指向函数的指针 指针与函数 03 34 56 65 106 例11函数指针 includeusingnamespacestd voidprint stuff floatdata to ignore voidprint message floatlist this data voidprint float floatdata to print void function pointer float intmain floatpi float 3 14159 floattwo pi float 2 0 pi 指针与函数 03 34 56 66 106 print stuff pi function pointer print stuff function pointer pi function pointer print message function pointer two pi function pointer 13 0 function pointer print float function pointer pi print float pi 66 03 34 56 67 106 voidprint stuff floatdata to ignore cout Thisistheprintstufffunction n voidprint message floatlist this data cout Thedatatobelistedis list this data endl voidprint float floatdata to print cout Thedatatobeprintedis data to print endl 67 03 34 56 68 106 运行结果 Thisistheprintstufffunction Thisistheprintstufffunction Thedatatobelistedis6 283180Thedatatobelistedis13 000000Thedatatobeprintedis3 141590Thedatatobeprintedis3 141590 68 03 34 56 69 106 对象指针的一般概念 声明形式类名 对象指针名 例 PointA 5 10 Piont ptr ptr 指针 03 34 56 70 106 对象指针应用举例 intmain PointA 5 10 Point ptr ptr 指针 03 34 56 71 106 曾经出现过的错误例子 classFred 前向引用声明classBarney Fredx 错误 类Fred的声明尚不完善 classFred Barneyy 指针 03 34 56 72 106 正确的程序 classFred 前向引用声明classBarney Fred x classFred Barneyy 指针 03 34 56 73 106 this指针 隐含于每一个类的成员函数中的特殊指针 明确地指出了成员函数当前所操作的数据所属的对象 当通过一个对象调用成员函数时 系统先将该对象的地址赋给this指针 然后调用成员函数 成员函数对对象的数据成员进行操作时 就隐含使用了this指针 指针 03 34 56 74 106 this指针 例如 Point类的构造函数体中的语句 X xx Y yy 相当于 this X xx this Y yy 指针 03 34 56 75 106 指向类的非静态成员的指针 通过指向成员的指针只能访问公有成员声明指向成员的指针声明指向公有数据成员的指针类型说明符类名 指针名 声明指向公有函数成员的指针类型说明符 类名 指针名 参数表 指针 03 34 56 76 106 指向类的非静态成员的指针 指向数据成员的指针说明指针应该指向哪个成员指针名 类名 数据成员名 通过对象名 或对象指针 与成员指针结合来访问数据成员对象名 类成员指针名或 对象指针名 类成员指针名 指针 03 34 56 77 106 指向类的非静态成员的指针 指向函数成员的指针初始化指针名 类名 函数成员名 通过对象名 或对象指针 与成员指针结合来访问函数成员 对象名 类成员指针名 参数表 或 对象指针名 类成员指针名 参数表 指针 03 34 56 78 106 指向类的非静态成员的指针 例13访问对象的公有成员函数的不同方式intmain 主函数 PointA 4 5 声明对象APoint p1 指针 03 34 56 79 106 指向类的静态成员的指针 对类的静态成员的访问不依赖于对象可以用普通的指针来指向和访问静态成员例14通过指针访问类的静态数据成员例15通过指针访问类的静态函数成员 指针 03 34 56 80 106 例14通过指针访问类的静态数据成员 includeusingnamespacestd classPoint Point类声明 public 外部接口 公有数据成员 Point intxx 0 intyy 0 X xx Y yy countP 构造函数Point Point 静态数据成员定义性说明 03 34 56 81 106 intmain 主函数 声明一个int型指针 指向类的静态成员int count 81 03 34 56 82 106 例15通过指针访问类的静态函数成员 includeusingnamespacestd classPoint Point类声明 public 外部接口 公有数据成员 其它函数略staticvoidGetC 静态函数成员 cout Objectid countP endl private 私有数据成员intX Y staticintcountP 静态数据成员引用性说明 函数实现略intPoint countP 0 静态数据成员定义性说明 03 34 56 83 106 intmain 主函数 指向函数的指针 指向类的静态成员函数void gc Point GetC PointA 4 5 声明对象Acout PointA A GetX A GetY gc 输出对象序号 通过指针访问静态函数成员PointB A 声明对象Bcout PointB B GetX B GetY gc 输出对象序号 通过指针访问静态函数成员 83 03 34 56 84 106 引用的概念 引用 为一个变量 函数等对象规定一个别名 该别名称为引用 此后 对别名的操作即是对别名所代表的对象的操作 即引用变量创建了变量和对象的别名 引用虽是一种类型 但不是值 只能用它标识另一个对象 从理论意义上说 引用是一种映射 把一个标识符映射到一个对象 从直观意义上说 引用是用一个标识符给一个对象起了一个别名 引用标识对象 就是用一个别名标识对象 引用 03 34 56 85 106 引用的创建 声明 创建 声明 引用 创建引用与定义指针类似 只不过将 换成 引用 03 34 56 86 106 引用的初始化 引用若不是作为函数参数的 则必须初始化 PITA 并且必须引用某个 真实 的变量或对象 否则发生编译错误 方法 一般使用相同类型的变量来初始化 例 intsomeVar 1 int引用总是作为目标的别名使用 也就是说 引用一旦初始化 它就维系在所代表的对象上 再也分不开 任何对该引用的赋值 都是对引用所维系目标赋值 而不是将引用维系到另一目标上 即一旦引用变量被声明并初始化 在引用的作用域内 不能再作为其他对象的引用 别名 如果引用在函数声明中用作形参 则初始化会自动完成 因为在每次调用函数时都会初始化引用 当函数终止时 堆栈中的引用会自动超出作用域 引用 03 34 56 87 106 能够引用的数据类型 1 简单数据类型的变量或常量的引用例 int 引用 03 34 56 88 106 能够引用的数据类型 3 指针变量或常量的引用例 int pInt newint int 引用 03 34 56 89 106 创建对数组的引用 可以创建对数组的引用 例 intconstdimension 5 doublearray1 dimension 0 0 double 引用 03 34 56 90 106 使用const限定引用 1 用const限定引用时表示不能通过引用改变被引用的空间的值 例 inti constint 正确3 没有 常量引用 即没有 数据类型 const引用名 03 34 56 91 106 内存的5个区域 通常程序员处理内存的5个区域 全局命名空间堆寄存器代码空间堆栈局部变量和函数参数在堆栈中 代码在代码空间中 全局变量在全局命名空间中 寄存器用于内部的内务处理函数 剩下的几乎全部内存交给堆 堆又叫做自由存储 03 34 56 92 106 由函数返回引用 1 左值与右值 以下文字是摘自 C Primer3rdEdition 变量和文字常量都有存储区 并且有相关的类型 区别在于变量是可寻址的 addressable 对于每一个变量都有两个值与其相关联 1 它的数据值 存储在某个内存地址中 有时这个值也被称为对象的右值 rvalue 读作are value 我们也可认为右值的意思是被读取的值 readvalue 文字常量和变量都可被用作右值 2 它的地址值 即存储数据值的那块内存的地址 它有时被称为变量的左值 lvalue 读作ell value 我们也可认为左值的意思是位置值locationvalue 文字常量不能被用作左值 03 34 56 93 106 由函数返回引用 在下面的表达式中 ch ch O 变量ch同时出现在赋值操作符的左边和右边 右边的实例被读取 与其相关联的内存中的数据值被读出 左边的ch用作写入 减操作的结果被存储在ch的位置值所指向的内存区中 原来的数据值会被覆盖 在表达式的右边 ch和文字字符常量用作右值 在左边 ch用作左值 03 34 56 94 106 由函数返回引用 2 函数可以通过引用来返回变量 可以使用或不使用const限定符 如果不使用const限定符 函数返回可修改的左值 3 当按引用返回函数值的时候 确保没有引用作用域外的对象 如局部 自动 变量 03 34 56 95 106 何时不需要使用引用 如果被调用的函数认为基本类型是 只读 即被调函数不修改实参的值 的时候 使用值传递参数的方式比较好 而不需要使用引用方式的地址传递参数 03 34 56 96 106 指针与引用的优劣 1 指针是个变量 可以把它再赋值成其它的地址 水性杨花 然而建立引用时必须进行初始化并且决不会再指向其他不同的变量 从一而终 2 有空指针 无空引用 3 由于指针也是变量 所以可以有指针变量的引用 例 int a int p是a的一个别名 是一个指针 03 34 56 97 106 指针与引用的优劣 4 引用本身不是一种数据类型 所以没有引用的引用 也没有引用的指针 例 inta int 错 企图定义一个引用的指针由 于指针也是变量 所以可以有指 针变量的引用5 引用

温馨提示

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

评论

0/150

提交评论