第10章-指针课件.ppt

上传人(卖家):三亚风情 文档编号:3165885 上传时间:2022-07-27 格式:PPT 页数:132 大小:868.01KB
下载 相关 举报
第10章-指针课件.ppt_第1页
第1页 / 共132页
第10章-指针课件.ppt_第2页
第2页 / 共132页
第10章-指针课件.ppt_第3页
第3页 / 共132页
第10章-指针课件.ppt_第4页
第4页 / 共132页
第10章-指针课件.ppt_第5页
第5页 / 共132页
点击查看更多>>
资源描述

1、1 1、指针变量的定义、引用、指针变量的定义、引用2 2、指针变量的初始化及运算、指针变量的初始化及运算3 3、指向数组的指针变量、指向数组的指针变量4 4、指向字符串的指针变量、指向字符串的指针变量5 5、指针数组、二级指针、指针数组、二级指针6 6、指向函数的指针、指向函数的指针10.110.1地址和指针的概念地址和指针的概念 为了说清楚什么是指针,必须弄清楚数据在内为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。存中是如何存储的,又是如何读取的。内存区的每一个字节有一个编号,这就是内存区的每一个字节有一个编号,这就是“地地址址”。如果在程序中定义了一个变量,在对

2、程序进。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配行编译时,系统就会给这个变量分配相应的相应的内存单内存单元。元。假设程序已定义了假设程序已定义了3 3个整型变量个整型变量i i、j j、k k,编译,编译时系统分配时系统分配20002000和和20012001两个字节给变量两个字节给变量i i,20022002,20032003字节给字节给j j,20042004,20052005给给k k。、通过变量名来对内存单元进行存取操作。、通过变量名来对内存单元进行存取操作。程序经过编译后己经将变量名转换为变程序经过编译后己经将变量名转换为变量的地址,按变量地址存取变量值

3、的方量的地址,按变量地址存取变量值的方式称为式称为“直接访问直接访问”方式方式 访问方式:访问方式:k=i+j;k=i+j;的执行是:的执行是:从从2000、2001字节取出字节取出i的值的值(3),再从,再从2002、2003字节取出字节取出j的值的值(6),将,将它们相加后再将其和它们相加后再将其和(9)送到送到k所占用的所占用的2004、2005字节单元中。字节单元中。例如:例如:printf(%d,i);printf(%d,i);的执行是:的执行是:根据变量名与地根据变量名与地址的对应关系址的对应关系(这个对应关系是在编译时确定的这个对应关系是在编译时确定的),找到变量找到变量i i的

4、地址的地址20002000,然后从由,然后从由20002000开始的两开始的两个字节中取出数据个字节中取出数据(即变量的值即变量的值3)3),把它输出。,把它输出。scanf(%d,&i);scanf(%d,&i);的执行是:的执行是:把从键盘输入把从键盘输入的值送到地址为的值送到地址为2000开始的整型存储单元中。开始的整型存储单元中。2 2、另一种存取变量值的方式称为、另一种存取变量值的方式称为“间接访问间接访问”方式。即将变量的地址存放在另一个变方式。即将变量的地址存放在另一个变量中。然后通过这个变量去访问变量量中。然后通过这个变量去访问变量i i。在语言中在语言中,可以定义一种特殊的变

5、量可以定义一种特殊的变量,它是专门用来存放其它变量地址的。这种变量它是专门用来存放其它变量地址的。这种变量称为称为“指针变量指针变量”假设我们定义了一个指针变量假设我们定义了一个指针变量i_pointeri_pointer用用来存放整型变量的地址,它被分配地址为来存放整型变量的地址,它被分配地址为(3010)(3010)、(3011)(3011)的两个字节。的两个字节。可以通过语句:可以通过语句:i i_pointer_pointer ;将将i i的地址的地址(2000)(2000)存放到存放到i_pointeri_pointer中。中。这时,这时,i_pointeri_pointer的值就是

