计算机本科C语言第十章讲.ppt_第1页
计算机本科C语言第十章讲.ppt_第2页
计算机本科C语言第十章讲.ppt_第3页
计算机本科C语言第十章讲.ppt_第4页
计算机本科C语言第十章讲.ppt_第5页
已阅读5页,还剩192页未读 继续免费阅读

下载本文档

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

文档简介

2004年11月1日 第十章指针 重点 指针的概念 指针的运算 指针的应用难点 指针概念的建立 10 1指针的概念1地址内存区的每个字节有一个编号 这就是 地址 内存字节地址旅馆房间房间号在地址所标志的单元中存放数据 相当于房间中住旅客一样 凡在程序中定义的变量 在编译时 系统都给它们分配相应的存储单元 如 一般微机C系统给int变量分配2字节 给float变量分配4字节 每个变量所占用的存储单元都有确定的地址 例如 inta 3 b 4 floatc 4 5 d 8 6 chare w f y 它们在内存中的情况如右图所示 变量的地址变量的地址 是其所占存储单元第一个字节的编号 是用 变量名来表示 由此可得 a1010 b1012 c1014 d1018 要访问内存中的变量 在程序中通常通过变量名来引用变量的值 例如 printf d a 实际上 在编译时 在内存中不再出现变量 而只有地址将键盘输入的一个数存到1012开始的2个字节的整型存储单元中 由于通过变量的地址能找到变量的存储单元 我们说地址 指向 该变量单元 路牌 路 变量地址 变量存储单元 指向 指向 在C中 将这种 指向 形象化为指针 在三叉路口 路牌就是一个指针 它指向某一目的地 变量的地址它指向变量的存储单元 因此变量的地址就是变量的指针 若一个变量的地址为2000 可以说变量的指针为2000 房间号 房间 指向 3变量的指针 下图 a的地址为1010 即a的指针为1010 也就是1010指向a的存储单元 如同房间号1010指向1010房间 4直接访问方式这种按变量地址存取变量值的方式 称为 直接存取 方式或称 直接访问 方式 5 间接存取 方式或称 间接访问 方式 先找到存放b的地址的变量pb 从中取出b的地址 然后对1012开始的2个字节的整型存储单元进行存取操作 6指针变量存放地址的变量是一种特殊变量 地址变量或指针变量 它只能用来存放地址 根据上图所示的逻辑关系 可以把它们形象地表示为下图 指向 指向 指向 指向 指向 指向 小结 地址 内存中每个字节的编号变量的地址 指着是变量所占存诸单元第一个字节的地址 指针变量 其值为地址的变量指向 是通过地址来体现 通过地址能找到所需的变量单元 可以说 地址指向该变量单元 a 3 a 1010 10 2变量的指针和指向变量的指针变量 内容 指针变量的定义指针变量的引用及作函数的参数一 指针变量的定义一般形式 类型标识符 变量名如 int p1 char p2 float p3 说明 1 当 出现在声明中 说明p1 p2 p3为指针变量 2 指针变量有确定的指向的数据类型 int p1 中int是指 所定义的指针变量是指向整型值的指针变量 或者说p1只能存放整型数据的地址 也就是说p1只能用来指向整型数据 int就是指针变量的基类型 指针变量的基类型用来指定该指针变量可以指向的数据的类型 pa pc等分别指向不同数据类型的指针变量 它们的共同点 1 值为地址 2 它们的存储单元空间是一样的 一个指向char的指针和一个指向int的指针不同点 其实 指针本身只有一种 指针变量存放的值都是内存地址 在定义指针时 定义指针所指向的数据类型的目的是说明如何解释指针所指向的空间的数据 0 x0065FDED 0 x0065FDEE 0 x0065FDEF 0 x0065FDF0 0 x0065FDF1 如果有一个整型指针p指向了地址0 x0065FDED 那么系统就会将指针指向的地址开始的2个字节当成整数值来解释 而如果一个字符指针s指向了地址0 x0065FDED 那么系统会认为这里存放了一个字符串 在定义指针变量时要注意 1一般形式 基类型 指针变量名2不能用一个整数给一个指针变量赋初值int p 2000 写此语句的原意可能是想将地址2000作为指针变量p的初值 但编译系统并不把2000认为是地址 而认为是整数 因此认为是语法错误 3在定义指针变量时必须指明基类型 float p p 说明p只能指向类型为实型的变量 且使指针移动1个位置意味着移动4个字节 二 指针变量的引用1有两个与指针变量有关的运算符 取地址运算符 指针运算符 间接访问运算符 例如 a为变量a的地址 p为指针变量p所指向的存储单元 2指针变量赋值运算1 可以将一个变量的地址直接赋给同类型的指针变量floatscore float pf 2 同类型的指针变量之间可以互相赋值intt1 1 int p1 p2 p1 4 可以将NULL 0 赋给指针变量 它表示指针变量为空 即该指针变量不指向任何存储单元 3 用指针变量对变量赋值如 inti j p p 的意义为指针变量p指向变量i 注意 p是地址变量 p是非地址变量 与i是一回事 例10 1main inta int aptr a 7 aptr 运行结果为 0012FED40012FED477 例10 2main inta b int pointer 1 pointer 2 a 100 b 10 pointer 1 关于运算符 例10 3输入a和b两个整数 按先大后小的顺序输出a和b includemain int p1 p2 p a b scanf d d 三 指针变量作为函数参数值传递方式 函数的形参为变量 实参可以是变量 常量 表达式 地址传递方式 函数的形参可以是指针变量 实参可以为变量的指针或指向变量的指针变量 功能 将一个变量的地址传送到另一函数中 实参和形参均可用指针 例10 4计算整数立方函数方法之一 值传递方式intcube value intn returnn n n voidmain intnumber 5 printf numberis d n number printf numberis d n cube value number 例10 4计算整数立方函数方法之二 地址传递方式intcube value int nptr nptr nptr nptr nptr voidmain intnumber 5 printf numberis d n number cube value 例10 5对输入的两个整数按大小顺序输出 今用函数处理 而且用指针类型的数据作函数参数程序如下 swap p1 p2 int p1 p2 intp p p1 p1 p2 p2 p main inta b int ptr 1 ptr 2 scanf d d 调用函数时可以改变实参指针变量所指向变量的值 例10 5程序可修改为 swap p1 p2 int p1 p2 intp p p1 p1 p2 p2 p main inta b scanf d d 下面例子不能正确交换数据 swap pl p2 int p1 p2 int p p pl p1 p2 p2 p main inta b int ptr 1 ptr 2 scanf d d 调用函数时不会改变实参指针变量的值 但可以改变实参指针变量所指向变量的值 实参和形参指针变量的传递是单向的 例10 6输入a b c三个整数 按大小顺序输出 swap pt1 pt2 int pt1 pt2 intp p pt1 ptl pt2 pt2 p exchange q1 q2 q3 int q1 q2 q3 if ql q2 swap q1 q2 if ql q3 swap q1 q3 if q2 q3 swap q2 q3 main inta b c p1 p2 p3 scanf d d d 想通过函数调用得到n个要改变的值 方法如下 1在主调函数中设n个变量 设n个指针指向它 并把指针变量作实参 将其值传给形参 2编写被调用函数 其形参为指针变量 其基类型与实参的基类型一致3通过形参指针变量的指向 改变n个变量的值4在主调函数中可用这些改变了值的变量 例10 6程序可改写为swap pt1 pt2 int pt1 pt2 intp p pt1 ptl pt2 pt2 p exchange q1 q2 q3 int q1 q2 q3 if ql q2 swap q1 q2 if ql q3 swap q1 q3 if q2 q3 swap q2 q3 main inta b c scanf d d d 10 3数组与指针 重点 指向数组元素的指针变量及其应用知识点 一维数组与指针多维数组与指针难点 多维数组与指针 一 指向数组元素的指针变量1数组元素的指针一个数组包含若干元素 每个元素在内存中都占有存储单元 它们都有相应的地址 所谓数组元素的指针就是数组元素的地址 2指向数组元素的指针变量指针变量可以指向普通变量 也可以指向数组元素 指向数组元素的指针变量 即该指针变量的值是数组元素的地址 把某一元素的地址放到一个指针变量的存储单元中 inta 10 int p p 二 指向数组元素的指针变量的定义与赋值1 定义相同于指向普通变量的指针变量的定义类型标识符 变量名如 int p float p1 2 赋值将某元素或数组的首地址赋给指针变量如 inta 10 p p 三 通过指针变量引用数组元素例 inta 10 int p p 可以通过指针变量引用数组元素 指针变量p已指向数组中的第一个元素 序号为0的元素 则p 1或p 指向下一个元素 例如 数组元素是整型 p 1所代表的地址实际上是p 1 d d是一个元素所占的字节数 1元素赋值如 inta 10 p p a p 1 相当于a 0 1 2各元素地址 用上定义 指针p增一便指向下一单元 p指向a 0 p 1指向a 1 p 2指向a 2 p i指向a i p 9指向a 9 从上可知 如果p的初值为 a 0 则 p i和a i就是a i 的地址 或者说它们是指向a数组中的第i个元素 p i 和 a i 是p i和a i所指向的数组元素 即a i 可以看出 实际上是变址运算符 对a i 的求解过程是 先按a i d计算数组元素的地址 然后找出此地址所指向的单元中的值 指向数组元素的指针变量也可以带下标 如p i 等价于 p i 3引用元素下标法如a i 形式指针法如 a i 用指针变量引用数组元素inta 10 int p p a p 3 例10 7输出一数组的全部元素 main staticinta 10 1 2 3 4 5 6 7 8 9 10 int p i for i 0 i 10 i printf d a i 下标法 printf n for i 0 i 10 i printf d a i 指针法 printf n for p a p a 10 p printf d p 指针变量指用数组元素 printf n 三种方法比较 1 从执行效率上比较下标法与指针法的执行效率是相同的 C编译系统是将a i 转换为 a i 处理的 对每个a i 都分别计算a i d 然后访问该元素 第3种方法 用指针变量指向数组元素 比较快 不必每次都重新计算地址 像p 这样的自加操作能提高执行效率 2 从直观性上比较用下标法比较直观 能直接知道是第几个元素 例如 a 5 是数组中序号为5的元素 用地址法和指针变量的方法都不太直观 难以判断出当前处理是哪一个元素 例10 8输出数组a的全部元素 main int p i a 10 p a printf Enter10numbers n for i 0 i 10 i scanf d p printf n p a for i 0 i 10 i p printf d p 当p变时注意p当前的值 指针变量p可以指向有效的数组元素 实际上也可以指向数组以后的内存单元 3 关于指针变量的一些运算 设a为一维数组名且p a 1 p p 2 p 等价于 p 先得到 p的值 再做p p 等价于 p 先得到 p的值 再做p 3 p p先自增1 再得到 p的值 p p先自减1 再得到 p的值 4 p 使元素值加1 p 使元素值减1 三 数组名作函数参数1 数组名作函数参数 传递的是地址 例10 9将数组a中n个数反序排列voidinv x n 数组名作形参和实参 intx n intt i j m n 1 2 for i 0 i m i j n 1 i t x i x i x j x j t return includemain staticinti a 10 0 1 2 3 4 5 6 7 8 9 printf theorginalarray n for i 0 i 10 i printf d a i printf n inv a 10 printf thearrayhasbeeninverted n for i 0 i 10 i printf d a i printf n 例10 9将数组a中n个数反序排列 指针变量作函数参数 形参和实参 voidinv x n int x n intt i j m n 1 2 j x n 1 for i x i x m i j t i i j j t return includemain staticinti a 10 0 1 2 3 4 5 6 7 8 9 int p a printf theorginalarray n for i 0 i 10 i printf d p printf n p a inv p 10 printf thearrayhasbeeninverted n for p a p a 10 p printf d p printf n 例10 10从10个数中找出其中最大的和最小的 intmax min 全局变量 voidmax min value array n 形参为数组名 intarray n int p array end array end array n 1 max min array for p array 1 pmax max p elseif p min min p return main inti number 10 printf Enter10data n for i 0 i 10 i scanf d 例10 10从10个数中找出其中最大的和最小的 intmax min max min value array n 形参为指针 int array n int p array end array end array n 1 max min array for p array 1 pmax max p elseif p min min p main inti number 10 p number printf Enter10data n for i 0 i 10 i scanf d p for i 0 p number i 10 i printf d p p number max min value p 10 实参为指针 printf nmax d min d n max min 例10 11用选择法对10个整数排序 实参用指针而形参用数组 main int p i a 10 p a for i 0 i 10 i scanf d p p a sort p 10 for i 0 i 10 i printf d p p sort x n intx n inti j k t for i 0 i n 1 i k i for j i 1 j n j if x j x k k j if k i t x i x i x k x k t 课后10 3输入10个整数 将其中最小的数与第一个数对换 把最大的数与最后一个数对换 写三个函数 1 输入10个数2 进行处理3 输出10个数编程思路 主函数 input input sort output 主函数和被调用函数之间存在地址传递关系 用数组名作实参 1输入10个数 voidinput int a inti for i 0 i 9 i scanf d a i 2进行处理 voidsort int a inti min max k min max a for i 0 imax max a i if a i min min a i for i 0 i 9 i if a i max k a i a i a 9 a 9 k for i 0 i 9 i if a i min k a i a i a 0 a 0 k 3输出10个数 voidoutput int a inti putchar n for i 0 i 9 i a printf 4d a voidmain intnum 10 input num sort num output num 课后10 4有n个整数 使前面各数顺序向后移m个位置 最后m个数变成最前面的m个数 写一函数实现以上功能 在主函数中输入n个整数和输出调整后的n个数 m n m n m m 编程思路 编写一个函数使之具有以下功能把a 6 的值赋给一个临时变量把前面所有的元素 除最后元素外 后移一位把临时变量的值赋给a 0 该函数调用m次 编程思路 先定义一个函数可以实现 把最后的元素赋给一个中间变量 然后把前一个元素赋给后一个元素 最后把中间变量的值赋给序号为0的元素 for i N 1 i 0 i p i p i 1 然后把中间变量的值赋给 P 第二次调用该函数 for i N 1 i 0 i p i p i 1 该函数总共调用m次才能完成以上功能 include defineN7voidmove int t intn intm int k i i t n 1 for k t n 1 k t 1 k k k 1 t 0 i m if m 0 move t n m voidmain intm k inta N printf pleaseinputtom n while 1 scanf d 课后10 5有n个人围成一圈 顺序排号 从第一个人开始报数 从1报到3 凡报到3的人退出圈子 问最后留下的是原来第几号的那位 i至10时掉头从0开始计 k至3时重新报数k 0 是3时其值为0 p i m N 1时循环终止 include defineN10 方便修改数组的长度 voidmain inti k m a N p k是用来报数 m是退出人数 i用来循环计数 p a for i 0 i N i p i 1 i m k 0 p a while m N 1 if p i 0 k 是圈子里的人要参与报数 if k 3 p i 0 k 0 m 到3时k从1开始报数 m自加1 p i所指的元素值为0 i if i N i 0 p a while p 0 p 循环终止时 p指向值不为0的元素 printf thelastoneis d n p 四 多维数组与指针先讨论多维数组的地址 然后讨论指向多维数组元素的指针变量和指向一维数组的指针变量 一 多维数组的地址设有一个数组 它有3行4列 它的定义为 staticinta 3 4 1 3 5 7 9 11 13 15 17 19 21 23 a是一个数组名 a数组包含3行 即3个元素 a 0 a 1 a 2 而每一个元素又是一个一维数组 它包含4个元素 即4个列元素 例如 a 0 所代表的一维数组又包含4个元素 a 0 0 a 0 1 a 0 2 a 0 3 可以认为二维数组是 数组的数组 即二维数组a是由3个一维数组所组成的 1 从二维数组的角度来看数组的首地址为a且a代表数组首元素的地址 现在的首元素是由4个整型元素所组成的一维数组 因此a代表的是首行的起始地址 2 各行的首地址1 用a表示 从行的角度考虑 第0行首地址为a a 0或 a 0 第1行首地址为a 1 a 1或 a 1 第2行首地址为a 2 a 2或 a 2 第i行首地址为a i a i或 a i 2 用a i 表示 从列的角度来考虑问题 因为a 0 a 1 a 2 为数组名而C又规定了数组名代表数组首元素地址 因此a 0 代表一维数组a 0 中0列元素的地址即 a 0 0 a 1 的值为 a 1 0 a 2 的值为 a 2 0 以此类推a i 为第i行 第0列元素的地址 各行首地址的变化情况 设数组首地址为2000 则各行首地址为 2000 2008 2016 各行相差4 2 8 3 某行某列的地址 即各元素的地址 可有多种表示方式 1 用a i 示第i行 第j列元素的地址为 a i j2 用a表示为 对一维数组a 0 a 1 a 2 和 a 0 a 1 a 2 均表示元素 所以a 0 与 a 0 等价 即a 0 与 a等价a 1 与 a 1 等价 a 2 与 a 2 等价对二维数组 则a 0 a 1 a 2 和 a 0 a 1 a 2 表示各行的首地址 从列角度考虑 所以第i行 第j列元素的地址为 a i j3 用 a i j 表示 请大家思考以下问题 a a 0 a 0 a 0 a 0 0 之间的关系 a i a i a i a i a i 0 之间的关系 4 元素的表示方法即第i行 第j列的元素表示方法 1 下标法 a i j 2 用a i j地址表示 a i j 3 用 a i j地址表示 a i j 5 地址表示方法汇总 例10 11 defineformat d d n main staticinta 3 4 1 3 5 7 9 11 13 15 17 19 21 23 printf format a a 158 158printf format a 0 a 0 158 158printf format 9 9 二 多维数组的指针1 指向多维数组元素的指针变量例10 12用指针变量输出元素值 main staticinta 3 4 1 3 5 7 9 11 13 15 17 19 21 23 int p for p a 0 p a 0 12 p if p a 0 4 0 printf n printf 3d p 运行结果为 1357911131517192123 第i行 第j列元素的相对地址为i m jm表示列数实际地址为a 0 i m j n例 ints 3 4 s代表数组的首地址 其为2000 请计算出元素s 2 3 的地址为 2 指向一维数组的指针变量变量的指针只能存放变量的地址 而不能存放数组的地址 可定义数组的指针变量来存放数组的地址 定义的一般形式 类型说明符 指针变量 数组长度 如 int p 4 p为指向具有4个整型元素的一维数组的指针变量 不能写成 p 4 此为指针数组 说明 1 p的增值以一维数组的长度为单位 2 用p表示数组的行地址如 inta 3 4 p 4 p a 或p 或p a 2 则p 1指向第一行 与a 1相同 表示第一行的首地址p i表示第i行的首地址 3 用p表示数组元素的地址inta 3 4 p 4 p a p表示第0行第0列的地址 p 1 表示第1行第0列元素的地址 p i 表示第i行第0列元素的地址所以 p i j表示第i行第j列元素的地址 4 用p表示数组元素 p i j 表示第i行第j列的元素 例用指向多维数组元素的指针变量输入并输出二维数组各元素的值 includevoidmain inta 3 4 int p for p a 0 p a 0 12 p scanf 4d p for p a 0 p a 0 12 p printf 4d p putchar n 例10 13用指向m个元素组成的的一维数组的指针变量输入并输出二维数组元素的值 main staticinta 3 4 int p 4 t j p a for t 0 t 3 t for j 0 j 4 j scanf d p t j for t 0 t 3 t for j 0 j 4 j printf d p t j 请大家思考以下问题 inta 4 1 2 3 4 ints 3 4 0 int p 4 p s p a 哪一个能实现正确赋值 不正确的地方如何修改 三 多维数组的指针作为函数参数实参是指针 形参有两种形式 1 用指向数组元素的指针变量 2 用指向一维数组的指针变量 例10 14有一个班 3个学生 各4门课程 计算总平均分数和查找第n个学生的成绩 main voidaverage float int voidsearch float int staticfloatscore 3 4 65 67 70 60 80 87 90 81 90 99 100 98 scanf d 实参是行指针 voidaverage p n 形参用指向元素的指针 float p intn p指向第一个元素 float p end floatsum 0 aver p end p n 1 p end指向第一个元素 for p p end p sum sum p 通过循环求出各元素之和 aver sum n printf average 5 2f n aver voidsearch p n 实参是多维数组名 形参用指向数组的指针 float p 4 intn inti printf thescoreofNo dare n n 1 for i 0 i 4 i 通过循环输出第n行4个元素 printf 5 1f p n i printf n 程序运行结果为 average 82 25thescoreofNo 3are 90 099 0100 098 0 例10 15在上题的基础上 查找有一门以上课程不及格的学生 打印出他们的全部课程的成绩 main voidsearch float int staticfloatscore 3 4 65 57 70 60 58 87 90 81 90 99 100 98 search score 3 实参用的是行指针 voidsearch p n float p 4 intn inti j flag for j 0 j n j 从第0行开始查找至第n 1行 flag 0 不及格标志 for i 0 i 4 i 查找某人的成绩 if p j i 60 flag 1 if flag printf No disfail his her scoresare n j 1 for i 0 i 4 i printf 5 1f p j i printf n 课后10 10将一个5 5的矩阵中最大的元素放在中心 4个角分别放4个最小的元素 顺序为从左到右 从上到下顺序依次从小到大存放 写一函数实现之 用主函数调用 include defineN5voidmove inta N N i j max min1 min2 min3 min4 inttemp int p 5 a for i 0 i max max p i j elseif p i j min1 min1 p i j temp max max p 2 2 p 2 2 temp 把最大值放到中心 temp p 0 0 p 0 0 min1 min1 temp 把最小值放到a 0 0 min2 min3 min4 p 0 1 min2min3min4指向第0行第1列 for i 0 i p 0 0 min2 p i j temp p 0 4 p 0 4 min2 min2 temp 交换 for i 0 i p 0 4 min3 p i j temp p 4 0 p 4 0 min3 min3 temp 交换 for i 0 i p 4 0 min4 p i j temp p 4 4 p 4 4 min4 min4 temp 交换for i 0 i N i for j 0 j N j printf 4d p i j printf n voidmain move 课后10 15有一个班4个同学 5个门 1 求第一门课的平均分 2 找出有2门以上课程不及格的学生 输出他们的学号 全部课程和平均成绩 3 找出平均成绩在90分以上或全部课程在85分以上的学生 分别编3个函数实现以上3个要求 主函数 average 求第一题 found1 求第二题 found2 求第三题 主函数和被调用函数之间存在地址传递且传递的是行地址 include defineN10voidmain voidaverage float p 5 intn voidfound1 float p 5 intn voidfound2 float p 5 intn floata 4 5 90 32 78 12 80 90 89 90 87 99 89 87 67 76 56 76 87 30 65 70 average a 4 found1 a 4 found2 a 4 求第一门课的平均分 voidaverage float p 5 intn inti floatsum 0 for i 0 i n i 求出第0至n 1行第0列的总和 sum p i 0 printf 第一门课的平均分是 f n sum n voidfound1 float p 5 intn floatsum 0 inti j m m用来统计有2门以上不及格 for i 0 i 2 printf 有2门以上不及格学生的学号 d n i 1 printf 其成绩为 for j 0 j 5 j printf f p i j sum p i j printf n其平均分成绩为 f n sum 5 找平均分在90分以上或全部课程在85分以上的学生 voidfound2 float p 5 intn floatsum inti j m m用来求每个同学课程大于85分的个数 for i 0 i85 m if m 5 sum 5 90 printf 学号是 d n i 1 10 4字符串的指针和指向字符串的指针变量 重点 1 字符串指针的定义 引用及作函数参数 2 字符串指针变量与字符数组的区别 一 字符串的表示形式1 用字符数组如 chara 10 CHINA 2 用字符指针例10 17main char string IloveChina printf s n string char string IloveChina 等价于下面两行 char string string IloveChina 在程序中定义了一个字符指针变量string 用字符串 IloveChina 对它初始化 对字符指针变量的初始化实际上是把字符串第一个元素的地址赋给string printf s string 在输出时 系统先输出string所指向的第一个字符数据 然后使string自动加1 使之指向下一个字符 然后输出 直至遇到字符串结束标志 而字符数组不允许这样 chars 20 s IloveChina 请大家思考使s数组元素得到值的方法 对字符串中字符的存取 可用下标法 也可以用指针法 例10 18将字符串a复制到字符串b main 指针法 chara Iamaboy b 20 inti for i 0 a i 0 i b i a i b i 0 printf stringais s n a printf stringbis s n b 例10 19用指针变量来处理例10 18 main 通过指针变量来处理 chara Iamaboy b 20 p1 p2 inti p1 a p2 b for p1 0 p1 p2 p2 p1 p2 0 p1 a p2 b printf s n s n p1 p2 二 字符串指针作函数参数实参是字符串 字符数组名或字符串指针 传递的是地址 在被调函数中改变后 可在主调函数中得到改变后的字符串 例10 20用函数调用实现字符串的复制 1 用字符数组名作参数voidcopy string from to charfrom to inti 0 while from i 0 to i from i i to i 0 main chara Iamateacher b youarestudent printf stringais s n a printf stringbis s n b copy string a b printf stringais s n a printf stringbis s n b 2 形参和实参分别用字符指针变量voidcopy string from to char from to inti 0 for from 0 from to to from to 0 main char a Iamateacher char b youareastudent printf stringais s n a printf stringbis s n b copy string a b printf stringais s n a printf stringbis s n b 3 函数体的几种简化形式1 voidcopy string from to char from to while to from 0 to from 2 voidcopy string from to char from to while to from 0 3 voidcopy string from to char from to while from 0 to from to 0 4 voidcopy string from to char from to while to from 5 voidcopy string from to char from to for to from 0 6 用字符数组voidcopy string from to charfrom to char p1 p2 p1 from p2 to while p2 p1 0 三 字符指针变量与字符数组虽二者均能实现对字符串的存储和计算 但二者有区别 主要有以下几点 1 字符数组由元素组成 元素中放字符 字符指针变量放地址 如字符串的首地址等 2 赋初值的方式不同 对字符数组赋初值一般用static初始化 如staticcharstr IloveChina 而字符指针变量赋初值一般不用static 如 char p IloveChina 3 赋值方式不同 1 对字符数组要么赋初值 即定义时赋值 要么对元素赋值 下面的赋值方式是错误的 charstr 14 str IloveChina 2 字符指针变量赋值一般可赋初值 或先定义后赋值 如char a a IloveChina 等价于 char a IloveChina 4 定义字符数组时 编译后便分配了存储单元 但存储单元的值为空 如 charstr 10 scanf s str 为正确 但char a scanf s a 为错误的 而char a str 10 a str scanf s a 为正确的 5 字符指针变量的值可改变 例10 21main char a IloveChina a a 7 printf s a 而数组名代表数组的首地址 为地址常量 其值不能改变main chara IloveChina a a 7 printf s a 6 字符指针也可用下标法来表示 例10 22main char a IloveChina inti printf Thesixthcharacteris c n a 5 for i 0 a i 0 i printf c a i 运行结果为 ThesixthcharacteriseIloveChina 10 5函数的指针和指向函数的指针变量 重点 函数指针的概念及指向函数的指针变量用指向函数的指针变量作函数参数一 函数的指针及指向函数的指针变量1 函数指针的概念一个函数在编译时被分配一个入口地址 这个入口地址称为函数的指针 函数名代表函数的入口地址 2 指向函数的指针变量定义的一般形式 数据类型标识符 指针变量名 例 int f1 int 定义一个函数指针f1 它所指向的函数具有一个整型参数 返回类型整型 void f2 float f3 float 由于函数名表示该函数的入口地址 因此可以通过函数名赋给函数指针的方法 使函数指针指向某个函数 前提是函数的参数与返回类型必须与函数指针的参数与类型一致 intfun1 intn voidfun2 floatfun3 floatk int f1 int void f2 float f3 float f1 fun1 f1fun1 f2 fun2 f2fun2 f3 fun3 f3fun3 当指向函数的指针指向某一函数之后 可以通过指针变量调用函数 f1 3 f1 3 fun1 3 这三个语句作用是一样的 例1 intmax inta intb intx if a b x a elsex b returnx main intx y int p int int p max p为指向函数max的指针变量 scanf d d 例2 设计一个程序 实现两个数的加 减 乘 除四则运算 include includefloatadd floatx floaty returnx y floatsub floatx floaty returnx y floatmul floatx floaty returnx y floatdev floatx floaty if y 0 returnx y else printf 除数不能为0 n exit 1 voidmain floata b charc float p float float printf 输入计算式 格式为 操作数1运算符操作数2 n scanf f c f 例3设计一个菜单驱动函数调用的程序 includevoidmenu1 printf print n voidmenu2 printf copy n voidmenu3 printf delete n voidmain intchoice void p menu1 menu2 menu3 do puts 1 print n puts 2 copy n puts 3 delete n puts 0 exit n scanf d 请思考如何用while语句来取代do while语句 二 用指向函数的指针变量作函数的参数传递的是函数的入口地址 一般的使用形式 sub f1 f2 sub x1 x2 int x1 x2 inta b i j 次主调函数 a x1 i x1 x2为被调函数 b x2 i j 主调函数 次主调函数 例10 23设一个函数process 在调用它时 每次实现不同的功能 调用三次 分别求出a b中较大者 较小者和二者之和 main intmax int int min int int add int int intprocess int int int p int int inta b printf Enteraandb scanf d d max x y intx y intz return z x y x y min x y intx y intz return z x y x y add x y intx y intz z x y return z process x y fun intx y int fun intresult result fun x y printf d n result 用指向函数的指针变量作函数的参数说明 1 一般在嵌套调用中使用 传递的是函数的入口地址 2 次主调函数对其它函数操作 完成一定的功能 3 次主调函数的参数 实参 用函数名 10 6返回指针值的函数一 指针函数的定义数据类型标识符 函数名 形参表列 形参说明 函数体 如 int a x y 存储类别为外部函数 intx y return 函数体中必有return语句 二 指针函数的应用例10 23有若干个学生的成绩 每个学生有4门课程 要求输入学生序号后 输出该生的全部成绩 用指针函数来实现 includemain staticfloatscore 4 60 70 80 90 56 89 67 88 34 78 90 66 float search float 4 int float p inti m printf enterthenumberofstudent scanf d float search pointer n 返回第n行第0列元素的地址 float pointer 4 intn float pt pt pointer n return pt 运行结果 enterthenumberofstudent 1回车thescoresofNo 2are 56 089 067 088 0 例10 24对上例中的学生 找出其中有不及格课程的学生及其学生号 main staticfloatscore 4 60 70 80 90 50 89 67 88 34 78 90 66 float search float 4 所起的作用把行指针变为列指针 float p intk j for k 0 k 3 k p search score k if p score k printf No dscores k 1 for j 0 j 4 j printf 5 1f p j printf n float search pointer float pointer 4 inti for i 0 i 4 i if pointer i 60 return pointer 运行结果 No 2scores 56 089 067 088 0No 3scores 34 078 090 066 0 通过上面2个例子我们可知 指针函数函数体中必有return语句 且返回值为指针 例 通过改变函数返回值改变它所指向的存储单元的值 includeintk 0 int fun1 return 10 7指针数组和指向指针的指针 重点 指针数组及其应用一 指针数组其元素均为指针型数据的数组 称为指针数组 定义形式 类型标识符 数组名 数组长度说明 如 int p 4 不能写成int p 4 注意 1 在使用指针数组中的元素之前 必须为该元素指定一个确定的值 对指针数组的初始化时其每个元素的值都为地址 inti1 i2 i3 int p 3 2 在使用指针数组元素时 与指针的使用方法一样 includemain intk 4 t int p 4 3 指针数组主要用于指向多个字符串 使字符串处理方便 char a Math C English 3个字符串在内存中的分配可能是连续分配或不连续的 指针数组与二维字符数组的异同 相同点 表示一组字符串区别 指针数组所指的字符串长度是不规则的 内存空间可以是不连续的 chars 3 8 Math C English 指针数组所指一组字符串所占内存大小 5 4 8二维数组所占内存大小 8 8 8 最长列大小为数组大小 例如 图书馆有若干本书 想把书名放在一个数组中 见下图 然后要对这些书目进行排序和查询 按一般方法 字符串本身就是一个字符数组 因此要设计一个二维的字符数组才能存放各字符串 但二维数组的列数确定后 每一行的元素个数都相等 但实际上各字符串 书名 长度是不相等的 如按最长的字符串来定义 则会浪费许多内存单元 可以分别定义一些字符串 然后用指针数组中的元素分别指向各字符串 如果想对字

温馨提示

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

评论

0/150

提交评论