《指针与字符串》PPT课件.ppt_第1页
《指针与字符串》PPT课件.ppt_第2页
《指针与字符串》PPT课件.ppt_第3页
《指针与字符串》PPT课件.ppt_第4页
《指针与字符串》PPT课件.ppt_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

高级语言程序设计 授课教师 电话 邮箱 授课班级 电子商务2009级 第6章指针与字符串 6 1指针的概念6 2指针型变量6 3指针与数组6 4指针与函数6 5指针与类 对象6 7动态内存分配与new和delete运算符6 8string类 第6章指针与字符串 C 语言拥有在运行时获得变量地址和操纵地址的能力 这种可用来操纵地址的变量类型就是指针 指针可以用于数组 内存的访问 还可作为函数的参数 6 1指针的概念 指针是变量 是用来专门存放内存地址的变量 为了说清楚指针变量 先讨论对变量的访问 存取 方式 按变量的地址直接存取变量的方法称为 直接访问 方式 存贮变量的内存空间的首地址称为该变量的地址 如果将一个变量的地址放在另一个变量中 则存放地址的变量称为指针 pointer 型变量 这样存取变量 也可以间接的由指针变量取得该变量的地址进行 称为 间接访问 方式 由于指针变量中的值是另一个变量的地址 我们习惯上形象地称指针变量指向该变量 指针变量中的值也简称为指针 所以指针就是地址 设a是整型变量 其值为5 其分配的内存地址为1000H H是16进制后缀 汇编语言表示方式 又设pa是整型指针变量 其值为1000H 可以说指针pa指向变量a 6 2指针型变量 1 如何定义指针指针类型变量定义格式如下 存贮类型指向类型 变量名 变量名 这里 是一个定义变量为指针的说明符 而不是指针变量的一部分 更不是乘号 inta 5 pa a定义为整型变量 pa定义为整型变量指针double p p定义为双精度实型变量指针char p3 p3定义为字符型变量指针int p4 5 p4定义为一维数组的指针 指向的数组有5个元素int p6 p6定义为一个整型变量指针的指针 即p6的值是一个指针型变量的地址 那个指针变量指向一个整型变量 换句话说 p6是一个二级指针变量 2 指针的赋值 为了给指针赋值 C 中提供了一个取变量地址运算符 赋给p3的值为数组b的首地址 实际上p2 p3的值一样 指针变量必须先赋值再使用 对指针变量决不可任意赋一个非负整数 指针变量中存放的是在内存中可寻址的变量或对象的首地址 而变量或对象的内存地址是由系统分配的 程序员不能代替系统给变量分配内存 系统不允许给指针变量随意赋一个地址值 只能取系统分配的变量地址赋给指针变量 2 指针的赋值 指针赋值注意事项 指针值是地址 指针只能指向定义时规定的类型如有定义 int p doublex 则赋值语句 p p1的值是a的地址 p1的值又赋给p2 暂时不用的指针可赋值为0 表示空指针 这表示当前该指针并不指向该类型的任何一个变量 对象 并不是指向地址为0的内存空间 3 指针的运算 使用指针变量可以间接访问指针指向的单元 如有定义 inta p 其中运算符 称为间接引用 dereference 运算符 作用于一个指针类型的变量 访问该指针所指向的内存数据 实际上例中的a与 p完全是一回事 指针的运算共有4类 赋值运算 包括一个指针赋给另一个指针 同类型表达式的值赋给指针指向的变量 指针加减整数 实际加减的是指向类型长度的整数倍 同类型指针相减同类型指针比较 补充例1 逆序输出字符串 includeintstrlen1 char voidmain chars abcdefg char p intn strlen1 s 声明调用后面定义的函数for p s n 1 p 1 s p cout p cout endl intstrlen1 chara 计算给定字符串的字符个数 字符串长度 char p a inti 0 while a i 0 p 移动指针 使其指到串结束标志returnp a 两个地址相减 结果为串长度 补充例2 指针运算例子 includevoidmain inti 6 pi1 与指针有关的基本运算符有以下两个 1 变量名 为取地址运算符 用来获取变量的首地址 2 指针变量名 为指向运算符 用来获取指针变量所指向变量的值 和 运算符都是单目运算符 其优先级高于所有双目运算符 采用从右到左的结合性 6 3指针与数组 6 3 1指针与数组的关系数组是由同一类型元素组成的一个有序集合 如 inta 5 5 8 13 21 34 该数组在系统编译时分配连续的存储空间 数组名a就是这连续空间的首地址 因此可以将数组名当作地址值 指针 看待 即数组名是常量 是一个指针值 如再定义 int p 则下述有关指针的运算是合法的 p a p p p 3 p a 2 下述有关指针的运算是非法的 a a a 3 a p 2 原因在于p是变量 a是常量 1 一维数组元素的指针表示假设已有定义 inta 5 p a 则a i 数组中的第i 1个元素 有以下4种表示方法 a i p i a i p i 前两种称为数组表示法 后两种称为指针表示法 C 中指针表示比数组表示效率高 需要提高运行效率时 仅可能使用指针表示方法 上述表示中 数组名与指针名在使用方式上没有区别 但要注意 指针的值可以改变 数组名代表的值是不可以改变的 6 3 2用指针表示数组元素 例6 3 用指针的方法编写求一个数组中所有元素之和的程序 includeintSum int pPointer intn intnSum 0 while n 0 nSum pPointer pPointer n returnnSum voidmain intpnArray 10 6 7 8 9 5 4 3 2 10 1 intsumArray sumArray Sum pnArray 10 cout 数组各元素和 sum1 sumArray endl 2 二维数组元素的指针表示 二维数组元素在内存中实际上是按照行优先的规定以一维 线性 的形式存储的 如 inta 3 4 在内存中存储顺序为 a 0 0 a 0 1 a 0 2 a 0 3 a 1 0 a 1 1 a 1 2 a 1 3 a 2 0 a 2 1 a 2 2 a 2 3 等12个元素是线性排列的 二维数组a呈现在用户面前的是3行4列的矩阵 是二维形式 因此对二维数组元素的指针表示有两种方式 一级指针表示和二级指针表示 上述数组元素a i j i 0 1 2j 0 1 2 3 的一级指针表示为 a 0 0 4 i j 其中 a 0 0 表示首地址二级指针表示为 a i j 其中a i表示第i行的首地址 a a 1 a 2 从二维数组的角度来看 a代表整个二维数组的首地址 也就是第0行的首地址 a 1代表第1行的首地址 因此a 1的含义是a 1 的地址 a 0 a 1 a 2 既然是一维数组名 而C 又规定了数组名代表数组的首地址 因此a 0 代表第0行一维数组中第0列元素的地址 即 a 0 0 a 1 的值是 a 1 0 a 2 的值是 a 2 0 第0行第1列元素地址怎么表示 用a 0 1表示 即 a 0 1 由于a i 和 a i 等价 因此a 0 1和 a 0 1的值都是 a 0 1 请记住 二维数组名 如a 是指向行的 一维数组名是指向列元素的 在行指针前面加一个 就转换为列指针 在列指针前面加一个 就成为行指针 补充例3 阅读程序 注意数组元素的表示方法 includeinta 2 3 1 3 5 7 9 11 voidmain cout a a a endl cout a 0 指针可以指向数组元素 也可以指向数组 1 指向数组元素的指针指向数组元素的指针是一级指针 如定义数组 指针 inta 10 b 3 5 int p1 p2 p3 则下述赋值是正确的 p1 是错误的 因为b是二维数组名 相当于二级指针 而p2是一级指针 因此是错误的 6 3 3指向数组的指针 补充例4 阅读程序 includeintm 3 12 10 8 6 4 2 voidmain int p p为一级指针 m为二维数组 但m在内存中实际是一维存储的 可用一级指针表示 指针p初始化为指向数组的最后一个元素 m 1 2 由于 的级别高于 故 p 相当于 p 而不是 p p 表示先取出指针p指向变量的值 再将指针的值加1 将程序中的 p 改为 p 运行程序试一试 例6 5 用指针的方法将二维数组的转置 行列互换 形式输出 并输出相应的指针值 进行观察 比较 includevoidmain intaMatrix 3 4 1 2 3 4 5 6 7 8 9 10 11 12 inti j p cout 转置前的矩阵 endl for i 0 i 3 i p aMatrix i p存放各行的起始地址for j 0 j 4 j cout p j cout endl cout 转置后的矩阵 endl for j 0 j 4 j for i 0 i 3 i p aMatrix i p存放各行的起始地址 注意所在的位置 cout p j cout endl cout 输出相应的指针值 endl cout aMatrix aMatrix 0 2 指向一维数组的指针 指向一维数组的指针实际上是二级指针 指向二维数组的指针实际上是三级指针等等 一维数组指针的定义格式为 数组元素类型名 数组指针名 数组元素个数 注意 定义时的 不可少 因为 的级别高于 补充例 阅读程序 includeinta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 voidmain int p 4 p a 1 cout p 0 0 p 1 2 p 1 3 p 1 2 endl 阅读程序时 将二级指针p当作二维数组名a看待 但要注意p的初始位置 6 3 4指针数组 前述的数组指针是指针 他指向一个数组 而指针数组是数组 其元素是指针 一维一级指针数组定义方式为 指针指向类型 数组名 元素个数 其中的元素个数也是数组中的指针个数例 int a 5 就定义了一个5个元素的数组 其中每个元素都是一个整型指针 注意 int a 5 定义的是一个指针 二级 指向一个5个整数构成的一个一维数组 6 4指针与函数 6 4 1指针变量作为函数参数指针类型也可以作为函数的参数 通过指针型参数 可以将一个变量的地址传递给函数 而通过这个地址 函数体中的语句就可以修改函数以外的变量的值 例6 7 通过函数调用交换两个变量的值 includevoidchangFunction int int voidmain inta 5 b 10 cout 函数调用前 a a b b endl changFunction 6 4 2指向函数的指针1 指向函数指针变量的定义与使用在C 语言中 函数的调用实际上是通过指针来完成的 函数的指针是一个函数在内存中的入口地址 函数名实际上就是一个指针 它指向函数的入口 定义一个指针变量 并赋予它函数名 这样的指针变量称为指向函数的指针变量 简称函数指针变量 我们就可以通过函数指针变量来调用它所指向的函数 声明一个函数指针变量的形式如下 函数指针变量名 参数表 注意 定义中的两对圆括号都不要遗漏 数据类型是函数指针变量所指函数的返回值的数据类型 例如 若定义函数voidFunctionA intm intn 则对应于函数FunctionA的指针型变量可以按如下方法声明 void pFPointer int int 用已经定义的函数指针变量来调用函数 分两步进行 第一步 将函数名赋给已定义的函数指针变量 采用的格式为函数指针变量名 函数名pFpointer FunctionA 第二步 使用函数指针变量调用它所指的函数 采用的格式为 函数指针变量名 实参表 或函数指针变量名 实参表 FunctionA 3 4 等价于 pFPointer 3 4 或pFPointer 3 4 2 函数指针变量作为函数的参数函数指针变量的一个主要用途是在函数调用时把函数指针变量作为参数 也就是说传递的不是数值 而是函数的入口地址 目的是实现对若干个不同函数的灵活调用 具体编程时要注意的是 主调函数的实参应设置成将被调用的函数名 被调函数的相应形参应设置成接受同类型函数入口地址的函数指针变量 例6 9 将函数指针变量作为函数参数例题 includeintadd intx inty returnx y intsub intx inty returnx y intfunct int fun int int intx inty intresult result fun x y 等价于result fun x y returnresult voidmain inta 5 b 10 cin a b cout a b funct add a b endl cout a b funct sub a b endl 6 4 3指针作为函数的返回类型函数的返回值是地址的函数称为指针函数 其定义的一般形式如下 函数名 形参表 函数体 int ip int fFun1 intx returnip 补充例 有若干个学生的成绩 每个学生有4门课程 要求在用户输入学生序号以后 能输出该学生的全部成绩 用指针函数来实现 voidmain floatscore 4 60 70 80 90 56 89 67 88 34 78 90 66 float search float p0int 4 intn float p inti m cout m cout TherscoresofNo m are p search score m for i 0 i 4 i cout setw 4 p i cout endl float search float point 4 intn float pt pt point n return pt 6 5指针与类 对象 1 类的指针变量类的指针变量是一个用于保存该类对象在内存中存储空间首地址的指针型变量 同普通数据类型的指针变量有相同的性质 声明一个类的指针变量的语法如下 指针变量名 2 对象的指针对象的指针指的是一个对象在内存中的首地址 取得一个对象在内存中首地址的方法同取得变量在内存中首地址的方法一样 都是通过取地址运算符 表示表达式 Stu1是取得对象Stu1内存中的首地址 其值的类型是CStudent 同类指针pStu就指向对象Stu1在内存中的首地址 已知一个对象的指针 访问该对象中成员的方法有两种 指针变量名 成员名或指针变量名 成员名CStudentStu1 Cstudent pStu 都是合法表达式 3 this指针this指针是每个对象中隐藏的指针 this指针是默认的 当一个对象生成后 这个对象的this指针就指向内存中保存该对象数据的存储空间的首地址 this指针对一个对象来说是系统自动生成的 主要用于在成员函数中需要把对象本身作为参数传递给另一个函数 例6 11 this指针的作用例题 includeclassThisSample intn public ThisSample ThisSample intm n m voidaddvalue intm ThisSampleq q n n m 此处n相当于this n this q 将临时对象q的值传回调用对象 voiddisp cout n n endl voidmain ThisSamples 10 s disp s addvalue 5 相当于函数调用 addvalue 6 6指针与字符串 6 6 1字符串指针在C 语言中 字符串是以 0 为结束标志的字符序列 是以字符数组的形式进行存储与处理的 而数组与指针又紧密相连 数组名就保存着字符串在内存的起始地址 因此 字符串实质上与char 型指针相对应 char 型指针变量可以在定义时进行初始化 其形式为char 指针变量名 字符串 例如 char myString Thisisastring char 型的指针变量 或函数参数 既可以用于接收字符串常量 也可以接收字符型数组 例如 charpString IloveChina char myString Thisisastring myString pString 例6 12 字符串的复制 includevoidcopy string char from char to 复制函数 for from 0 from to to from to 0 赋值字符串结束标识 voidmain charpSource Iamateacher charpDestination youareastudent pDestination字符串长度 pSource字符串长度copy string pSource pDestination cout pSource endl cout pDestination endl 6 6 2字符串标准库函数实际上 C 提供了许多操作字符串数据的标准库函数 如比较字符串 搜索字符串中的字符 确定字符串长度等 我们在程序设计时可直接引用 注意 使用字符串处理库中的函数应在程序的开头添加包含 string h 头文件的预处理命令 include 例6 13 例6 12字符串的复制可以直接用C 的标准库函数strcpy 来实现 include includevoidmain charpSource Iamateacher charpDestination youareastudent pDestination字符串长度 pSource字符串长度strcpy pDestination pSource 等价于strncpy pDestination pSource 19 cout pSource endl cout pDestination endl 6 7动态内存分配与new和delete运算符 动态内存分配是相对于静态内存分配而言的 静态内存分配是指在编译阶段就分配好存储单元空间 这些空间的大小在程序运行过程中是不可更改的 如变量 数组等 动态内存分配则是指程序员在程序语句中通过调用内存分配函数或使用内存分配运算符取得存储空间 通过动态内存分配得到的空间的大小 编译器是不知道的 完全由动态运行中的程序的当时情况决定 6 7 1new运算符new运算符用于动态分配一块内存空间 new运算符的使用形式如下 指针变量 new 长度 例如 char CBuffer newchar 256 分配一个可以容纳256个char型数据的空间 说明 如果分配的空间长度为1个单位 则可以省略new运算符格式中的中括号和中括号中的整数 使用new运算符分配内存空间时 其空间长度可以是变量 也可以是数值表达式 例如 intnSize 5 int nPInt newint nSize 5 由new分配的内存空间是连续的 可以通过指针的变化访问所分配空间的每一个元素 如 int nPInt newint 10 nPInt 5 100 或 nPInt 5 100 如果当前存储器无足够的内存空间可分配 则new运算符返回0 NULL 例6 14 改写字符串复制函数 要求能通过源字符串的大小动态分配目的字符串的存储空间 并返回所分配空间的首地址 includechar toDest char copy string char from 复制函数 intnSize 1 while from nSize 0 求源字符串的长度并加1 注意nSize的初值赋1的作用 nSize char to newchar nSize 定义目的字符串并申请分配内存空间toDest to 用非函数局部变量保存空间首地址if to NULL 申请内存空间成功 for from 0 from to to from to 0 赋值字符串结束标识 returntoDest voidmain charpSource Iamateacher char pDest pDest copy string pSource if pDest NULL cout 源字符串 pSource endl cout 目的字符串 pDest endl elsecout 无内存空间进行复制操作 endl 6 7 2delete运算符由new运算符分配的内存空间在使用完毕后 应该使用delete运算符释放 delete运算符的使用有两种形式 delete指针及delete 指针 int pInt newint deletepInt int pManyInt newint 10 delete pManyInt 说明 用new运算符获得的内存空间 只许使用一次delete 不允许多次对同一块空间进行多次释放 否则将会产生严重错误 delete只能用来释放由new运算符分配的动态内存空间 对于程序中的变量 数组的存储空间 不得使用delete运算符去释放 6 8string类 在处理字符串方面 C 还提供了标准的模板类 string类 我们用string类将字符串定义为对象 然后利用string类提供的赋值 连接 复制 查找 交换等字符串操作功能 即可方便地实现对字符串的各种处理 与字符数组和字符指针处理字符串不同的是 string不一定要用 0 来标识字符串的结束 下标运算符 也可以用于访问字符串中的各个字符 由于string类的结构比较复杂 在此主要就其基本特点与用法进行介绍并举例加以说明 关于更多 更详细的内容 请读者自行参阅有关资料 1 string类对象的定义与初始化形式1 string对象名 字符串 或string对象名 字符串 形式2 string对象名 n 字符 生成由n个 字符 组成的字符串 2 string类对象的操作string类对象的操作 即实现对字符串进行赋值 连接 复制 查找 交换等功能 主要通过string类对象的成员函数调用与重载运算符 例如 strings1 Hello intlen s1 len

温馨提示

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

评论

0/150

提交评论