




已阅读5页,还剩58页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第六章指针 计算机基础教研室 高级语言程序设计 本章主要内容 指针概述地址 指针 指针变量多重指针指针变量作为函数参数指针与数组数组 指针与函数调用行指针指针数组带参数的主函数指针与函数指向函数的指针变量返回指针值的函数 教学目的与要求了解指针与地址的概念了解指针与函数的概念掌握指针变量的定义 初始化及指针的运算掌握指针与数组 指针数组 二级指针等知识掌握指针作为函数参数的应用重点与难点指针与地址的概念指针与变量的关系指针与数组指针与字符串指针数组与二级指针指针的应用 一 指针概述 1 地址 address P201如果在程序中定义了一个 实体 变量 数组 函数 编译时系统就要给这些实体分配内存单元 分配规则 什么是内存单元 地址 内存单元是以字节为单位 每个字节都有一个编号 即 地址 如果将内存比作一个旅馆 内存单元就好比 床位 而实体则好比 旅客 这些 旅客 实体 中 有单人型 char 夫妇型 int 家庭型 float long double等 还有团体型 数组等 每个 实体 占用的内存单元是不同的 如 chara intb floatc intd 3 intmax 内存单元与地址 main chara intb floatc intd 3 intmax 地址 通常我们关心的不是各个内存单元的具体地址值 而是每个实体的 起始地址 如何表示实体地址 实体地址表示法1 直接访问 实体名 普通变量a b c a b c数组d 3 d 数组名 d 0 d 1 d 2 对二维数组 可用单下标法表示每行首地址 如对charx 3 4 可用x 0 x 1 x 2 分别表示其第一 二 三行的首地址 函数max max 函数名 入口地址 取地址运算符 适用于普通变量或数组元素 实体地址表示法2 间接访问 指针 适合于地址运算 加减等 2 指针 pointer 实体地址的一种表示法 便于编程处理 指针是一种特殊的数据类型 存放的是某个实体的地址值 变量的 指针 变量在内存单元的占用的地址 首地址 那为什么不就叫 地址 呢 实际上我们在C程序中用到的并不是代表地址的 指针 而是另有所指啊 3 指针变量P202 存放 指针 地址值 的特殊变量 定义方法 类型标识符 变量名如int a char b float c 通常在C语言中 所谓 指针 就是指 指针变量 从现在开始 我们所说的 指针 除非另加说明 否则均表示 指针变量 是不是说地址有 整型 字符型 实型 之分 为什么要使用指针变量 C程序中访问 读写 变量有两种方式 直接访问 按名单预留的座位入座 利用实体名访问变量 访问变量的过程 变量 实体 名 定义时分配的地址 变量值好比 先坐再买票 看电影 来一个观众 分配一个空位给他去坐 并且还要在纸上记一个某人坐在哪里 这种方式对用户来说很方便 直接就座 但对系统来说 找某人 就极不方便 间接 查名字 座号 间接访问 先买票 后按号入座 把变量地址先存放在 指针 中 再通过 指针 访问变量 好比先买票 票 指针 座号 地址 再 按号入座 看电影 这种方式对用户来说属于 间接就座 便对系统查找来说就很直接 且便于处理 尤其对于数组 团体 可通过指针简单自加或自减 对整个数组进行处理 习惯用语 若指针变量p存放了变量a的地址 我们称 p指向a 指针变量 不要谈 指 色变 指针是C语言学习中的一大难点 难 难在概念 main inta p1 p2 学了半天 我还是一头雾水 首先 搞定 p 请看以下变量声明语句inta p1 charb p2 a b普通变量 存放某个数值或字符 p1 p2指针变量 存放某个实体的地址 如果是int a p1 char b p2 变量声明时 如果变量名前带 号 表示该变量是个指针变量 注意 不同的 p 以下程序中哪些语句是错误的 main inta p a 3 p 3 或者p a p 或者 p 3 讨论 程序中引用变量时 对指针变量p 不带 号引用表示 带 号引用表示 两个特殊的运算符 变量名取该变量的地址 指针变量名取该地址处存放的值 有关 p的小结 变量声明时 p表示定义了一个用来存放变量地址而非数据 数值 字符等 的指针变量 程序中引用时 p表示取指针变量p所指变量的值 原来就这么简单 main inta p1 p2 p 并非就这么简单 p的含义与p所指的对象有关如果p被定义成指向普通变量的指针变量 则 p代表该变量的值 如int p a 5 p 则 p代表数组a中某个元素 看看两个例子 includemain inta b 10 p system cls p main int p a 12 1 2 3 4 5 clrscr p a for p 5 p printf d p 结果 a 13 b 10 结果 1234 p指向字符数组时的 p 如果p被定义成指向某个字符数组或某个字符串的指针变量 则 p代表某个字符 如int p a 3 abcd p a p代表a中的某个字符 main char p a 12 abcde p a for p p printf c p main char p p abcde for p p printf c p 如果直接用a进行循环 行不行 在for语句中用 p控制循环 是否适用于数值数组 与 组合使用时 若inta p p a a p 妙 和 可以互相 抵消 小考一下 如何 以下程序的运行结果是什么 main floatx y int p x 3 14 p 结果 y 2621 000000 怎么会这样 把int p改为float p后 结果正确 y 3 140000 指针变量能参加运算吗 指针变量和其他变量一样 可以在各种表达式中参加运算 但指针变量和普通变量不同 只能进行以下三种运算 赋值运算算术运算指针比较 指针变量的赋值运算 指针变量初始化变量声明时赋值 main inta 5 p printf d d d n p p a 指针变量一般赋值程序处理时赋值 结果 2000 5 5 main intx int p1 p2 p1 p以16进制显示指针 典型错误 指针变量定义后 未指向具体存储单元 实体地址 就使用 此时指针变量所指单元是任意的 是个 危险指针 例一 若有定义char p ch 则不能正确赋值的语句组是 A p 例二 若有定义char a b 30 则以下各语句正确的是 A a abcde B b abcde C scanf s a D scanf s b X X 字符串是一种特殊的实体 存放在内存用户区的常量区 为什么未指向实体的指针是 危险指针 危险指针 不要耸人听闻好不好 一个指针未指向任何实体就被使用 属于 内存盗用 因为该指针将随意指向内存中某一单元 轻则误取或破坏其他实体的值 重则破坏操作系统的工作 一个指针变量被声明后 在没有被赋予某个实体地址之前 如果使用它 不仅可能破坏你的程序 而且可能导致计算机操作系统崩溃 出现灾难性的错误 因为它可能指向内存的任何部分 空指针P256 空指针 int p p NULL NULL是什么 在stdio h中 定义 defineNULL0所以p NULL 相当于p 0 小姐 我把0号办公室分配给你 院长办公室给我 哼 空头人情 内存使用常识 任何C程序的变量在内存中的地址均由操作系统自动分配 不能由编程者通过赋值指定 p NULL表示p不指向任何变量 内存的低端只供由操作系统使用 相当于政府机关 普通百姓不能使用 讨论 以下程序中的 p1 p2 includemain int p1 NULL p2 clrscr p1 100 p2 200 printf d d n p1 p2 p1有确定地址 但未指向任何变量 p2无确定地址 是 危险指针 在指针p指向某个实体的地址之前 不可对 p进行赋值 否则可能发生意想不到的错误 p随便指向某个单元 指针变量的算术运算 指针只有两种算术运算 加 减p 5p p 1p 注意加减运算是以实体为单位而不是以字节为单位 此外 两个指针变量可以相减 即 如果两个指针变量指向同一数组时 两个指针变量值之差是两个指针之间的元素个数 参见P256 但两个指针变量相加并无实际意义 以下程序哪个语句执行时会出错 includemain inta 10 p1 a clrscr a p1 X 指针的逻辑比较P256 指针变量指向同一个对象 如数组 的不同单元地址时 才可以进行比较 地址在前者为小 任何指针变量或地址都可以与NULL作相等或不相等的比较 如if p NULL include includefun char w intn chart s1 s2 s1 w s2 w n 1 while s1 s2 t s1 s1 s2 s2 t main char p p 1234567 fun p strlen p puts p 结果 1711717 注意 对 s1 因 与 同级 且自右至左结合 所以等价于 s1 执行时是先做 s1 后做s1 P215 p 多重指针 指向指针的指针 P251 对于int p 定义一个二级指针 指向指针的指针 存放某个指针变量的地址 等效于int p 在引用时 p是p间接指向的对象的地址 p是p间接指向的对象的值 晕 用一个 声明一个变量pinta 5 p 使用时p带两个 是a的值 两重间接取值 p带一个 是a的地址 看了例子也许会明白的 以下程序段的输出是什么 int pp p a 20 b 30 pp 对不对 结果 30 30 多重间接取值 指针变量作为函数参数使用 main voidswap int int inta 5 b 3 p1 p2 clrscr p1 main voidswap int int inta 5 b 3 p1 p2 clrscr p1 再看一个例子 includefun int i staticinta 1 i a main intk 0 fun 结果 3 为了实现 在被调函数中改变实体值 然后在主调函数中使用这些改变了的实体值主要技术要点在于 主调函数的实参和被调函数对应的形参都必须用地址表示 地址传递 用于作实参的地址可以是 变量名 数组元素名 很少使用 数组名指针变量名对应的形参则为 数组定义指针定义 二 指针与数组 1 一维数组中的有关规定 defineN9main inta 10 i p clrscr p a for i 0 i N i scanf d Let stry 运行程序 观看结果在scanf语句中 分别用a i p i和 p i 代替 a i 试试 在printf语句中 分别用 a i p i 和p i 代替a i 试试 在p a语句中 用 a 0 代替a试试 有何感觉 我明白了 一维数组中p a时 p和a都可以相互替换 有一个地方不能替换 知道是什么地方吗 p 不能用a 替换 为什么 因为a是常量 5 即5 5 1是个低级错误 注意事项 注意指针变量当前值P214例10 6 注意不要超界 常见表示法 P215 p 等价于 p 先取 p值 然后p p p先自加 然后取 p的值 p 与 p 功能同上 小结 C语言的有关规定 对一维数组的数组名a 代表数组首地址 数组第一个元素a 0 的地址 即 a 则p和a在程序中实际上可以互相替换使用 p a 0 p a 0 p i a i p i a i 切记 p自加或自减不能用a自加或自减替换 试一试看 例 有inta 10 0 1 2 3 4 5 6 7 8 9 p a i 其中0 i 10 则对a数组元素不正确的引用是 A a p a B a i C p i D a i 答案 D 二维数组可以照此类推吧 不可以的 二维数组可要大伤脑筋了 二维数组就没这么简单了 2 二维数组中的有关规定二维数组的地址有 行地址 和 列地址 之分行地址表示是数组中的第几行 不带下标的数组名 行地址aa i a i a 1或a 1表示下移或上移一行列地址指第几个元素的地址 单下标或双下标 每行的首地址a 0 a i a 0 0 都是列地址列地址 1或列地址 1表示左移或右移一位 列地址是怎么回事 列地址 a 0 a i a 0 0 单下标或双下标 使用列地址时 是将整个二维数组看成同一行 遍历数组时用单循环实现 将数组元素排队处理 不妨看一个示例 includemain inta 3 3 1 2 3 4 5 6 7 8 9 int p i j 0 system cls p a for i 0 i 9 i printf d n a 0 1 Let stry 1 将a 0 改为a 1 a 2 a 0 0 a2 将注释标记去掉 行地址又是怎么回事呢 行地址 aa i a i 不带下标的数组名 使用行地址时 是将整个二维数组看成i行j列 遍历数组时用双循环实现 将数组元素分行列处理 使用行指针时 a和 a表示第0行的行地址a i和 a i 表示第i行的行地址 a i j表示第i行第j个元素的地址 a i j 表示第i行第j列元素值 a i j 看两个例子 includemain inta 3 3 1 2 3 4 5 6 7 8 9 int p i system cls p a for i 0 i 3 i printf d a i printf d d d n 改成 a i a i 分别试试再把 d改为 p试试 注意 二维数组中 a i a i与 a i 等价 P225 原因 a i不是变量 C规定a i a i与 a i 等价 P226 看一个例子 includemain inta 3 3 1 2 3 4 5 6 7 8 9 int p i j system cls p a for i 0 i 3 i for j 0 j 3 j printf d a i j 改成a i j 试试 用简单指针变量指向二维数组时 用简单指针变量指向二维数组时 inta 10 10 p p a p都是列地址性质的指针 姑且称 列指针 此时 p可与 排队法 中的a 0 互换使用 但不能与 行列法 中的a互换使用 比较一下 includemain inta 3 3 1 2 3 4 5 6 7 8 9 int p i system cls p a for i 0 i 9 i printf d n p i 123456789 换成 a 0 i 试试 再看下一个例子 includemain inta 3 3 1 2 3 4 5 6 7 8 9 int p i j system cls p a for i 0 i 3 i for j 0 j 3 j printf d a i j a改成p试试 讨论 如果将输出语句中的 a i j 改为 p i j 可不可以 不行 Why 因为p不是 行指针 行指针P229 形式 int p n 含义 p为指向含有n个元素的一维数组的指针变量 P255使用 二维数组可以视为由若干一维数组组成 行指针p是行地址性质的指针 此时 p可与 行列法 中的a互换使用 但不能与 排队法 中的a 0 互换使用 行指针是如何使用的 若inta 4 5 int p 5 p a 或p a 0 则 p 0 a 0 0 p 1 a 0 1 p 2 a 0 2 p 1 0 a 1 0 p 1 1 a 1 1 行指针是一种行地址 可以与二维数组用数组名表示的行地址互换使用 事实上 有 p i j p i j p i j a i j 示例一 main inta 3 3 1 2 3 4 5 6 7 8 9 int p 3 i j p a for i 0 i 3 i for j 0 j 3 j printf d p i j 结果 123456789 示例二 若有以下定义和语句 且0 i 4 0 j 3 则不能访问a数组元素的是 inti p 3 inta 3 1 2 3 4 5 6 7 8 9 10 11 12 p a A a i j B p i j C p i j D p j j 答案 D p j j是个地址 示例三 main chara 3 10 abc 123456 ABCDE char p 10 p a printf s s n p 1 p 1 printf c c c n p 1 p 2 1 p 2 1 结果 123456 1234561 B B 指针与字符串 例一 求以下程序的运行结果 main char pc Fujian Province while pc while pc pc if pc 0 break printf c pc pc printf n 结果 FujianProvince 指针与字符串 例二 以下函数的功能对应于 intfun char s char t while s A strlen s strlen t B strcmp s t C strcpy s t D strcat s t 结果 B 指针数组 定义 char p 5 功能 定义数组p 5 其每个元素p 0 p 1 p 4 都是指针变量 通常用于指向一组字符串 此时 对于p i 其下标表示第i个字符串 p i 本身是第i个字符串的首地址 示例 main char str AA BB CC str 1 str 2 printf s s s n str str 1 str 2 结果 AA CC CC 指针数组的典型应用P219 例一 已知TEST C的源程序如下 main intargc char argv while argc 1 printf s argv argc printf n 将该文件编译后 在命令行输入 testabc123则该程序运行结果是什么 结果 123abc 指针数组的典型应用P253 例二 以下程序经过编译连接后得到的可执行文件名为echo exe 在dos提示符下输入 则在屏幕上将显示Mycomputer includemain intargc char argv inti for i 1 i argc i printf s c argv i i argc 1 n A MycomputerB echoMycomputerC MycomputerD main Mycomputer 答案 B 三 指针与函数 1 指向函数的指针变量P241可以用指针变量指向一个函数 一个函数在编译时被分配给一个 入口地址 定义方法 类型标识符 指针变量名 如int p 指向一个返回整型值的函数用法 设有函数fun a b 令p fun 则有 p a b 相当
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 美丽拼音教学课件
- 员工感恩培训
- 技术部考试试题及答案
- 交通银行2025宿州市半结构化面试15问及话术
- 邮储银行2025白城市秋招面试典型题目及参考答案
- 中国银行2025黄石市秋招群面案例总结模板
- 2025年3D打印的金属成型工艺
- 2025年3D打印的药物递送系统
- 中国银行2025阳泉市笔试英文行测高频题含答案
- 农业银行2025成都市秋招群面案例总结模板
- 网络货运行业知识培训课件
- 人体十二经络系统解析
- 1.8《天气的影响》教学设计-教科版三上科学(新教材)
- 消防系统信号传输方案
- T-WHCIA 1008-2025 城市道路软弱土地基处理技术规程
- DB15∕T 3644-2024 国有企业阳光采购规范
- 2025年7月广东深圳市光明区审计局招聘专干1人笔试参考题库附答案解析
- 2025年交通安全宣传周知识竞赛考试题库及答案(含各题型)
- 2025年江西省赣州市《综合基础知识》事业单位招聘考试国考真题(附答案)
- 2025年云南文山交通运输集团公司招聘考试笔试试卷【附答案】
- 2025年深圳中级电工试题及答案
评论
0/150
提交评论