6、的值就是(2000)(2000),即变量,即变量所占用单元的起始地址。所占用单元的起始地址。要存取变量的值,可以采用间接方式:先要存取变量的值,可以采用间接方式:先找到存放找到存放 “的地址的地址”的变量的变量 i i_pointer_pointer ,从中取出的地址从中取出的地址(2000)(2000),然后到,然后到2000 2000、20012001字节取出的值字节取出的值()。打个比方,为了开一个打个比方,为了开一个A A抽屉,有两种抽屉,有两种办法:办法:一种是将一种是将A A钥匙带在身上,需要时直接钥匙带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西。找出该钥匙打开抽屉,取出

7、所需的东西。另一种办法是:为安全起见,将该另一种办法是:为安全起见,将该A A钥钥匙放到另一抽屉匙放到另一抽屉B B中锁起来。如果需要打开中锁起来。如果需要打开A A抽屉,就需要先找出抽屉,就需要先找出B B钥匙,打开钥匙,打开B B抽屉,取抽屉,取出出A A钥匙,再打开钥匙,再打开A A抽屉,取出抽屉,取出A A抽屉中之物,抽屉中之物,这就是这就是“间接访问间接访问”。直接访问直接访问将将3送到变量送到变量i所标志的单元中。所标志的单元中。间接访问间接访问将将3送到变量送到变量i_pointeri_pointer所所“指指向向”的单元的单元(即即i所标志的单元所标志的单元)中。中。所谓所谓“

8、指向指向”就是通过地址来体现的。就是通过地址来体现的。i_pointei_pointer r中的值为中的值为20002000,它是变量,它是变量i i的地址,这样通过的地址,这样通过i_pointeri_pointer能知道能知道i i的地址,从而找到变量的地址,从而找到变量i i的内存单元。即由于通的内存单元。即由于通过地址能找到所需的变量单元,我们可以说,地址过地址能找到所需的变量单元,我们可以说,地址“指指向向”该变量单元该变量单元(如同说,房间号如同说,房间号“指向指向”某一房间一某一房间一样样)。一个变量的地址称为该变量的一个变量的地址称为该变量的“指针指针”。例如,地址例如,地址2

9、0002000是变量的指针。是变量的指针。如果有一个变量如果有一个变量专门用来存放另一变量的地址专门用来存放另一变量的地址(即指针即指针),则它称为,则它称为“指针变量指针变量”。上述的上述的i_pointeri_pointer就是一个指针变就是一个指针变量。量。指针和指针变量的定义:指针和指针变量的定义:指针变量的值指针变量的值(即指针变量中存放的值即指针变量中存放的值)是地址是地址(即指针即指针)。请区分。请区分“指针指针”和和“指针变量指针变量”这两个这两个概念。概念。例如,可以说变量例如,可以说变量i i的指针是的指针是20002000,而不能说,而不能说i i的指针变量是的指针变量是

10、20002000。10.2 10.2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量 变量的指针就是变量的地址。变量的指针就是变量的地址。存放变量地存放变量地址的变量是指针变量,用来指向另一个变量。址的变量是指针变量,用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联为了表示指针变量和它所指向的变量之间的联系,在程序中用系,在程序中用“*”符号表示符号表示“指向指向”,例,例如:如:i_pointeri_pointer代表指针变量,而代表指针变量,而*i_pointeri_pointer是是i_pointeri_pointer所指向的变量,如下图。所指向的变量,如下图。

11、10.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为:定义指针变量的一般形式为:基类型基类型 *指针变量名;指针变量名;下面都是合法的定义:下面都是合法的定义:float float *pointer_3pointer_3;/pointer_3/pointer_3是指向是指向floatfloat型变量的指针变量型变量的指针变量 char char*pointer_4pointer_4;/pointer_4/pointer_4是指向字符型变量的指针变量是指向字符型变量的指针变量 可以用赋值语句使一个指针变量得到另一个变量可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向

12、一个该变量。如:的地址,从而使它指向一个该变量。如:pointer_1pointer_1&i&i;pointer_2pointer_2&j&j;在定义指针变量时要注意两点:在定义指针变量时要注意两点:(1)(1)指针变量前面的指针变量前面的“*”,表示该变量的类型为指,表示该变量的类型为指针型变量。针型变量。例例:float float *pointer_1pointer_1;指针变量名是指针变量名是pointer_1pointer_1 ,而不是,而不是*pointer_1 pointer_1 。(2)(2)在定义指针变量时必须指定基类型。在定义指针变量时必须指定基类型。需要特别注意的是,只有

