《清华大学_C++课程_第10讲指针(上)_376102715精编版》由会员分享,可在线阅读,更多相关《清华大学_C++课程_第10讲指针(上)_376102715精编版(40页珍藏版)》请在金锄头文库上搜索。
1、第10讲指针 上 参考教材的10 1到10 3节 指针是C 语言中的一个重要概念 掌握指针的用法 可使程序简洁 高效 灵活 不难学也不容易学 关键是理解下列故事含义 故事 很久很久以前 特务阿宝接到上级指令 要去寻找一个密钥 几经周折 线人告之 密钥藏在某墓地的看幕人所住的一栋小楼的房间中 一个风雨交加的夜晚 阿宝潜入了小楼 房间很多 不知该进哪一间 正在一筹莫展之际 忽然走廊上的电话铃声响起 艺高人胆大 阿宝毫不迟疑 抓起听筒 一个陌生人说 去打开小姐卧室 那里有线索 阿金疾步上楼 打开小姐卧室 用电筒一照 只见桌上赫然6个大字 1000房间 阿宝眼睛一亮 迅速找到1000房间 取出重要数据
2、66 密钥 完成任务 10 1指针的概念 指针 pointer 是内存中某存储单元的地址 编号 指针变量 也是内存中的一个变量 只是其值存放的是另一个变量的地址 10 1指针的概念 引进指针以后 变量的访问 访问是指取出其值或向它赋值 方式有两种 1 直接访问 通过变量名访问 如通过变量名i直接访问 2 间接访问 通过该变量的指针 地址 来访问 如通过i pointer访问变量i 张强 父亲 张强 儿子 余雨 母亲 10 2指针变量 指针变量 存放其他变量地址 指针 的变量指针变量有三个属性 1 指针变量指向的变量类型 如i pointer指向的变量i是整型 2 指针变量在内存中占多少内存单元
3、 如i pointer占两个内存单元 称为 近指针 用near表示 如果该变量在内存中占4个内存单元 称为 远指针 用far表示 如果未指定near或far 缺省是near 3 指针变量指向哪一个变量 即该指针变量的值 地址值 是多少 如i pointer的值是2000 10 2指针变量 指针变量定义的一般形式 基类型 标识符其中 表示定义指针变量 标识符 是指针变量名 基类型 表示该指针变量所指向的变量类型例 inti j 定义两个整型变量 int pointer 1 pointer 2 float pointer 3 char pointer 4 指针赋值例inta 66 定义一个整型变量
4、aint p q 定义p q为指向整型变量的指针变量p 将p的值赋给q 见图2 指针赋值 10 2指针变量 指针变量的赋值 方法1 例 pointer 1 10 2指针变量 指针变量的引用有两个运算符可以引用指针变量 1 10 2指针变量 说明 定义指针变量时 还未规定它指向哪一个变量 此时不能用 运算符访问指针 只有在程序中用赋值语句具体规定其指向变量后 才能用 运算符访问所指向的变量 inta int p 未规定指向哪个变量 p 100 这种错误称为访问悬挂指针 suspendedpointer 10 2指针变量 例1 输入a和b两个整数 按先大后小的顺序输出a和b 10 2指针变量 10
5、 3指针变量作为函数的参数 例2 输入a和b两整数 按先大后小顺序输出a和b 10 3指针变量作为函数的参数 程序执行过程的说明1 执行pointer 1 pointer 2 b后 pointer 1和pointer 2分别指向a和b 2 调用函数swap pointer 1 pointer 2 生成两个形参p1和p2 实参pointer 1的值传送给形参p1 因此p1也指向a 同理 p2指向b 10 3指针变量作为函数的参数 3 在swap 函数内 把 p1和 p2的值进行交换 p1是变量a p2是变量b 即把a和b的值进行交换 4 函数swap 调用结束后 形参p1 p2被释放 main中
6、得到的a和b是已经被交换的值 10 3指针变量作为函数的参数 intswap int p1 int p2 int p p p1 p1 p2 p2 p 使用指针变量 应注意避免指针悬挂 10 3指针变量作为函数的参数 函数swap 的形参是指针变量 有两种调用方式 swap pointer 1 pointer 2 swap 该函数交换形参的值 不能实现实参值的交换 因为在C语言中 实参和形参之间使用 传值法 数据只能单向由实参传到形参 形参值的变化不影响实参 10 3指针变量作为函数的参数 分析 下面的程序是否能达到交换的目的 intswap int p1 int p2 交换形参的值 int p
7、 p p1 p1 p2 p2 p main inta b int pointer 1 pointer 2 scanf d d 10 3指针变量作为函数的参数 小结 1 指针变量作为函数参数 可以使函数通过指针变量返回其所指向的变量值 从而实现主调函数和被调函数之间的数据双向传递2 以指针变量作函数的参数 实参和形参之间使用 地址值传递法 而且 地址值 也只能单向由实参传到形参 形参值的变化不影响实参 即不能改变实参指针变量本身的值 但可以改变实参指针变量所指向的变量的值 10 3指针变量作为函数的参数 例3 输入a b c三个整数 按大小顺序输出 10 3指针变量作为函数的参数 3 区分 运算
8、符在不同场合的作用 编译器能够根据上下文环境判别 的作用 inta b c p 表示定义指针 p 给指针p所指向的变量赋值 这里是给变量a赋值 10 4数组的指针变量 指针变量可以指向数组和数组元素 当指针指向数组后 对数组元素的访问 既可以使用数组下标 也可以使用指针 并且用指针访问数组元素 程序的效率更高 用下标访问数组元素程序更清晰 例如inta 10 元素为整型 floatb 10 元素为实型 int p 可以指向数组a的元素 float pf 可以指向数组b的元素 因此 以下语句均使指针p指向数组a p 把数组a的起始地址赋给p 不是把数组的全部元素赋给p 10 4数组的指针变量 通
9、过指针引用数组元素 10 4数组的指针变量 例4 输出整型数组的全部元素整型访问各元素有三种方法 1 下标法 常用 很直观 main inta 10 inti for i 0 i 10 i scanf d 10 4数组的指针变量 2 用数组名 指针法 计算数组元素的地址 效率与下标法相同 不常用 main inta 10 inti for i 0 i 10 i scanf d 10 4数组的指针变量 3 用指针变量访问各元素 常用 效率高 10 4数组的指针变量 使用指针指向数组 应注意以下问题 1 若指针p指向数组a 虽然p i与a i p i 与 a i 意义相同 但仍应注意p与a的区别
10、a代表数组的首地址 是不变的 p是一个指针变量 可以指向数组中的任何元素 例 inta 10 p for p a a p 10 a printf d a 是否正确 10 4数组的指针变量 10 4数组的指针变量 2 指针变量可以指向数组中的任何元素 注意指针变量的当前值 因此 使用指针时 应特别注意避免指针访问越界例如 本例中第二次for循环 p已经越过数组的范围 但编译器不能发现该问题 避免指针访问越界是程序员自己的责任 10 4数组的指针变量 3 指针使用的几个细节 设指针p指向数组a p a 则 p 或p 1 则 p p 表示什么意义 p 与 p 的分别表示什么意义 p 表示什么意义 1
11、0 4数组的指针变量 答案 p 或p 1 p指向下一个元素 p 相当于 p 因为 和 同优先级 是右结合运算符 p 与 p 的作用不同 p 先取 p 再使p加1 p 先使p加1 再取 p p 表示 p指向的元素值加1 小结 如果p当前指向数组a的第i个元素 则 p 相当于a i 先取 p 再使p减1 p 相当于a i 先取 p 再使 p减1 p 相当于a i 先使p加1 再取 p p 相当于a i 先使p减1 再取 p 10 4数组的指针变量 数组名和指针变量作函数参数 例 将数组a中n个元素按相反顺序存放 10 4数组的指针变量 voidinv intx intn 形参是数组 intt i
12、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 main staticinti a 10 3 7 9 11 0 6 7 5 4 2 printf theoriginalarray 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 4数组的指针变量 函数inv 可以用指针作形参 运行情况与用数组作形参相同 voidinv int x intn int
13、p t i j m n 1 2 i x 指针i指向数组第一个元素 j x n 1 指针j指向数组最后一个元素 p x m 指针p指向数组中间一个元素 for i p i j t i i j j t return 10 4数组的指针变量 10 4数组的指针变量 小结 数组作函数的参数 实参和形参之间传送数组的首地址 首地址可以用指针表示 也可以用数组名表示 因此 实参和形参有以下四种组合情况 组合情况实参形参1数组名数组名2数组名指针3指针指针4指针数组名 重点关注 需要了解直接访问和间接访问的含义 指针与指针变量的概念注意P172倒数第2段 仔细阅读和体会数组名实际是指针 但不是指针变量 指针做函数参数传递说明 本周上机考试 因此没有作业和实验要求