C语言指针讲解ppt课件

上传人:钟*** 文档编号:4973365 上传时间:2020-01-16 格式:PPT 页数:102 大小:1.75MB
返回 下载 相关 举报
C语言指针讲解ppt课件_第1页
第1页 / 共102页
C语言指针讲解ppt课件_第2页
第2页 / 共102页
C语言指针讲解ppt课件_第3页
第3页 / 共102页
点击查看更多>>
资源描述
第十章 使用指针 1 主要内容 10 1地址和指针的概念10 2变量的指针和指向变量的指针变量10 3通过指针引用数组10 4通过指针字符串10 5指向函数的指针10 6返回指针值的函数10 7指针数组和多重指针10 8动态内存分配与指向它的指针变量 2 10 1地址和指针的概念 内存区的每一个字节有一个编号 这就是 地址 如果在程序中定义了一个变量 在对程序进行编译时 系统就会给这个变量分配内存单元 按变量地址存取变量值的方式称为 直接访问 方式 3 4 2 另一种存取变量值的方式称为 间接访问 的方式 即 将变量 的地址存放在另一个变量中 在 语言中 指针是一种特殊的变量 它是存放地址的 5 一个变量的地址称为该变量的 指针 例如 地址2000是变量 的指针 如果有一个变量专门用来存放另一变量的地址 即指针 则它称为 指针变量 上述的i pointer就是一个指针变量 指针和指针变量的定义 6 10 2变量的指针和指向变量的指针变量 10 1怎样定义指针变量 定义指针变量的一般形式为基类型 指针变量名 7 下面都是合法的定义 float pointer char pointer 可以用赋值语句使一个指针变量得到另一个变量的地址 从而使它指向一个该变量 例如 pointer pointer 8 在定义指针变量时要注意两点 9 在对指针变量赋值时需要注意两点 指针变量中只能存放地址 指针 不要将一个整数赋给一个指针变量 例 pointer 1 pointer 1是指针变量 是整数 不合法 2 赋给指针变量的变是量地址不能是任意的类型 而只能是与指针变量的基类型具有相同类型的变量的地址 10 在引用指针变量时 可能有三种情况 给指针变量赋值 如 p 引用指针变量指向的变量 有关的两个运算符 取地址运算符 a是变量a的地址 指针运算符 或称 间接访问 运算符 p是指针变量p指向的对象的值 10 2 2怎样引用指针变量 11 例10 通过指针变量访问整型变量 includevoidmain int int pointer pointer pointer 把变量 的地址赋给pointer 1 pointer 把变量 的地址赋给pointer printf printf pointer pointer 12 13 例10 2输入 和 两个整数 按先大后小的顺序输出 和 includevoidmain int 1 2 scanf 1 if printf printf max min 1 2 14 运行情况如下 当输入 时 由于 将 和 交换 交换前的情况见图 交换后见图 15 16 10 3指针变量作为函数参数 例10 3对输入的两个整数按大小顺序输出 includevoidmain voidswap int int int int pointer pointer scanf pointer pointer 2 if swap pointer pointer 2 printf 17 voidswap int int inttemp temp 1 temp 18 19 例10 输入3个整数 要求按大小顺序将它们输出 用函数实现改变这3个变量的值 includevoidmain voidexchange int 1 int 2 int 3 int scanf exchange printf 20 voidexchange int int int voidswap int int if swap if swap if swap voidswap int int inttemp temp temp 21 10 3通过指针引用数组 一个变量有地址 一个数组包含若干元素 每个数组元素都在内存中占用存储单元 它们都有相应的地址 指针变量既然可以指向变量 当然也可以指向数组元素 把某一元素的地址放到一个指针变量中 所谓数组元素的指针就是数组元素的地址 10 3 1数组元素的指针 22 可以用一个指针变量指向一个数组元素 例如 定义 为包含 个整型数据的数组 定义 为指向整型变量的指针变量 把 元素的地址赋给指针变量 也就是使 指向 数组的第 号元素 23 24 语言规定在指针指向数组元素时 可以对指针进行以下运算 加一个整数 用 或 如p 1减一个整数 用 或 如p 1自加运算 如p p自减运算 如p p两个指针相减 如p1 p2 只有p1和p2都指向同一数组中的元素时才有意义 10 3 2指针的运算 25 分别说明如下 如果指针变量p已指向数组中的一个元素 则 指向同一数组中的下一个元素 指向同一数组中的上一个元素 2 如果p原来指向a 0 执行 p后p的值改变了 在p的原值基础上加d 这样p就指向数组的下一个元素a 1 3 如果 的初值为 则 和 就是数组元素 的地址 或者说 它们指向 数组的第 个元素 或 是 或 所指向的数组元素 即 5 如果指针变量p1和p2都指向同一数组 如执行p2 p1 结果是两个地址之差除以数组元素的长度 26 10 3通过指针引用数组元素 引用一个数组元素 可以用 下标法 如 形式 指针法 如 或 其中 是数组名 是指向数组元素的指针变量 其初值 例10 5输出数组中的全部元素 假设有一个 数组 整型 有 个元素 要输出各元素的值有三种方法 27 1 下标法 includevoidmain int int for scanf printf for printf 28 2 通过数组名计算数组元素地址 找出元素的值 includevoidmain int int for scanf printf for printf 29 3 用指针变量指向数组元素 includevoidmain int int for scanf printf for printf 30 例10 通过指针变量输出 数组的 个元素 includevoidmain int for scanf printf for printf 程序运行情况 12345671090 221532340030036252021163110259102372104103显然输出的数值并不是 数组中各元素的值 31 includevoidmain int for scanf printg p a for printf 程序运行情况 12345671090 12345671090 32 10 3 4用数组名作函数参数 在第7章中介绍过可以用数组名作函数的参数 如 voidmain i intarr int intarray array void intarr int 33 例10 将数组 中 个整数按相反顺序存放 34 includevoidmain voidinv int int int printf Theoriginalarray for printf printf inv printf Thearrayhasbeeninverted for printf printf 35 voidinv int int 形参x是数组名 inttemp for temp temp return 运行情况如下 Theoriginalarray Thearrayhasbeeninverted 36 37 includevoidmain voidinv int int int printf Theoriginalarray for printf printf inv printf Thearrayhasbeeninverted for printf printf 对刚才的程序可以作一些改动 将函数inv中的形参 改成指针变量 38 voidinv int int 形参x为指针变量 int temp for emp temp return 39 如果有一个实参数组 想在函数中改变此数组中的元素的值 实参与形参的对应关系有以下 种情况 1 形参和实参都用数组名 如 voidmain void int int int 40 41 2 实参用数组名 形参用指针变量 如 void void int int int 3 实参形参都用指针变量 例如 voidmain void int int int p a p 42 43 4 实参为指针变量 形参为数组名 如 voidmain void intx int p a p 44 includevoidmain voidinv int int int printf Theoriginalarray n for scanf printf inv 实参为指针变量 printf Thearrayhasbeeninverted for printf printf 例10 8用实参指针变量改写例10 45 voidinv int int int temp for emp temp return 46 例10 9用选择法对 个整数按由大到小顺序排序 includevoidmain voidsort int int int 10 for scanf sort for 47 voidsort int int int for for 48 10 3 5通过指针引用多维数组 用指针变量可以指向一维数组中的元素 也可以指向多维数组中的元素 但在概念上和使用上 多维数组的指针比一维数组的指针要复杂一些 1 多维数组元素的地址 先回顾一下多维数组的性质 可以认为二维数组是 数组的数组 例 定义inta 3 4 1 3 5 7 则二维数组a是由3个一维数组所组成的 设二维数组的首行的首地址为 则 2 指向多维数组元素的指针变量 1 指向数组元素的指针变量 例10 10用指向元素的指针变量输出二维数组元素的值 includevoidmain int 3 4 1 3 5 7 9 11 13 15 17 19 21 23 int for printf printf 运行结果如下 13579111315192123 51 2 用指向由 个元素组成的一维数组的指针变量 例10 11输出二维数组任一行任一列元素的值 includevoidmain int 1 3 5 7 9 11 13 15 int scanf printf 运行情况如下 本行为键盘输入 52 3 用指向数组的指针作函数参数 例10 12有一个班 个学生 各学 门课 计算总平均分数以及第 个学生的成绩 这个题目是很简单的 只是为了说明用指向数组的指针作函数参数而举的例子 用函数average求总平均成绩 用函数search找出并输出第 个学生的成绩 53 includevoidmain voidaverage float p intn voidsearch float p 4 intn floatscore 3 4 65 67 70 60 100 107 90 101 90 99 100 910 average score 12 求12个分数的平均分 search score 求序号为 的学生的成绩 54 voidaverage float int float floatsum aver p end for sum sum aver sum printf average aver 55 voidsearch float 4 int p是指向具有4个元素的一维数组的指针 int printf thescoreofNo are for printf 5 2 程序运行结果如下 average 10 ThescoreofNo 2are 10 56 例10 3在上题基础上 查找有一门以上课程不及格的学生 打印出他们的全部课程的成绩 includevoidmain voidsearch float p 4 intn 函数声明 floatscore 3 4 65 57 70 60 510 107 90 101 90 99 100 910 search score 57 voidsearch float p 4 int int for flag for if flag if printf No dfails hisscoresare n j 1 for printf printf 程序运行结果如下 No 1fails hisscoresare No 2fails hisscoresare 10 10 10 58 10 通过指针引用字符串 10 4 字符串的表示形式 例10 14定义一个字符数组 对它初始化 然后输出该字符串 includevoidmain charstring IloveChina printf string 1 用字符数组存放一个字符串 然后输出该字符串 59 2 用字符指针指向一个字符串可以不定义字符数组 而定义一个字符指针 用字符指针指向字符串中的字符 例10 15定义字符指针 使它指向一个字符串 includevoidmain char string IloveChina printf 60 例10 16将字符串 复制为字符串 includevoid char amaboy 20 int for printf stringais printf stringbis for printf printf 61 也可以设指针变量 用它的值的改变来指向字符串中的不同的字符 例10 17用指针变量来处理例10 16问题 includevoidmain char Iamaboy 20 p1 p2 int for p1 p2 62 printf string is printf for printf printf 程序必须保证使 和 同步移动 63 64 10 4 2字符指针作函数参数 例10 110用函数调用实现字符串的复制 includevoidmain voidcopy string char from char to char a Iamateacher charb Youareastudent char p b printf stringa s nstringb s n a p printf copystringatostringb n copy string a p printf nstringa s nstringb s n a b 1 用字符数组作参数 65 voidcopy string char from char to for from 0 from to to from to 0 程序运行结果如下 stringa Iamateacher stringb Youareastudent copystringatostringb stringa Iamateacher string Iamateacher 66 1 将copy string函数改写为voidcopy string char from char while from to from 对 函数还可以改写得更精练一些 请分析以下几种情况 2 copy string函数的函数体还可改为 while to from 67 3 copy string函数的函数体还可写成 while from to from to 4 由于字符可以用其 码来代替所以函数体可简化为 68 5 上面的while语句还可以进一步简化为下面的while语句 while to from 它与下面语句等价 while to from 将 from赋给 to 如果赋值后的 to值等于 则循环终止 已赋给 to 6 函数体中while语句也可以改用for语句 for to from 或for to from 69 7 也可以用字符数组名作函数形参 在函数中另定义两个指针变量p1 p2 函数 可写为voidcopy string charfrom char char from while p2 p1 10 4 3对使用字符指针变量和字符数组的讨论 字符数组和字符指针变量二者之间的区别主要有以下几点 70 1 字符数组由若干个元素组成 每个元素中放一个字符 而字符指针变量中存放的是地址 字符串第1个字符的地址 决不是将字符串放到字符指针变量中 2 赋值方式 对字符数组只能对各个元素赋值 不能用以下办法对字符数组赋值 charstr str IloveChina 而对字符指针变量 可以采用下面方法赋值 char IloveChina 71 3 对字符指针变量赋初值 char loveChina 等价于char IloveChian 而对数组的初始化 charstr loveChina 不能等价于charstr str IloveChina 72 4 定义了一个字符数组 在编译时为它分配内存单元 它有确定的地址 而定义一个字符指针变量时 给指针变量分配内存单元 在其中可以放一个字符变量的地址 例如 charstr scanf str 73 5 指针变量的值是可以改变的 例如 例10 19改变指针变量的值 includevoid char IloveChina printf 74 6 若字符指针变量p指向字符串 就可以用指针变量带下标的形式引用所指的字符串中的字符 如有 char a IloveChina 7 字符数组中各元素的值是可以改变的 可以对它们再赋值 但字符指针变量指向的字符串中的内容是不可以被取代的 不能对它们再赋值 如 chara House char b House a 2 r 合法 r取代u b 2 r 非法 字符串常量不能改变 75 10 指向函数的指针 10 5 1什么是函数指针 如果在程序中定义了一个函数 在编译时 编译系统为函数代码分配一段存储空间 这段存储空间的起始地址 又称入口地址 称为这个函数的指针 可以定义一个指向函数的指针变量 用来存放某一函数的起始地址 这就意味着此指针变量指向该函数 76 10 5 2用函数指针变量调用函数 如果想调用一个函数 除了可以通过函数名调用以外 还可以通过指向函数的指针变量来调用该函数 例10 20用函数求 和 中的大者 1 通过函数名调用函数 77 includevoidmain intmax int int int printf pleaseenteraandb scanf printf intmax int int int if else return 运行情况如下 pleaseenteraandb 3 10 a 3 b 10 max 10 78 将程序改写为 includevoidmain intmax int int int p int int inta b c p max printf pleaseenteraanbb scanf d d 2 通过指针变量来访问它指向的函数 79 例10 21输入两个整数 然后让用户选择1或2 选1时调用max函数 输出二者中的大数 选1时调用min函数 输出二者中的小数 includevoid intmax int int intmin int int int p int int inta b c n printf pleaseenteraandb scanf d d 80 elseif n 2 p min c p a b printf a d b d a b if n 1 printf max d n c elseprintf min d n c intmax intx inty intz if x y z x elsez y return z intmin intx inty intz if x y z x elsez y return z 运行情况如下 pleaseenteraandb 4 9 pleasechoose1or2 1 a 3 b 10 max 10再运行一次 pleaseenteraandb 4 9 pleasechoose1or2 2 a 3 b 10 min 3 81 10 5 3用指向函数的指针作函数参数 函数指针变量常用的用途之一是把指针作为参数传递到其他函数 指向函数的指针也可以作为参数 以实现函数地址的传递 这样就能够在被调用的函数中使用实参函数 82 实参函数名f1 voidfun int x1 int int x2 int int int 调用 函数 调用 函数 83 例10 22有两个整数 和 由用户输入1 2或3 如输入1 程序就给出 和 中大者 输入2 就给出 和 中小者 输入3 则求 与 之和 includevoidmain intmax int int 函数声明 intmin int int 函数声明 intadd int int 函数声明 intfun intx inty int p int int 函数声明 inta 34 b 21 n printf pleasechoose1 2or3 scanf d 84 intmin intx inty intz if x y z x elsez y printf min d return z intadd intx inty intz z x y printf sum d return z intfun intx inty int p int int intresout resout p x y printf d n resout 运行情况如下 pleasechoose1 2or3 1 34 pleasechoose1 2or3 2 1 pleasechoose1 2or3 3 13 85 10 返回指针值的函数 一个函数可以带回一个整型值 字符值 实型值等 也可以带回指针型的数据 即地址 其概念与以前类似 只是带回的值的类型是指针类型而已 这种带回指针值的函数 一般定义形式为类型名 函数名 参数表列 例如 int int 86 例10 23有若干个学生的成绩 每个学生有 门课程 要求在用户输入学生序号以后 能输出该学生的全部成绩 用指针函数来实现 includevoidmain float score 4 60 70 100 90 56 109 67 1010 34 710 90 66 float search float pointer 4 intn float int printf enterthenumberofstudent scanf printf ThescoresofNo are 87 search for printf float search float 4 int float return 运行情况如下 enterthenumberofstudent ThescoresofNo are 56 00109 0067 001010 00 88 10 7指针数组和多重指针 10 7 1指针数组的概念 一个数组 若其元素均为指针类型数据 称为指针数组 也就是说 指针数组中的每一个元素都相当于一个指针变量 一维指针数组的定义形式为 类型名 数组名 数组长度 例如 89 90 例10 24将若干字符串按字母顺序 由小到大 输出 include includevoidmain voidsort char name intn voidprintf char name intn char name Followme BASIC GreatWall FORTRAN Computerdesign int sort print 91 voidsort char int char int for for if strcmp name name 0 if temp name i name i name k name k temp 92 voidprint char int printf 运行结果为 ComputerdesignFORTRANFollowmeGreatWall 93 10 7 2指向指针数据的指针 定义一个指向指针数据的指针变量 的前面有两个 号 运算符的结合性是从右到左 因此 相当于 显然 是指针变量的定义形式 如果没有最前面的 那就是定义了一个指向字符数据的指针变量 现在它前面又有一个 号 表示指针变量 是指向一个字符指针变量的 就是 所指向的另一个指针变量 94 例10 25使用指向指针数据的指针变量 includevoidmain char name Followme BASIC GreatWall FORTRAN Computerdesign char int for printf 95 例10 26一个指针数组的元素指向整型数据的简单例子 includevoidmain int int num 5 a 0 a 1 a 2 a 3 a 4 int for printf 96 10 8动态内存分配与指向它的指针变量 10 8 1什么是内存的动态分配 前面介绍过全局变量和局部变量 全局变量是分配在内存中的静态存储区的 非静态的局部变量 包括形参 是分配在内存中的动态存储区的 这个存储区是一个称为栈 stack 的区域 除此以外 C语言还允许建立内存动态分配区域 以存放一些临时用的数据 这些数据是临时存放在一个的特别的自由存储区 称为堆 heap 区 97 10 8 2怎样建立内存的动态分配 对内存的动态分配是通过系统提供的库函数来实现的 主要有以下4个函数 1 函数 函数原型为void malloc unsignedintsize 作用是在内存的动态存储区中分配一个长度为 的连续空间 2 函数 函数原型为void calloc unsigned unsigned 作用是在内存的动态存储区中分配 个长度为 的连续空间 98 10 8 2怎样建立内存的动态分配 3 函数 函数原型为voidfree void p 作用是释放由指针变量 指向的动态空间 使这部分空间能被其他变量使用 4 realloc函数函数原型为void realloc void p unsignedintsize 如果已经通过malloc函数或calloc函数获得了临时分配域 想改变函数其大小 可以用recalloc函数重分配 99 10 8 3void指针类型 指针类型 允许定义一个基类型为 的指针变量 它不指向任何具体的数据 请注意 不要把 指向void类型 理解为能指向 任何的类型 的数据 而应理解为 指向空类型 或 不指向确定的类型 的数据 在将它的值赋给另一指针变量时要进行强制类型转换使之适合于被赋值的变量的类型 例如 inta 3 定义a为整型变量 int p1 错误 p2是无指向的 不能指向a 100 例10 27建立动态数组 输入5个学生的成绩 另外用一个函数检查其中有无低于60分的 输出不合格的成绩 include includevoidmain voidcheck int int p1 i void p2 p2 malloc 5 sizeof int p1 int p2 for i 0 i 5 i scanf d p1 i check p1 free p2 101 voidcheck int p inti printf Theyarefail for i 0 i 5 i if p i 60 printf d p i printf n 102
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!