计算机二C语言程序设计第.ppt_第1页
计算机二C语言程序设计第.ppt_第2页
计算机二C语言程序设计第.ppt_第3页
计算机二C语言程序设计第.ppt_第4页
计算机二C语言程序设计第.ppt_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

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

文档简介

第9讲指针 指针是 语言中的重要概念 也是 语言的重要特色 使用指针 可以使程序更加简洁 紧凑 高效 9 1指针和指针变量的概念9 2指针变量的定义与应用9 3数组的指针和指向数组的指针变量9 4字符串的指针和指向字符串的指针变量9 5返回指针值的函数9 6指针数组与主函数main 的形参9 7函数的指针和指向函数的指针变量 9 1指针和指针变量的概念 1 内存地址 内存中存储单元的编号1 计算机硬件系统的内存储器中 拥有大量的存储单元 容量为 字节 为了方便管理 必须为每一个存储单元编号 这个编号就是存储单元的 地址 每个存储单元都有一个惟一的地址 2 在地址所标识的存储单元中存放数据 注意 内存单元的地址与内存单元中的数据是两个完全不同的概念 例 inta a 12 变量a内的 内容 变量值 是12 变量值可由键盘等方法录入a变量的地址 a 是3000 变量的地址 a是编译时系统统一编码赋予的 2 变量地址 系统分配给变量的内存单元的起始地址假设有这样一个程序 main intnum scanf d 时 存取变量num值的方式可以有两种 1 直接访问 直接利用变量的地址进行存取1 上例中scanf d num 的执行过程是这样的 用变量名num作为索引值 检索符号表 找到变量num的起始地址3000 然后将键盘输入的值 假设为12 送到内存单元3000至3003中 此时 变量num在内存中的地址和值 如图9 1所示 2 printf num d n num 的执行过程 与scanf 很相似 首先找到变量num的起始地址3000 然后从3000至3003中取出其值 最后将它输出 2 间接访问 通过另一变量访问该变量的值 语言规定 在程序中可以定义一种特殊的变量 称为指针变量 用来存放其它变量的地址 例如 假设定义了这样一个指针变量p 它被分配到4000至4003单元 其值可通过赋值语句 p num 得到 此时 指针变量p的值就是变量num在内存中的起始地址3000 如图9 2所示 见下一页 通过指针变量p存取变量num值的过程如下 首先找到指针变量p的地址 4000 取出其值3000 正好是变量num的起始地址 然后从3000至3003中取出变量num的值 3 3 两种访问方式的比较两种访问方式之间的关系 可以用某人甲 系统 要找某人乙 变量 来类比 一种情况是 甲知道乙在何处 直接去找乙就是 即直接访问 另一种情况是 甲不知道乙在哪 但丙 指针变量 知道 此时甲可以这么做 先找丙 从丙处获得乙的地址 然后再找乙 即间接访问 main intnum 12 int p p是专门用于存放其他变量 num 地址的变量 存放整型变量地址 p p num的首地址是3000 将num地址装入了指针变量p 40004003 3000 12 p num 30003003图9 2 p num的首地址是3000p指向了 首地址为3000 变量num 4 指针与指针变量 1 指针 即地址 指针变量的值 称为指针 这个值是其他变量的地址 一个变量的地址称为该变量的指针 通过变量的指针能够找到该变量 2 指针变量 专门用于存储其它变量地址的变量指针变量p的值就是变量num的地址 指针与指针变量的区别 关系 就是变量值与变量 名 的区别 关系 3 为表示指针变量和它指向的变量之间的关系 用指针运算符 表示 例如 指针变量p与它所指向的变量num的关系 在上例中 表示为 p 即 p等价于变量num 而p等价于变量 将3赋给指针变量p所指向的变量 Return 指针变量的概念与小结 指针 变量a的地址 称为变量a的指针 即1 对指针变量 定义语句中各符号的说明类型符号 说明p是指针变量基类型符号int 说明p存储整型变量的地址 基类型 用于指针运算时的步长单位 稍后可见 变量名 p 不要用 P 作变量名 符号 只是类型说明 2 对指针变量 引用语句中各符号的说明常用运算符号 printf d p 引用 3 对于指针变量的符号 出现在不同位置 其作用不同 1 定义中 说明所定义的变量是指针变量 2 引用中 是指针运算符 取指针变量指向的变量的数值 9 2指针变量的定义与应用 9 2 1指针变量的定义与相关运算 案例9 1 指针变量的定义与相关运算示例 案例代码文件名 AL9 1 C includemain intnum int 12 p int 定义一个指向int型数据的指针变量p int floatnum f 3 14 p f 定义一个指向float型数据的指针变量p f charnum ch p p ch 定义一个指向char型数据的指针变量p ch p int AL9 1 C 程序演示 3000 12 p int p int 30003003图9 2 num int 40004003 程序运行结果 num int 12 p int 12num f 3 14 p f 3 14num ch p p ch p程序说明 1 头三行的变量定义语句 指针变量的定义与一般变量的定义相比 除变量名前多了一个星号 指针变量的定义标识符 外 其余一样 基 数据 类型 指针变量 指针变量2 注意 此时的指针变量p int p f p ch 并未指向某个具体的变量 称指针是悬空的 使用悬空指针很容易破坏系统 导致系统瘫痪 2 中间三行的赋值语句 取地址运算 取地址运算的格式 变量例如 num int num f num ch的结果 分别为变量num int num f num ch的地址 注意 指针变量只能存放指针 地址 且只能是相同类型变量的地址 例如 指针变量p int p f p ch 只能分别接收int型 float型 char型变量的地址 否则出错 3 后三行的输出语句 指针运算 使用直接访问和间接访问两种方式 分别输出变量num int num f num ch的值 注意 这三行出现在指针变量前的星号 是指针运算符 访问指针变量所指向的变量的值 而非指针定义标识符 理解 如果已定义point1是指向变量a的指针变量 inta 12 point1 point1 3 point1 即a point1 等价 point1 案例9 2 使用指针变量求解 输入2个整数 按升序 从小到大排序 输出 案例代码文件名 AL9 2 C main intnum1 num2 int num1 p AL9 2 C 程序演示 程序运行情况 Inputthefirstnumber 9 Inputthesecondnumber 6 num1 9 num2 6min 6 max 9num1 9 num2 6程序说明 1 第5行的if语句如果 num1 p num2 p 即num1 num2 则交换指针 使num1 p指向变量num2 较小值 num2 p指向变量num1 较大值 2 printf min d max d n num1 p num2 p 语句 通过指针变量 间接访问变量的值 9 2 2指针变量作函数参数1 指针变量 既可以作为函数的形参 也可以作函数的实参 2 指针变量作实参时 与普通变量一样 也是 值传递 即将指针变量的值 一个地址 传递给被调用函数的形参 必须是一个指针变量 注意 被调用函数不能改变实参指针变量的值 但可以改变实参指针变量所指向的变量的值 案例9 3 使用函数调用方式改写 案例9 2 要求实参为指针变量 案例代码文件名 AL9 3 C exchange 功能 交换2个形参指针变量所指向的变量的值 形参 2个 均为指向整型数据的指针变量 返回值 无 voidexchange int pointer1 int pointer2 inttemp temp pointer1 pointer1 pointer2 pointer2 temp 主函数main main intnum1 num2 int num1 p AL9 3 C 程序演示 案例9 3 与 案例9 2 的主要区别是通过函数exchange 的调用 交换2个形参指针变量所指向的变量的值 功能 在函数exchange 的调用中 实参把地址传给形参 形参指针变量所指向的 变量 存储单元地址与实参指针变量所指向的 变量 存储单元地址是同一单元 其效果是 交换2个形参指针变量所指向的变量的值 实参指针变量所指向的变量的值也随之交换 原因是 实参 形参指向的是同一地址单元 num2 p num2 pointer2 num2 num2 6 num1 p num1 pointer1 num1 num1 8 函数的调用时 把实参指针变量的值 地址 传给了形参指针变量 形 实二者指向的是同一地址单元 图9 5 调用函数exchange 之前 之时 结束时和结束后的情况 如图所示 见前一页 形参指针变量pointer1 指向变量num1 和pointer2 指向变量num2 在函数调用开始时才分配存储空间 函数调用结束后立即被释放 虽然被调用函数不能改变实参指针变量的值 但可以改变它们所指向的变量的值 9 3数组的指针和指向数组的指针变量 9 3 1概述1 概念数组的指针 数组在内存中的起始地址 数组元素的指针 数组元素在内存中的起始地址 2 指向数组的指针变量的定义指向数组的指针变量的定义 与指向普通变量的指针变量的定义方法一样 例如 intarray 10 pointer array 或注意 数组名代表数组在内存中的起始地址 与第1个元素的地址相同 所以可以用数组名给指针变量赋值 3 数组元素的引用数组元素的引用 既可用下标法 也可用指针法 使用下标法 直观 而使用指针法 能使目标程序占用内存少 运行速度快 9 3 2通过指针引用数组元素如果有 inta 10 p a 则 1 p i和a i都是数组元素a i 的地址 如图9 6 见下一页 所示 实际地址为p i d d为每个数组元素所占的字节数 2 p i 和 a i 就是数组元素a i 实际上 在编译时 对数组元素a i 就是处理成 a i 3 指向数组的指针变量 也可将其看作是数组名 因而可按下标法来使用 例如 p i 等价于 p i 注意 p 1指向数组的下一个元素 而不是简单地使指针变量p的值 1 其实际变化为p 1 size size为一个元素占用的字节数 例如 假设指针变量p的当前值为1000 则p 1为1000 1 4 1004 而不是1001 如图9 6 见下一页 所示 元素起始地址a 0 1000a 1 1004a 2 1008a 3 1012a i 1016a 5 1020a 6 1024a 7 1028a 8 1032a 9 1036 a数组 如果有 inta 10 p a 则 1 p i和a i都是数组元素a i 的地址 如图所示 实际地址为p i d d为每个数组元素所占的字节数 2 p i 和 a i 就是数组元素a i 实际上 在编译时 对数组元素a i 就是处理成 a i 3 指向数组的指针变量 也可将其看作是数组名 因而可按下标法来使用 例如 p i 等价于 p i 有条件 p a 等价元素a i p1000 p 1 a 1 图9 6 案例9 5 使用指向数组的指针变量来引用数组元素 案例代码文件名 AL9 5 C 程序功能 使用指向数组的指针变量来引用数组元素 includemain intarray 10 p array i printf Input10numbers for i 0 i 10 i scanf d p i 使用指针变量来输入数组元素的值 printf array 10 for i 0 i 10 i printf d p i 使用指向数组的指针变量输出数组元素的值 printf n AL9 5 C 程序演示 程序运行情况 Input10numbers 0123456789 array 10 0123456789 说明 1 指针变量的值是可以改变的 所以必须注意其当前值 否则容易出错 2 指向数组的指针变量 可以指向数组以后的内存单元 虽然没有实际意义 3 对指向数组的指针变量 px和py 进行算术运算和关系运算的含义1 可以进行的算术运算 只有以下几种 px n px px px px px py px n 将指针从当前位置向前 n 或回退 n n个数据单位 而不是n个字节 显然 px px和px px是px n的特例 n 1 px py 两指针变量的值之差 其意义是两指针之间的数据 数组元素的 个数 而不是指针的地址之差 思考题 若有以下定义和语句 且0 i 10 则对数组元素的错误引用是 inta 1 2 3 4 5 6 7 8 9 10 int p a i A a i Ba p a Cp iD a i 2 关系运算表示两个指针所指地址之间 位置的前后关系 前者为小 后者为大 例如 如果指针px所指地址在指针py所指地址之前 则px py的值为1 9 3 3再论数组名作函数参数数组名作形参时 接收实参数组的起始地址 作实参时 将数组的起始地址传递给形参数组 引入指向数组的指针变量后 数组及指向数组的指针变量作函数参数时 可有 种等价形式 本质上是一种 即指针数据作函数参数 1 形参 实参都用数组名 2 形参 实参都用指针变量 3 形参用指针变量 实参用数组名 4 形参用数组名 实参用指针变量 2007年4月 1 有以下程序voidf int q inti 0 for i 5 i q main inta 5 1 2 3 4 5 i f a for i 0 i 5 i printf d a i 程序运行后的输出结果是 A 2 2 3 4 5 B 6 2 3 4 5 C 1 2 3 4 5 D 2 3 4 5 6 2007年4月 2 以下程序的输出结果是 intfun int x intn if n 0 returnx 0 elsereturnx 0 fun x 1 n 1 main inta 1 2 3 4 5 6 7 printf d n fun a 3 10 2007年9月 1 若在定义语句 inta b c p 2007年9月 2 有以下程序 includevoidfun int a intn 函数功能是将a所指数组元素从大到小排序 intt i j for i 0 i n 1 i for j i 1 j n j if a i a j t a i a i a j a j t main intc 10 1 2 3 4 5 6 7 8 9 0 i fun c 4 6 for i 0 i 10 i printf d c i printf n 程序运行的结果是A 1 2 3 4 5 6 7 8 9 0 B 0 9 8 7 6 5 1 2 3 4 C 0 9 8 7 6 5 4 3 2 1 D 1 2 3 4 9 8 7 6 5 0 2007年9月 3 有以下程序 includevoidfun intn int p intf1 f2 if n 1 n 2 p 1 else fun n 1 程序的运行结果是A 2B 3C 4D 5 2008年4月 1 以下定义语句中正确的是A inta b 0 B charA 65 1 b b C floata 1 b 程序运行的结果是A y 0B y 1C y 2D y 3 2008年4月 3 有以下程序 includevoidfun int s intn1 intn2 inti j t i n1 j n2 while i j t s i s i s j s j t i j main inta 10 1 2 3 4 5 6 7 8 9 0 k fun a 0 3 fun a 4 9 fun a 0 9 for k 0 k 10 k printf d a k printf n 程序运行得结果是A 0987654321B 4321098765C 5678901234D 0987651234 2008年4月 4 以下程序的输出结果是 35 includevoidswap int a int b int t t a a b b t main inti 3 j 5 p 2008年4月 5 以下程序的输出结果是 4 includemain inta 5 2 4 6 8 10 p p a p printf d p 2008年9月 1 若有定义语句 doublex 5 1 0 2 0 3 0 4 0 5 0 p x 则错误引用x数组元素的是A pB x 5 C p 1 D x2 以下程序的输出结果是 9 includemain intj a 1 3 5 7 9 11 13 15 p a 5 for j 3 j j switch j case1 case2 printf d p break case3 printf d p 9911 2008年9月 3 以下程序的输出结果是 10 include defineN5intfun int s inta intn intj s a j n while a s j j returnj main ints N 1 intk for k 1 k N k s k k 1 printf d n fun s 4 N 3 2009年3月 1 若有定义语句 doublex y px py 执行了px 2009年3月 2 有以下程序 includevoidfun int a int b int c c a a b b c main intx 3 y 5 p 程序运行后输出的结果是A 3 5 5 3B 3 5 3 5C 5 3 3 5D 5 3 5 3 2009年3月 3 有以下程序 includevoidf int p int q main intm 1 n 2 r 程序运行后的输出结果是A 1 3B 2 3C 1 4D 1 2 2009年3月 4 以下函数按每行8个输出数组中的数据 includevoidfun int w intn inti for i 0 i n i printf d w i printf n 下划线出应填入的语句是A if i 8 0 printf n B if i 8 0 continue C if i 8 0 printf n D if i 8 0 continue 2009年3月 5 若有以下定义intx 10 pt x 则对数组元素的正确引用是A x 10 B x 3 C pt 10 D pt 3 2009年3月 6 有以下程序 includeintb 2 intfun int k b k b return b main inta 10 1 2 3 4 5 6 7 8 i for i 2 i 4 i b fun 程序运行后的输出结果是A 1012B 810C 1028D 1016 2009年9月 1 有以下程序 includemain intm 1 n 2 p 程序运行后的输出结果是A 1 2 1 2B 1 2 2 1C 2 1 2 1D 2 1 1 2 9 3 42维数组的指针及其指针变量1 2维数组的指针假设有如下数组定义语句 inta 3 4 1 3 5 7 9 11 13 15 17 19 21 23 1 从2维数组角度看 数组名a代表数组的起始地址 是一个以行为单位进行控制的行指针 a i 行指针值 指向2维数组的第i行 a i 等价于a i 列 指针值 指向第i行第 列 控制由行转为列 但仍为指针 a i 数组元素a i 0 的值 用a作指针访问数组元素a i j 的格式 a i j 注意 行指针是一个 级指针 如图所示 2 从1维数组角度看 数组名a和第1维下标的每一个值 共同构成一组新的1维数组名a 0 a 1 a 2 它们均由4个元素组成 a 0 a 0 1 a 0 3 语言规定 数组名代表数组的地址 所以a i 是第i行1维数组的地址 它指向该行的第0列元素 是一个以数组元素为单位进行控制的列指针 a i j 列 指针值 指向数组元素a i j a i j 数组元素a i j 的值 如果有 inta 3 4 p a 0 则p 1指向下一个元素 如图所示 用p作指针访问数组元素a i j 的格式 p 每行列数 j 2 行指针变量 指向由n个元素组成的一维数组的指针变量 1 定义格式数据类型 指针变量 n 注意 指针变量 外的括号不能缺 否则成了指针数组 数组的每个元素都是一个指针 指针数组 本章第6节介绍 2 赋值行指针变量 2维数组名 行指针变量 案例9 6 使用行指针和列指针两种方式输出2维数组的任一元素 1 使用行指针 案例代码文件名 AL9 6 1 C 程序功能 使用行指针输出2维数组的任一元素 main inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 int pointer 4 row col pointer a printf Inputrow scanf d 程序运行情况 Inputrow 1 Inputcol 2 array 1 2 7思考题 本题也可以直接使用数组名a作指针 应如何修改 2 使用列指针 案例代码文件名 AL9 6 2 C 程序功能 使用列指针输出2维数组的任一元素 main inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 int pointer row col 定义一个 列 指针变量pointer pointer a 0 给 列 指针变量pointer赋值 printf Inputrow scanf d 程序演示 3 2维数组指针作函数参数一维数组的地址可以作为函数参数传递 多维数组的地址也可以作为函数参数传递 在用指针变量作形参以接受实参数组名传递来的地址时 有两种方法 用指向变量的指针变量 用指向一维数组的指针变量 2008年9月 1 有以下程序 includeintfun int s 4 intn intk intm i m s 0 k for i 1 im m s i k returnm main inta 4 4 1 2 3 4 11 12 13 14 21 22 23 24 31 32 33 34 printf d n fun a 4 0 程序的运行结果是A 4B 34C 31D 32 9 3 5动态数组的实现在程序运行过程中 数组的大小是不能改变的 这种数组称为静态数组 静态数组的缺点是 对于事先无法准确估计数据量的情况 无法做到既满足处理需要 又不浪费内存空间 所谓动态数组是指 在程序运行过程中 根据实际需要指定数组的大小 在C语言中 可利用内存的申请和释放库函数 以及指向数组的指针变量可当数组名使用的特点 来实现动态数组 动态数组的本质是 一个指向数组的指针变量 案例9 7 动态数组的实现 案例代码文件名 AL9 7 C 程序功能 实现动态数组 include includemain int

温馨提示

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

评论

0/150

提交评论