13、整型变量的地址才能放到需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的指向整型变量的指针变量中。下面的赋值是错误的 float a;float a;int int *pointer_1;pointer_1;pointer_1=&a;/pointer_1=&a;/*将将floatfloat型变量的地址放到型变量的地址放到指向整型变量的指针变量中,错误指向整型变量的指针变量中,错误 */10.指针变量的引用指针变量的引用 请牢记,指针变量中只能存放地址请牢记,指针变量中只能存放地址(指指针针),不要将一个整数,不要将一个整数(或任何其他非地址类或任何其他非地

14、址类型的数据型的数据)赋给一个指针变量。赋给一个指针变量。下面的赋值是不合法的:下面的赋值是不合法的:pointer-1=100;pointer-1=100;(pointer-1(pointer-1为指针变量,为指针变量,100100为整数为整数)有两个有关的运算符:有两个有关的运算符:(1)&(1)&:取地址运算符。:取地址运算符。(2)(2)*:指针运算符:指针运算符(或称或称“间接访问间接访问”运算符运算符)。例如:例如:&a&a为变量为变量a a的地址,的地址,*p p为指针变量为指针变量p p所指所指向的存储单元。向的存储单元。例例10.通过指针变量访问整型变量通过指针变量访问整型变

15、量#include stdio#include stdio.h.hvoidvoidmainmain()()intint a,b;a,b;int int*pointer_1,pointer_1,*pointer_2pointer_2;a=100;b=10;a=100;b=10;pointer_1=&a;pointer_1=&a;/*把变量把变量a a的地址赋给的地址赋给pointer_1 pointer_1*/pointer_2=&b;pointer_2=&b;/*把变量把变量b b的地址赋给的地址赋给pointer_2pointer_2*/printf(%d,%dna,b);printf(%d

16、,%dna,b);printf(%d,%dn,printf(%d,%dn,*pointer_1,pointer_1,*pointer_2pointer_2););表示定义两个指针变量表示定义两个指针变量pointer_1、pointer_2。表示表示pointer_1和和pointer_2所指向的变量。所指向的变量。注意区分注意区分注意注意:不应写成不应写成 *pointer_1=&a;pointer_1=&a;*pointer_2=&b;pointer_2=&b;对对“&”&”和和“*”运算符说明:运算符说明:如果已执行了语句如果已执行了语句 pointer_1=&a;pointer_1=&

17、a;(1)(1)*pointer_1pointer_1的含义是什么?的含义是什么?“”和和“*”两个运算符的优先级别相同,但两个运算符的优先级别相同,但按自右而左方向结合,因此先进行按自右而左方向结合,因此先进行*pointer_1pointer_1的运算,的运算,它就是变量它就是变量a a,再执行,再执行&运算。运算。因此,因此,&*pointer_1pointer_1与与&a&a相同,即变量相同,即变量a a的地址。的地址。如果有如果有pointer_2=&pointer_2=&*pointer_1pointer_1;它的作用是将;它的作用是将&a&a(a a的地址的地址)赋给赋给poin

18、ter_2pointer_2,如果,如果pointer_2pointer_2原来指向原来指向b b,经过重新赋值后它已不再指向经过重新赋值后它已不再指向b b了,而指向了了,而指向了a a。如下图如下图(2)(2)*&a&a的含义是什么?的含义是什么?先进行先进行&a&a运算,得运算,得a a的地址,再进行的地址,再进行*运算。运算。即即&a所指向的变量,也就是变量所指向的变量,也就是变量a a。*&a和和*pointer_pointer_的作用是一样的,它们都等价于变的作用是一样的,它们都等价于变量量a a。即。即*&a与与a a等价。等价。(3)(3)(*pointer_1)+pointe

19、r_1)+相当于相当于a+a+。注意括号是必要的,如果没有括号,就成注意括号是必要的,如果没有括号,就成为了为了*pointer_1+pointer_1+,从附录可知:,从附录可知:+和和*为同一为同一优先级别,而结合方向为自右而左。因此它相优先级别,而结合方向为自右而左。因此它相当于当于*(pointer_1+)(pointer_1+)。由于。由于+在在pointer_1pointer_1的的右侧,是右侧,是“后加后加”,因此先对,因此先对pointer_1pointer_1的原值的原值进行进行*运算,得到运算,得到a a的值,然后使的值,然后使pointer_1pointer_1的值的值改

