c语言程序设计第三版谭浩强第十章指针.ppt
《c语言程序设计第三版谭浩强第十章指针.ppt》由会员分享,可在线阅读,更多相关《c语言程序设计第三版谭浩强第十章指针.ppt(110页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第十章第十章10.110.1地址和指针的概念地址和指针的概念为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。内存区的每一个字节有一个编号,这就是“地址地址”。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。、按变量地址存取变量值的方式称为“直接访问直接访问”方式(,);(,);例如:例如:另一种存取变量值的方式称为“间接访问间接访问”的方式。即,将变量的地址存放在另一个变量中。在语言中,指针是一种特殊的变量,它是存放地址的。在语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量i_pointer用来存放整型变量的地址
2、,它被分配地址为(3010)、(3011)的两个字节。可以通过语句:i_pointer;将的地址(2000)存放到i_pointer中。这时,i_pointer的值就是(2000),即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer,从中取出的地址(2000),然后到2000、200字节取出的值()。一个变量的地址称为该变量的“指针指针”。例如,地址2000是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量指针变量”。上述的i_pointer就是一个指针变量。指针和指针变量的定义:指针和指针变量的定义:指
3、针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针”和“指针变量”这两个概念。10.2 10.2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量10.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为基类型基类型 *指针变量名;指针变量名;下面都是合法的定义:float *pointer_;/pointer_是指向float型变量的指针变量char*pointer_;/pointer_是指向字符型变量的指针变量可以用赋值语句使一个可以用赋值语句使一个指针变量得到另一个变指针变量得到另一个变量的地址,从而使它指量的地址,从而使它指向一个该变量。如:向一个该变
4、量。如:pointer_;pointer_;在定义指针变量时要注意两点:在定义指针变量时要注意两点:(1)指针变量前面的“*”,表示该变量的类型为指针型变量。(2)例:float *pointer_1;(3)指针变量名是pointer_1,而不是*pointer_1。(4)(2)在定义指针变量时必须指定基类型。(5)需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的(6)float a;(7)int *pointer_1;(8)pointer_1=&a;/*将float型变量的地址放到指向整型变量的指针变量中,错误*/10.指针变量的引用指针变量的引用 请
5、牢记,指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)赋给一个指针变量。例例10.通过指针变量访问整型变量通过指针变量访问整型变量#include voidmain()int,;int*pointer_,*pointer_;pointer_;/*把变量的地址赋给 pointer_1*/pointer_;/*把变量的地址赋给 pointer_*/printf(%,%,);printf(%,%,*pointer_,*pointer_);对“”和“*”运算符说明:如果已执行了语句 pointer_;(1)*pointer_的含义是什么?“”和“*”两个运算符的优先级别相同
6、,但按自右而左方向结合,因此先进行*pointer_的运算,它就是变量,再执行运算。因此,*pointer_与相同,即变量a的地址。如果有pointer_2*pointer_;它的作用是将(的地址)赋给pointer_2,如果pointer_2原来指向,经过重新赋值后它已不再指向了,而指向了。(2)*的含义是什么?先进行运算,得的地址,再进行*运算。即所指向的变量,也就是变量a。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价。(3)(*pointer_)相当于。注意括号是必要的,如果没有括号,就成为了*pointer_,从附录可知:+和*为同一优先级别,而结合方向为自右而左
7、,因此它相当于*(pointer_)。由于+在pointer_1的右侧,是“后加”,因此先对pointer_的原值进行*运算,得到的值,然后使pointer_的值改变,这样pointer_不再指向了。例例10.2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main()int*1,*2,*,;scanf(,);1;if();printf(=,=,);printf(max=,min=,*1,*2);运行情况如下:运行情况如下:,当输入,时,由于,当输入,时,由于,将和交换。交换前的情况见图将和交换。交换前的情况见图(),交换后见图
8、()。(),交换后见图()。10.3 指针变量作为函数参数指针变量作为函数参数例例10.3 对输入的两个整数按大小顺序输出对输入的两个整数按大小顺序输出#include void main()void s*,int*);int,;int*pointer_,*pointer_;scanf(,);pointer_;pointer_2;if(swap(pointer_,pointer_2);printf(,);void swap(int*,int*)int temp;temp*1;*;*temp;例例10.输入、输入、3个整数,按大小顺序输出个整数,按大小顺序输出#include void main
9、()void exchange(int*1,int*2,int*3);int ,*,*,*;scanf(%,%,%,&,&,&);exchange(,);printf(,);void exchange(int*,int*,int*)void swap(int*,int*);if(*)swap(,);if(*)swap(,);if(*swap(,);void swap(int*,int*)int temp;temp*;*;*temp;10.3 10.3 数组与指针数组与指针 一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当
10、然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元数组元素的指针就是数组元素的地址素的地址。定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:;(定义为包含个整型数据的数组)*;(定义为指向整型变量的指针变量)应当注意,如果数组为型,则指针变量的基类型亦应为型。10.3.1 10.3.1 指向数组元素的指针指向数组元素的指针对该指针变量赋值:对该指针变量赋值:;把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:10.通过指针引用数组元素通过指针引用数组元素引用一个数组元素,可以用:()()下标法,如形式;下标法,如形
11、式;()()指针法,如指针法,如*()或()或*()()。其中是数组名,是指向数组元素的指针变量,其初值。例例10.5 输出数组中的全部元素输出数组中的全部元素 假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:(1)下标法下标法#include void main()int;int;for(;)scanf(,);printf();for(;)printf(,);(2)通过数组名计算数组元素地址,找出元素的值。#include voidmain()int;int;for(;)scanf(,);printf();for(;)printf(,*();(3)用指针变量指向数组元素。#inc
12、lude void main()int;int *,;for(;)scanf(,);printf();for(;();)printf(,*);例例10.通过指针变量输出数组的个元素。通过指针变量输出数组的个元素。有人编写出以下程序:有人编写出以下程序:#include void main()int*,;for(;)scanf(,);printf();for(;,)printf(,*);这个程序乍看起来好像没有什么问题。有的人即使已被告知此程序有问题,还是找不出它有什么问题。我们先看一下运行情况:1 2 3 4 5 6 7 8 9 022153 234 0 0 30036 25202 11631
13、 8259 8237 28483显然输出的数值并不是数组中各元素的值显然输出的数值并不是数组中各元素的值 解决这个问题的办法,只要在第二个循环之前解决这个问题的办法,只要在第二个循环之前加一个赋值语句:加一个赋值语句:;#include void main()int*,;for(;)scanf(,);printg();p=a;for(;,)printf(,*);10.3 用数组名作函数参数用数组名作函数参数在第在第8章章8.7节中介绍过可以用数组名作函数的参数节中介绍过可以用数组名作函数的参数如:void main()i(int,int);int;(,);void(int,int)f(int
14、arr,int n)但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成f(int*arr,int n)以上两种写法是等价的。需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。例例10 将数组中个整数按相反顺序存放将数组中个整数按相反顺序存放#include void main()void inv(int ,int);int,;printf(The original array:);for(;)printf(,);prin
15、tf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();void inv(int ,int)/*/*形参形参形参形参x x是数组名是数组名是数组名是数组名*/*/int temp,();for(;);temp;temp;return;运行情况如下:The original array:,The array has been inverted:,#include void main()void inv(int*,int);int,;printf(The original array:);for(;)pr
16、intf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();对这个程序可以作一些改动。将函对这个程序可以作一些改动。将函数数inv中的形参改成指针变量。中的形参改成指针变量。void inv(int*,int)/*/*形参形参形参形参x x为指针变量为指针变量为指针变量为指针变量*/*/int,temp,*,*,();for(;,)emp*;*;*temp;return;归纳起来,如果有一个实参数组,想在函归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参数
17、中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:的对应关系有以下种情况:(1)形参和实参都用数组名,如:形参和实参都用数组名,如:void main()void (int ,int)int;(,);(2)实参用数组名,形参用指针变量。如:实参用数组名,形参用指针变量。如:void()void(int*,int)int ;(,);(3)实参形参都用指针变量。例如:实参形参都用指针变量。例如:void main()void(int*,int)int,*p=a;(p,);(4)实参为指针变量,形参为数组名。如:实参为指针变量,形参为数组名。如:void main()void(int x,
18、int),*p=a;(p,);#include void main()void inv(int*,int);int,*;printf(The original array:n);for(;,)scanf(,);printf();inv(,);/*实参为指针变量实参为指针变量*/printf(The array has been inverted:);for(;)printf(,*);printf();void inv(int*,int)int,temp,*,*;();for(;,)emp*;*;*temp;return;例例109 用选择法对个整数按由大到小顺序排序用选择法对个整数按由大到小顺
19、序排序#include void main()void sort(int ,int);int*,10;for(;)scanf(,);sort(,);for(,;)(,*);void sort(int ,int)int,;for(;);for(;)();(!);10.多维数组与指针多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。1.多维数组元素的地址多维数组元素的地址先回顾一下多维数组的性质,可以认为二维数组是“数组的数组”,例:定义定义int a34=1,3,5,7,;则二维数组a是由3个一维数组所组
20、成的。设二维数组的首行的首地址为 ,则表表 示示 形形 式式含义含义地地 址址a 二维数组名,指向一维数组a0,即0行首地址2000a0,*(a+0),*a0行0列元素地址2000a+1,&a11行首地址2008a1,*(a+1)1行0列元素a10的地址2008A1+2,*(a+1)+2,&a121行2列元素a12 的地址2012*(a1+2),*(*(a+1)+2),a121行2列元素a12的值元素值为13例例10.0 输出二维数组有关的值输出二维数组有关的值#include define FROMAT,void main()int 341,3,5,7,9,;printf(,*);print
21、f(,0,*();printf(,0,00);printf(,1,);printf(,10,*(+)+);printf(,*();printf(,);printf(,*(*();某一次运行结果如下:,(0行首地址和0行0列元素地址),(0行0列元素地址),(0行0首地址和0行0列元素地址),(1行0列元素地址和1行首地址),(1行0列元素地址),(2行0列元素地址),(2行首地址),(1行0列元素的值)2.指向多维数组元素的指针变量指向多维数组元素的指针变量在了解上面的概念后,可以用指针变量指向多维数组的元素。(1)指向数组元素的指针变量指向数组元素的指针变量例例10.11 10.11 用指针
22、变量输出二维数组元素的值用指针变量输出二维数组元素的值#include void main()int 341,3,5,7,9,11,13,15,17,19,21,23;int*;for(;)()printf();printf(,*);运行结果如下:1 3 5 7 9 11 13 1519 21 23 可将程序最后两个语句改为可将程序最后两个语句改为printf(addr,value2,*);在TC+环境下某一次运行时输出如下:,(2)指向由个元素组成的一维数组的指针变量指向由个元素组成的一维数组的指针变量例例10.13 10.13 出二维数组任一行任一列元素的值出二维数组任一行任一列元素的值#
23、include void main()int 1,3,5,7,9,11,13,15,;int(*),;scanf(,);printf(,*(*();运行情况如下:,(本行为键盘输入),运行情况如下:,(本行为键盘输入),3.用指向数组的指针作函数参数用指向数组的指针作函数参数例例10.13 有一个班,个学生,各学门课,计算总有一个班,个学生,各学门课,计算总平均分数以及第个学生的成绩。这个题目是很简单平均分数以及第个学生的成绩。这个题目是很简单的。只是为了说明用指向数组的指针作函数参数而举的。只是为了说明用指向数组的指针作函数参数而举的例子。用函数求总平均成绩,用函的例子。用函数求总平均成绩,
24、用函数找出并输出第个学生的成绩。数找出并输出第个学生的成绩。#include void main()void average(float*p,int n);void search(float(*p)4,int n);float score34=65,67,70,60,80,87,90,81,90,99,100,98;average(*score,12);*求12个分数的平均分*search(score,);*求序号为的学生的成绩*void average(float*,int)float*_;float,;_;(;_;)(*);printf(average,aver);void search(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计 第三 版谭浩强 第十 指针
限制150内