最全的C语言指针详解.ppt_第1页
最全的C语言指针详解.ppt_第2页
最全的C语言指针详解.ppt_第3页
最全的C语言指针详解.ppt_第4页
最全的C语言指针详解.ppt_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

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

文档简介

第6章指针 6 1指针定义与使用6 2指针与函数6 3指针与数组6 4指针与字符串6 5指针数组与多级指针6 6指针与动态内存分配6 7指针的深层应用 6 1指针的引出 一 地址与指针1 地址与取地址运算C程序中的变量在内存中占有一个可标识的存储区 每一个存储区是由若干个字节组成 每一个字节都有自己的地址 而一个存储区的地址是指该存储区中第一个字节的地址 C语言允许在程序中使用变量的地址 通过地址运算符数组变量a的地址 数组名a 2 指针与指针变量 1 变量的访问方式 直接访问 通过变量名或地址访问变量的存储区例 scanf d 间接访问 将一个变量的地址存放在另一个变量中 如将变量x的地址存放在变量p中 访问x时先找到p 再由p中存放的地址找到x 2012 1010 1010 2 指针 一个变量的指针就是该变量的地址 指针就是地址 3 指针变量 存放变量地址的变量 它用来指向另一个变量 二 指针变量的定义1 格式 数据类型 指针变量名 例int p1 char p2 2 说明 1 在变量定义时 号表示该变量是指针变量 注意 指针变量是p1 p2 不是 p1 p2 2 定义指针变量后 系统为其分配存储空间 用以存放其他变量的地址 但在对指针变量赋值前 它并没有确定的值 也不指向一个确定的变量 例 intx p x 5 2012 1010 5 1234 注 指针变量p的值是随机值 此时p和x并无关联 3 使指针变量指向一个确定的变量必须进行赋值 intx p x 5 p 2012 1010 5 1010 三 指针变量的引用1 指针运算符 1 p与 p不同 p是指针变量 p的值是p所指向的变量的地址 p是p所指向的变量 p的值是p所指向的变量的值 p的值为5 p表示x 而p的值为1010 2 引用指针变量时的 与定义指针变量时的 不同定义变量时的 只是表示其后的变量是指针变量 inta p p 2012 1010 5 1010 12 让p指向a 对a重新赋值等价于a 12 即 a 2 a a p a p p a 3 与 inta 2 b 5 c d p p的值为a的地址 p的值为2p的值不变 p的值为3 2 c p c p c p p 执行后c的值为3 p的值为5 3 d p d p p d p 执行后d的值为3 p的值为3 2012 1010 1010 1 p 等价于a 1012 3 3 1014 3 例6 2 includevoidmain int p1 p2 p a b scanf d d a b a b a 5 9 输出结果 a 5 b 9max 9 min 5 一 指针变量作函数参数 例 2个数按大小顺序输出 includevoidswap intx inty inttemp temp x x y y temp voidmain inta b scanf d d 5 说明 该程序不能实现a和b的交换因为实参a b对形参x y是 值传递 x和y的变化不影响a和b所以输出为 a 5 b 9 9 main swap 5 5 9 9 5 6 2指针与函数 例6 3 includevoidswap1 int p1 int p2 inttemp temp p1 p1 p2 p2 temp voidmain inta b pt1 pt2 scanf d d b a 5 说明 这种方法是交换p1和p2所指向的变量的值 即交换main函数中a和b的值所以输出为 a 9 b 5 main swap1 5 9 a b 9 5 例6 3 includevoidswap2 int p1 int p2 int temp temp p1 p1 p2 p2 temp 说明 这种方法可能会破坏系统的正常工作状态 因为temp是一个指针变量但是在函数中并没有给temp一个确定的地址 这样它所指向的内存单元是不可预见的 而对 temp的赋值可能带来危害 main a b b a swap2 随机值 5 5 9 5 9 例6 3 includevoidswap3 int p1 int p2 int p p p1 p1 p2 p2 p a a b 这种方法是交换形参p1和p2的值 使它们的指向发生改变 但是main函数中的a和b的值并没有进行交换所以输出为 a 5 b 9 b a swap3 前面我们用到的函数 有些无返回值 有些有返回值 返回值类型多为int float char 一个函数的返回值也可以是一个指针类型的数据 即地址 定义函数 数据类型 函数名 形参表列 函数体 例 int fun inta intb 函数体 说明 定义一个返回指针值的函数与以前定义函数格式基本类似 只是在函数名前加 它表明该函数返回一个指针值 而这个指针值是指向一个int型数据 二 函数返回指针 例 include include defineSIZE100charbuf SIZE char p buf char alloc intn char begin if p n buf SIZE begin p p p n return begin elsereturn NULL voidmain char p1 p2 inti p1 alloc 10 strcpy p1 123456789 p2 alloc 5 strcpy p2 abcd printf buf p n buf printf p1 p n p1 printf p2 p n p2 puts p1 puts p2 for i 0 i 15 i printf c buf i buf 0 buf 1 buf 9 buf 10 buf 14 buf 15 buf 99 buf 10 buf buf buf 10 12 9 0 a 0 10 buf 15 buf 10 5 函数的指针 函数的入口地址在程序执行过程中调用函数时 计算机会转去执行函数体内的语句 因此计算机必须知道函数在什么地方 实际上函数在内存中也要占据一片存储单元 这片存储单元一个起始地址 我们称其为函数的入口地址 即函数的指针 这个函数的入口地址是用函数名来表示 因此我们可以定义一个指针变量 让它的值等于函数的入口地址 然后可以通过这个指针变量来调用函数 该指针变量称为指向函数的指针变量 三 指向函数的指针 指向函数的指针变量1 定义格式 数据类型 指针变量名 形参表列 int pt intarr intn 说明 数据类型 指针变量所指向的函数的返回值类型 形参表列 即指针变量所指向的函数的形参表列 格式中的小括号不能省略 2 应用 1 让指针变量指向函数pt add 因为函数名为函数的入口地址 所以直接将函数名赋给指针变量即可 2 使用指针变量调用函数格式 指针变量名 实参表列 例求一维数组中全部元素的和 includeintadd intb intn voidmain inta 6 1 3 5 7 9 11 total int pt intb intn pt add total pt a 6 printf total d n total intadd intb intn inti sum 0 for i 0 i n i sum sum b i return sum 定义指向函数的指针变量 令指针变量pt指向函数add 通过pt调用函数add 6 3指针与数组 一 一维数组与指针1 一维数组及元素的地址表示inta 5 1 2 3 4 5 数组的地址 a 2 用指针变量引用数组元素 1 定义指针变量int p a 5 1 2 3 4 5 p a 2 引用数组元素 注意 指针变量也可以加下标p k 等价于a k 分别用三种方法输出数组元素 其效率不同 下标法与地址法的效率相同 指针法的效率较快 用指针变量访问数组元素时要注意下标是否越界 例 将数组a中全部元素加1 再输出a includevoidmain inta 5 1 3 5 7 9 p j for p a p a 5 p printf 3d p printf n for j 0 j 5 j a j a j 1 for j 0 j 5 j printf 3d p j printf n p a aa 1a 2a 3a 4 2 4 6 8 10 可以用p 但不能用a 因为a代表数组的起始地址它是地址常量 不能改变而p是一个指针变量 使用指针变量时要注意它的当前值 3 指向数组的指针变量作函数参数 例6 7 实参和形参都用数组名 includevoidinv1 intx intn inttemp i j m n 1 2 for i 0 i m i j n 1 i temp x i x i x j x j temp voidmain inti a 6 1 3 4 6 7 9 inv1 a 6 for i 0 i 6 i printf 3d a i printf n a 0 a 1 a 2 a 3 a 4 a 5 x 0 x 1 x 2 x 3 x 4 x 5 main inv1 例6 7 实参用数组名 形参用指针变量 includevoidinv2 int x intn inttemp m n 1 2 int p i j i x j x n 1 p x m for i p i j temp i i j j temp voidmain inti a 6 1 3 4 6 7 9 inv2 a 6 for i 0 i 6 i printf 3d a i printf n a 0 a 1 a 2 a 3 a 4 a 5 inv2 9 1 7 3 6 4 1 a 1 a 4 a 2 a 3 3 4 i和j的指向会变化 p的指向保持不变 例6 7 实参和形参都用指针变量 includevoidinv3 int x intn voidmain int p a 6 1 3 4 6 7 9 p a inv3 p 6 for p a p a 6 p printf 3d p printf n voidinv3 int x intn inttemp m n 1 2 int p i j i x j x n 1 p x m for i p i j temp i i j j temp 例6 7 实参用指针变量 形参用数组名 includevoidinv4 intx intn voidmain int p a 6 1 3 4 6 7 9 p a inv4 p 6 for p a p a 6 p printf 3d p printf n voidinv4 intx intn inttemp i j m n 1 2 for i 0 i m i j n 1 i temp x i x i x j x j temp 例6 8求数组中最大和最小元素 includeintmax min voidm1 intarr intn int p end end arr n max min arr for p arr 1 pmax max p elseif p min min p voidmain inti a 6 for i 0 i 6 i scanf d a 0 a 1 a 2 a 3 a 4 a 5 471905 4 4 7 9 1 0 二 二维数组与指针 二维数组的定义 对于二维数组a 首先可以把它先理解为一个一维数组 它有3个元素 a 0 a 1 a 2 而每一个元素又是一个一维数组 包含4个元素如a 0 是一维数组 它有4个元素 a 0 0 a 0 1 a 0 2 a 0 3 a 3 4 a 0 a 1 a 2 只是一种地址表示方法 并不真的二维数组元素 可以看作是第二重一维数组的名字 二维数组的初始化 1 可以分行给二维数组赋初值 inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 1234 5678 9101112 2 可以将所有数据写在一个花括号中 按顺序对各元素赋初值 inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 二维数组的初始化 3 可以对部分元素赋初值 其余元素补0 inta 3 4 1 5 9 inta 3 4 1 0 6 0 0 11 4 如果对全部数据都赋初值 则定义时第一维的长度可以不指定 但第二维的长度不能省 inta 4 1 2 3 4 5 6 7 8 9 10 11 12 二维数组的初始化 如果只对部分数据赋初值 第一维的长度也可以不指定 但元素必须分行赋初值 inta 4 0 0 3 0 10 二维数组的地址 二维数组名a表示二维数组的首地址 也是第0个元素 a 0 的地址 a 1代表第1个元素 a 1 的地址a 1 a 1 a 2代表第2个元素 a 2 的地址a 2 a 2 a a 0 a 0 a 1 a 2 既然是第二重一维数组名 它们就代表了相应一维数组的首地址 因此a 0 代表了第0行第0列元素的地址 即 二维数组的地址 a 1 a 1 0 a 1 2 a 1 2 a 2 a 2 0 a 2 3 a 2 3 a 0 a 0 0 a 0 1 a 0 1 Question 二维数组的地址 因a a 0 所以 a a 0 a 0 a 0 0 即 a表示元素a 0 0 的地址 a 1表示元素a 0 1 的地址 a 1 表示元素a 1 0 的地址 a 2 3表示元素a 2 3 的地址 二维数组的地址 小结 二维数组名a代表二维数组的首地址 即 第0行的地址为a a 0 第1行的地址为a 1 a 1 第2行的地址为a 2 a 2 二维数组元素的地址 指向二维数组元素的指针 例1 用指针变量输出二维数组中的元素 Quizp a p includevoidmain inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 int p for p a 0 p a 0 12 p printf d p printf n 指向二维数组元素的指针 inta 3 4 int p p a 合法吗 intx 36 q p q 2010 2026 p是二级指针 它指向一个整型指针变量q 而q指向一个整型变量 a是一种地址表示方法 a实际指向了第一重一维数组元素a 0 而a 0 是第二重一维数组 非法 指向二维数组元素的指针 定义格式 类型名 指针变量名 数组长度 inta 3 4 int p 4 p a p指向一个包含有4个整型数据的一维数组 合法 虽然在定义p的时候只用了一个 但p实际上是一个二级指针变量 指向二维数组元素的指针 例2 输出二维数组中的元素 includevoidmain inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 int p 4 i j p a for i 0 i 3 i for j 0 j 4 j printf 6d p i j printf n 指向二维数组元素的指针 二维数组用得较多的是 字符串数组 配合字符串的操作 使字符串处理更加方便 灵活 chara 4 256 Pascal VC Basic Java Pascal Vc Basic Java include include defineMAXLEN256 defineN4voidmain inti j chartemp MAXLEN charname N MAXLEN Pascal VC Basic Java for i 0 i N i puts name i 书的数量 for i 0 i0 strcpy temp name i strcpy name i name j strcpy name j temp 选择法排序 书名的最大长度 1 指向二维数组元素的指针 比较两个字符串大小 复制字符串 Quiz选择法排序 Assignment 1 将数组a 2 3 中的每个元素向右移一列 最后一列换到最左一列 如右图所示 要求 必须用指针实现 2 将数组a M N 中的每个元素向右移一列 最后一列换到最左一列要求 必须用指针实现 Experiment 实验题目 指向二维数组的指针编程实验目的 深入理解如何用指针变量表示二维数组的元素和元素的地址 学会用指向二维数组的指针变量作函数参数实验内容 编程找出二维数组中的鞍点 二维数组的鞍点是指在该位置上的元素在该行上最大 在该列上最小 也可能没有鞍点 要求必须用指针实现 编写一个找鞍点的函数 用指向二维数组的指针变量作函数参数 6 4指针与字符串 一 字符指针1 定义指向字符串的指针变量char p China 说明 这里没有定义字符数组 但字符串在内存中还是以数组形式存放的 字符串在内存中占有一片连续的存储单元 以 0 结束 注意 赋值只是把字符串的首地址赋给p 而不是把字符串赋给p p是一个指针变量 它不能存放一个字符串 只能存放一个地址 246024612462246324642465 将字符串的首地址赋给p 2

温馨提示

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

评论

0/150

提交评论