20、变,这样改变,这样pointer_1pointer_1不再指向不再指向a a了。了。例例10.2 输入输入a和和b两个整数,按先大后小的顺序输出两个整数,按先大后小的顺序输出 a和和b。#include#include stdio.hstdio.hvoid void mainmain()()intint *p1,p1,*p2,a,b;p2,a,b;scanf(%d,%d,&a,&b);scanf(%d,%d,&a,&b);p1=&a;p2=&b;p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;if(ab)p=p1;p1=p2;p2=p;printf(a=%d,b=%dnn,

21、a,b);printf(a=%d,b=%dnn,a,b);printf(printf(max=%d,min=%dn,max=%d,min=%dn,*p1,p1,*p2);p2);指针变量应用例子指针变量应用例子运行情况如下:运行情况如下:5,9 a=5,b=9 max=9,min=5当输入当输入a=5,b=9时,由于时,由于ab,将,将p1和和p2交换。交换前交换。交换前的情况见图的情况见图(a),交换后见图,交换后见图(b)。注意:注意:a a和和b b并未交换,它们仍保持原值,但并未交换,它们仍保持原值,但p1p1和和p2p2的的值改变了。值改变了。p1p1的值原为的值原为&a&a,后来变

22、成,后来变成&b&b,p2p2原值为原值为&b&b,后来变成后来变成&a&a。这个问题的算法不是交换整型变量的值,而这个问题的算法不是交换整型变量的值,而是交换两个指针变量的值是交换两个指针变量的值(即即a a和和b b的地址的地址)。10.3 指针变量作为函数参数指针变量作为函数参数例例10.3 对输入的两个整数按大小顺序输出对输入的两个整数按大小顺序输出#include#include void main()void main()void swap(int void swap(int*p1,int p1,int*p2);p2);int a,b;int a,b;int int*pointer

23、_1,pointer_1,*pointer_2;pointer_2;scanf(%d,%d,&a,&b);scanf(%d,%d,&a,&b);pointer_1=&a;pointer_2=&b;pointer_1=&a;pointer_2=&b;if(ab)swap(pointer_1,pointer_2);if(ab)swap(pointer_1,pointer_2);printf(n%d,%dn,a,b);printf(n%d,%dn,a,b);void swap(int void swap(int*p1,int p1,int*p2)p2)int temp;int temp;temp=t

24、emp=*p1;p1;*p1=p1=*p2;p2;*p2=temp;p2=temp;注意:注意:本例采取的方法是,交换本例采取的方法是,交换a a和和b b的值,而的值,而p1p1和和p2p2的值不变。这恰和例的值不变。这恰和例10.210.2相反。相反。如果写成以下这样会怎样?如果写成以下这样会怎样?void swap1(void swap1(int int*p1p1,intint *p2)p2)int temp int temp;*temp=temp=*p1;p1;p1 p1=*p2;p2;p2 p2=*temp;temp;请注意交换请注意交换*p1p1和和*p2p2的值是如何实现的。的值

25、是如何实现的。*p1p1就是就是a a,是整型变量。而,是整型变量。而*temptemp是指针变量是指针变量temptemp所指向的变量。但所指向的变量。但temptemp中并无确定的地址值,它的值中并无确定的地址值,它的值是不可预见的,是不可预见的,*temptemp所指向的单元也是不可预见的。所指向的单元也是不可预见的。因此,对因此,对*temptemp赋值可能会破坏系统的正常工作状况。赋值可能会破坏系统的正常工作状况。此语句有问题此语句有问题 应该将应该将*p1p1的值的值赋给一个整型变量,赋给一个整型变量,如程序所示那样,用如程序所示那样,用整型变量整型变量temptemp作为临作为临

26、时辅助变量实现时辅助变量实现*p1p1和和*p2p2的交换。的交换。这个改变不是通过将形参值传回实参来实现的。这个改变不是通过将形参值传回实参来实现的。而是因实参和形参都是指针变量,实参传递给形参后,而是因实参和形参都是指针变量,实参传递给形参后,实参和形参指向共同的变量,在被调用函数中,交换实参和形参指向共同的变量,在被调用函数中,交换了形参指针所指向的变量值,也即是交换了实参指针了形参指针所指向的变量值,也即是交换了实参指针所指向变量的值。所指向变量的值。例例10.310.3中,在执行中,在执行SwapSwap函数后,变量函数后,变量a a和和b b的值改的值改变了。这个改变是怎么实现的?

27、变了。这个改变是怎么实现的?能否通过下面的函数实现能否通过下面的函数实现a a和和b b的互换。的互换。void swap2(int xvoid swap2(int x,int y)int y)int temp;int temp;temp=x;temp=x;x=y;x=y;y=temp;y=temp;如果在如果在mainmain函数中调用函数中调用Swap2Swap2函数:函数:swap(a,b);swap(a,b);会有什么结果呢?会有什么结果呢?如图所示。在函数调用时,如图所示。在函数调用时,a a的值传送给的值传送给x x,b b的值的值传送给传送给y y。执行完。执行完Swap2Swa

28、p2函数后,函数后,x x和和y y的值是互换了,的值是互换了,但但mainmain函数中的函数中的a a和和b b并未互换。也就是说由于并未互换。也就是说由于“单向单向传送传送”的的“值传递值传递”方式,形参值的改变无法传给实方式,形参值的改变无法传给实参。参。为了使在函数中改变了的变量值能被为了使在函数中改变了的变量值能被mainmain函数所函数所用,不能采取上述的办法,而应该用指针变量作为函用,不能采取上述的办法,而应该用指针变量作为函数参数,在函数执行过程中使指针变量所指向的变量数参数,在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依值发生变化,函

29、数调用结束后,这些变量值的变化依然保留下来,这样就实现了然保留下来,这样就实现了“通过调用函数使变量的通过调用函数使变量的值发生变化,在主调函数值发生变化,在主调函数(如如mainmain函数函数)中使用这些改中使用这些改变了的值变了的值”的目的。的目的。如果想通过函数调用得到如果想通过函数调用得到n n个要改变的值,可以:个要改变的值,可以:在主调函数中设在主调函数中设n n个变量,用个变量,用n n个指针变量指向它们个指针变量指向它们;然后将指针变量作实参,将这然后将指针变量作实参,将这n n个变量的地址传给个变量的地址传给所调用的函数的形参指针所调用的函数的形参指针;通过形参指针变量,改

30、变该通过形参指针变量,改变该n n个变量的值个变量的值;主调函数中就可以使用这些改变了值的变量。主调函数中就可以使用这些改变了值的变量。请读者按此思路仔细理解例请读者按此思路仔细理解例10.310.3程序。程序。viod swapviod swap(int(int*p1p1,intint *p2)p2)int intp;p;p p=p1;=p1;p1p1=p2;=p2;p2p2=p;=p;void main()void main()int a,b;int a,b;int pointer-1 int pointer-1,*pointer-2;pointer-2;scanf(%d,%d,&a,&b

31、);scanf(%d,%d,&a,&b);pointer-1=&a;pointer-2=&b;pointer-1=&a;pointer-2=&b;if(ab)swap(pointer-1,pointer-2);if(ab)swap(pointer-1,pointer-2);printf(n%d,%dn,printf(n%d,%dn,*pointer-1,pointer-1,*pointer-2);pointer-2);请注意,不能企图通过改变指针形参的值而使指请注意,不能企图通过改变指针形参的值而使指针实参的值改变。请看下面的程序:针实参的值改变。请看下面的程序:作者的意图是:交换作者的意图是

32、:交换pointer-1pointer-1和和pointer-2pointer-2的值,使的值,使pointer-1pointer-1指向值大的变量。其设想是:指向值大的变量。其设想是:先使先使pointer-1pointer-1指向指向a a,pointer-2pointer-2指向指向b b,见下图,见下图(a)a)。调用调用swapswap函数,将函数,将pointer-1pointer-1的值传给的值传给p1p1,pointer-2pointer-2传给传给p2p2,见下图,见下图(b)(b)。在在swapswap函数中使函数中使p1p1与与p2p2的值交换,见下图的值交换,见下图(c

33、)(c)。形参形参p1p1和和p2p2将地址传回实参将地址传回实参pointer-1pointer-1和和pointer-2pointer-2,使使pointer-1pointer-1指向指向B B,pointer-2pointer-2指向指向a a,见下图,见下图(d)(d)。输出输出*pointer-1pointer-1和和*pointer-2pointer-2,得到输出,得到输出“9,5”9,5”。但是这是办不到的,程序实际输出为但是这是办不到的,程序实际输出为“5,9”5,9”。问。问题出在第题出在第步。步。C C语言中实参变量和形参变量之间的数语言中实参变量和形参变量之间的数据传递是

34、单向的据传递是单向的“值传递值传递”方式。指针变量作函数参方式。指针变量作函数参数也要遵循这一规则。数也要遵循这一规则。调用函数不可能改变实参指针变量的值,但可以调用函数不可能改变实参指针变量的值,但可以改变实参指针变量所指变量的值。我们知道,函数的改变实参指针变量所指变量的值。我们知道,函数的调用可以调用可以(而且只可以而且只可以)得到一个返回值得到一个返回值(即函数值即函数值),而运用指针变量作参数,可以得到多个变化了的值。而运用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。如果不用指针变量是难以做到这一点的。例例10.输入输入 a,b,c 三三3个整数,按大

35、小顺序输出个整数,按大小顺序输出#include stdio.h#include void void mainmain()()void exchange(int void exchange(int*q1,int q1,int*q2,q2,intint *q3);q3);intint a,b,c,a,b,c,*p1,p1,*p2,p2,*p3;p3;scanf(%d,%d,%d,&a,&b,&c);scanf(%d,%d,%d,&a,&b,&c);p1=&a;p2=&b;p3=&c;p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);exchange(p1,p2,p3);p

36、rintf(n%d,%d,%dn,a,b,c);printf(n%d,%d,%dn,a,b,c);void void exchangeexchange(int(int*q1,int q2,int q3)q1,int q2,int q3)void swap(int void swap(int*pt1,int pt1,int*pt2);pt2);if(if(*q1q2)swap(q1,q2);q1q2)swap(q1,q2);if(if(*q1q3)swap(q1,q3);q1q3)swap(q1,q3);if(if(*q2q3)swap(q2,q3);q2q3)swap(q2,q3);void

37、void swapswap(int(int*pt1,int pt1,int*pt2)pt2)intint temp;temp;temp temp*pt1;pt1;*pt1=pt1=*pt2;pt2;*pt2=temp;pt2=temp;一个变量有地址,一个数组包含若干元素,每个一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也应的地址。指针变量既然可以指向变量,当然也可以指向数组元素可以指向数组元素(把某一元素的地址放到一个把某一元素的地址放到一个指针变量中指针变量中)。所谓。

38、所谓数组元素的指针就是数组元数组元素的指针就是数组元素的地址素的地址。定义一个指向数组元素的指针变量的方法,与以定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:前介绍的指向变量的指针变量相同。例如:;(定义为包含个整型数据的数组定义为包含个整型数据的数组)*;(定义为指向整型变量的指针变量定义为指向整型变量的指针变量)应当注意,如果数组为型,则指针变量的应当注意,如果数组为型,则指针变量的基类型亦应为型。基类型亦应为型。10.3.1 10.3.1 指向数组元素的指针指向数组元素的指针对该指针变量赋值:对该指针变量赋值:;把元素的地址赋给指针变量。也就是使把元素的

39、地址赋给指针变量。也就是使指向数组的第号元素,如图:指向数组的第号元素,如图:10.通过指针引用数组元素通过指针引用数组元素引用一个数组元素,可以用:引用一个数组元素,可以用:()下标法,如形式;下标法,如形式;()指针法,如指针法,如*()或或*()。其中是。其中是数组名,是指向数组元素的指针变量,其初值。数组名,是指向数组元素的指针变量,其初值。例例10.5 输出数组中的全部元素输出数组中的全部元素 假设有一个数组,整型,有个元素。要输出假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:各元素的值有三种方法:(1)(1)下标法下标法#include stdio.h#include

40、 void void main main()()intint ;intint;for(for(;)scanf(scanf(,);printf(printf();for(for(;)printf(printf(,);(2)(2)通过数组名计算数组元素地址,找出元素的值。通过数组名计算数组元素地址,找出元素的值。#include stdio.h#include voidvoidmainmain()()intint ;intint ;for(for(;)scanf(scanf(,);printf(printf();for(for(;)printf(printf(,*();(3)(3)用指针变量指向数

41、组元素。用指针变量指向数组元素。#include stdio.h#include void void mainmain()()intint ;intint *,;,;for(for(;)scanf(scanf(,);printf(printf();for(for(;();)printf(printf(,*);例例10.通过指针变量输出数组的个元素。通过指针变量输出数组的个元素。有人编写出以下程序:有人编写出以下程序:#include stdio.h#include void void mainmain()()intint*,;,;for(for(;)scanf(scanf(,);printf(

42、printf();for(for(;,;,)printf(printf(,*);这个程序乍看起来好像没有什么问题。有的人即使已被这个程序乍看起来好像没有什么问题。有的人即使已被告知此程序有问题,还是找不出它有什么问题。我们先告知此程序有问题,还是找不出它有什么问题。我们先看一下运行情况:看一下运行情况:1 2 3 4 5 6 7 8 9 0 22153 234 0 0 30036 25202 11631 8259 8237 28483显然输出的数值并不是数组中各元素的值显然输出的数值并不是数组中各元素的值 解决这个问题的办法,只要在第二个循环之前解决这个问题的办法,只要在第二个循环之前加一个赋

43、值语句:加一个赋值语句:;#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 arr,int n)但在编译时是将但在编译时是将arr按指针变量处理的,相当于将函按指针变量处理的,相当于将函数数f的首部写成的首部写成f(int*arr,int n)以上两种写法是

44、等价的。以上两种写法是等价的。需要说明的是:需要说明的是:C语言调用函数时虚实结合的方法都语言调用函数时虚实结合的方法都是采用是采用“值传递值传递”方式,当用变量名作为函数参数时方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。地址,所以要求形参为指针变量。例例10 将数组中个整数按相反顺序存放将数组中个整数按相反顺序存放#include void main()void inv(int ,int);in

45、t,;,;printf(The original array:);for(;)printf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();void inv(int ,int)int temp,();for(;);temp;temp;return;运行情况如下:运行情况如下:The original array:,The array has been inverted:,#include void main()void inv(int*,int);int,;,;printf(Th

46、e original array:);for(;)printf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();对这个程序可以作一些改动。将函对这个程序可以作一些改动。将函数数inv中的形参改成指针变量。中的形参改成指针变量。void inv(int*,int)int,temp,*,*,();for(;,;,)emp*;*;*temp;return;归纳起来,如果有一个实参数组,想在函归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参数中改变此数组中的元素

47、的值,实参与形参的对应关系有以下种情况:的对应关系有以下种情况:(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,int),*p=a;

48、(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 用选择法对个整数按由大到小顺序排序用选择法对个整数按由大到小顺序排序#in

49、clude void main()void sort(int ,int);int*,10;for(;)scanf(,);sort(,);for(,;,;)(,*);void sort(int ,int)int,;,;for(;);for(;)();(!);10.多维数组与指针多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。的指针比一维数组的指针要复杂一些。1.多维数组元素的地址多维数组元素的地址先回顾一下多维数

50、组的性质先回顾一下多维数组的性质,可以认为二维数组是可以认为二维数组是“数数组的数组组的数组”,例,例:定义定义int a34=1,3,5,7,;则二维数组则二维数组a是由是由3个一维数组所组成的。设二维数组个一维数组所组成的。设二维数组的首行的首地址为的首行的首地址为 ,则,则表表 示示 形形 式式含义含义地地 址址a a 二维数组名,指向一维数组二维数组名,指向一维数组a0a0,即,即0 0行首地址行首地址20002000a0a0,*(a(a+0),+0),*a a0 0行行0 0列元素地址列元素地址20002000a+1a+1,&a&a1 11 1行首地址行首地址20082008a a1

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(第10章-指针课件.ppt)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|