2022年C语言课件 2.pdf
《2022年C语言课件 2.pdf》由会员分享,可在线阅读,更多相关《2022年C语言课件 2.pdf(34页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、下载第6章指针指针是 C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效,清爽。但由于指针对初学者来说,难于理解和掌握,需要一定的计算机硬件的知识做基础,这就需要多做多练,多上机动手,才能在实践中尽快掌握,成为 C的高手。6.1 指针与指针变量过去,我们在编程中定义或说明变量,编译系统就为已定义的变量分配相应的内存单元,也就是说,每个变量在内存会有固定的位置,有具体的地址。由于变量的数据类型不同,它所占的内存单元数也不相同。若我们在程序中做定义为:int a
2、=1,b=2; float x=3.4,y=4. 5;double m=3.124;char ch1=a,ch2=b; 让我们先看一下编译系统是怎样为变量分配内存的。变量 a ,b是整型变量,在内存各占2个字节;x ,y是实型,各占 4个字节; m是双精度实型,占8个字节; c h1,ch2是字符型,各占1个字节。由于计算机内存是按字节编址的,设变量的存放从内存2 000单元开始存放,则编译系统对变量在内存的安放情况为图 6 -1所示。变量在内存中按照数据类型的不同,占内存的大小也不同,都有具体的内存单元地址,如变量a 在内存的地址是2 000,占据两个字节后,变量 b的内存地址就为2 002
3、,变量 m的内存地址为2 012等。对内存中变量的访问,过去用scanf(%d%d%f,&a,&b,&x) 表示将数据输入变量的地址所指示的内存单元。那么,访问变量,首先应找到其在内存的地址,或者说,一个地址唯一指向一个内存变量,我们称这个地址为变量的指针。如果将变量的地址保存在内存的特定区域,用变量来存放这些地址,这样的变量就是指针变量,通过指针对所指向变量的访问,也就是一种对变量的“间接访问”。设一组指针变量p a、p b、p x、p y、p m、p ch1、p ch2,分别指向上述的变量a、b、x、y、m、c h1、c h2,指针变量也同样被存放在内存,二者的关系如图6 -2所示:在图6
4、 -2中,左部所示的内存存放了指针变量的值,该值给出的是所指变量的地址,通过该地址,就可以对右部描述的变量进行访问。如指针变量p a的值为 2 000,是变量 a在内存的地变量a变量b变量x变量y变量m1200020022004200820122020202123.44.53.124ab变量ch1变量ch2图6-1 不同数据类型的变量在内存中占用的空间名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 34 页 - - - - - - - - - 址。因此, p a就指向变量
5、 a。变量的地址就是指针,存放指针的变量就是指针变量。图6-2 指针变量与变量在内存中的关系6.2 指针变量的定义与引用6.2.1 指针变量的定义在C程序中,存放地址的指针变量需专门定义;int *ptr1;float *ptr2;char *ptr3;表示定义了三个指针变量p tr1、p tr2、p tr3。p tr1可以指向一个整型变量,p tr2可以指向一个实型变量, p tr3可以指向一个字符型变量,换句话说,p tr1、p tr2、p tr3可以分别存放整型变量的地址、实型变量的地址、字符型变量的地址。定义了指针变量,我们才可以写入指向某种数据类型的变量的地址,或者说是为指针变量赋初
6、值:int *ptr1,m= 3;float *ptr2, f=4.5;char *ptr3, ch=a;pt r 1=&m ;pt r 2=&f;pt r 3=&ch;上述赋值语句p tr1=&m表示将变量 m的地址赋给指针变量p tr1,此时 p tr1就指向 m。三条赋值语句产生的效果是p tr1指向m;p tr2指向f;p tr3指向 ch 。用示意图 6 -3描述如下:9 2C语言程序设计下载papbpxpypmpch1pch220002002200420082012202020212000200220042008201220202021123.44.53.124ab10001002
7、1004100610081010101210141016变量a变量b变量x变量y变量m变量ch1变量ch2名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 34 页 - - - - - - - - - 第6章指针9 3下载图6-3 赋值语句的效果需要说明的是,指针变量可以指向任何类型的变量,当定义指针变量时,指针变量的值是随机的,不能确定它具体的指向,必须为其赋值,才有意义。6.2.2 指针变量的引用利用指针变量,是提供对变量的一种间接访问形式。对指针变量的引用形式为:*指
8、针变量其含义是指针变量所指向的值。例6-1 用指针变量进行输入、输出。m ai n()int *p,m;scanf ( % d, &m ) ;p=&m ;/ * 指针 p指向变量 m */printf(%d,*p); /* p是对指针所指的变量的引用形式, 与此 m 意义相同 */运行程序:RU N?3?3上述程序可修改为:m ai n()int *p,m;p=&m ;scanf ( % d, p) ;/* p是变量 m的地址 , 可以替换 &m * /printf(%d, m);运行效果完全相同。请思考一下若将程序修改为如下形式:m ai n( )int *p,m;scanf ( % d ,
9、p);p=&m ;printf(%d, m);会产生什么样的结果呢?事实上,若定义了变量以及指向该变量的指针为:int a,*p;&m&f4.53ptr1ptr2fptr3chm&cha名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 34 页 - - - - - - - - - 9 4C语言程序设计下载若p=&a; 则称 p指向变量 a,或者说 p具有了变量 a的地址。在以后的程序处理中,凡是可以写& a的地方,就可以替换成指针的表示p,a就可以替换成为 * p。6.3
10、指针运算符与指针表达式6.3.1 指针运算符与指针表达式在C中有两个关于指针的运算符:? &运算符 : 取地址运算符, & m即是变量 m的地址。? *运算符:指针运算符,* ptr表示其所指向的变量。例6-2 从键盘输入两个整数,按由大到小的顺序输出。m ai n( )int *p1,*p2,a,b,t;/ * 定义指针变量与整型变量*/scanf ( % d, % d, & a,&b) ;p1=& a;/* 使指针变量指向整型变量*/p2=&b;i f ( *p1*p2)/* 交换指针变量指向的整型变量*/t =*p1;*p1=*p2;* p2=t;pr i ntf ( % d,% d n
11、, a, b) ;在程序中,当执行赋值操作p 1=& a和 p 2=& b后,指针实实在在地指向了变量a与b,这时引用指针 * p1与* p2,就代表了变量 a与b。运行程序 :RUN?3,4 ?4, 3在程序运行过程中,指针与所指的变量之间的关系如图6 -4所示:图6-4 程序运行中指针与变量之间的关系当指针被赋值后,其在内存的安放如a ),当数据比较后进行交换,这时,指针变量与所指向的变量的关系如b )所示,在程序的运行过程中,指针变量与所指向的变量其指向始终没变。下面对程序做修改。&b3p2b *p2&a4p1a *p1&a3p1a *p1&b4p2b *p2a)b)名师资料总结 - -
12、 -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 34 页 - - - - - - - - - 第6章指针9 5下载例6 -3m ai n()int *p1,*p2,a,b,*t;scanf ( % d, % d, & a,&b) ;p1=& a;p2=& b;i f ( *p1*p2)/ * 指针交换指向 */t=p1;p1=p2;p2=t ;pr i ntf ( % d,% d n, *p1, *p2) ;程序的运行结果完全相同,但程序在运行过程中,实际存放在内存中的数据没有移动,而是将指
13、向该变量的指针交换了指向。其示意如图6 -5:图6-5 修改后的程序在运行中指针与变量之间的关系当指针交换指向后,p 1和p 2由原来指向的变量a和b改变为指向变量 b和a,这样一来, * p1就表示变量 b,而* p2就表示变量 a。在上述程序中,无论在何时,只要指针与所指向的变量满足p =&a;我们就可以对变量a 以指针的形式来表示。此时p等效于 & a,* p等效于变量 a 。6.3.2 指针变量作函数的参数函数的参数可以是我们在前面学过的简单数据类型,也可以是指针类型。使用指针类型做函数的参数,实际向函数传递的是变量的地址。由于子程序中获得了所传递变量的地址,在该地址空间的数据当子程序
14、调用结束后被物理地保留下来。例6-4 利用指针变量作为函数的参数,用子程序的方法再次实现上述功能。m ai n()void chang();/ * 函数声明 */int *p1,*p2,a,b,*t;scanf ( % d, % d, & a,&b) ;p1=& a;p2=&b;chang( p1,p2) ;/ * 子程序调用 */pr i ntf ( % d,% d n, *p1, *p2) ;&a4p2b p1&b3p1a*p2a)b)名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - -
15、第 5 页,共 34 页 - - - - - - - - - return 0;void chang(int *pt1,int *pt2)/ * 子程序实现将两数值调整为由大到小*/int t;if (*pt1*pt2)/ * 交换内存变量的值*/t=*pt1; *pt1=*pt2;* pt 2=t; r et ur n;由于在调用子程序时,实际参数是指针变量,形式参数也是指针变量,实参与形参相结合,传值调用将指针变量传递给形式参数p t1和p t2。但此时传值传递的是变量地址,使得在子程序中 p t1和 p t2具有了 p 1和p 2的值,指向了与调用程序相同的内存变量,并对其在内存存放的数
16、据进行了交换,其效果与例6 -2相同。思考下面的程序,是否也能达到相同的效果呢?m ai n()void chang();int *p1,*p2,a,b,*t;scanf ( % d,% d, & a,&b) ;p1=&a;p2=&b;chang( p1, p2) ;pr i ntf ( % d,% d n, *p1, *p2) ;void chang(int *pt1,int *pt2)int *t;if (*pt1*pt2)t=pt1; pt1=pt2;pt2=t ;r et ur n;程序运行结束,并未达到预期的结果,输出与输入完全相同。其原因是对子程序来说,函数内部进行指针相互交换指向
17、,而在内存存放的数据并未移动,子程序调用结束后,m ain()函数中 p 1和p 2保持原指向,结果与输入相同。6.4 指针与数组变量在内存存放是有地址的,数组在内存存放也同样具有地址。对数组来说,数组名就是数组在内存安放的首地址。指针变量是用于存放变量的地址,可以指向变量,当然也可存放数组的首址或数组元素的地址,这就是说,指针变量可以指向数组或数组元素,对数组而言,数组和数组元素的引用,也同样可以使用指针变量。下面就分别介绍指针与不同类型的数组。9 6C语言程序设计下载名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整
18、理 - - - - - - - 第 6 页,共 34 页 - - - - - - - - - 6.4.1 指针与一维数组假设我们定义一个一维数组,该数组在内存会有系统分配的一个存储空间,其数组的名字就是数组在内存的首地址。若再定义一个指针变量,并将数组的首址传给指针变量,则该指针就指向了这个一维数组。我们说数组名是数组的首地址,也就是数组的指针。而定义的指针变量就是指向该数组的指针变量。对一维数组的引用,既可以用传统的数组元素的下标法,也可使用指针的表示方法。int a10 , *ptr; /* 定义数组与指针变量* /做赋值操作: ptr=a; 或 p tr=&a0;则p tr就得到了数组的
19、首址。其中,a是数组的首地址, & a0是数组元素 a 0的地址,由于a 0的地址就是数组的首地址,所以,两条赋值操作效果完全相同。指针变量p tr就是指向数组a的指针变量。若p tr指向了一维数组,现在看一下C规定指针对数组的表示方法:1) ptr+n 与a +n表示数组元素 a n的地址,即 &an 。对整个 a数组来说,共有1 0个元素, n的取值为 09,则数组元素的地址就可以表示为p tr+0p tr+9或a +0a +9,与 &a0 & a9保持一致。2) 知道了数组元素的地址表示方法,* (ptr+n)和* (a+n)就表示为数组的各元素即等效于a n。3) 指向数组的指针变量也
20、可用数组的下标形式表示为p trn,其效果相当于 * (ptr+n)。例6-5 /* 以下标法输入输出数组各元素。下面从键盘输入 1 0个数,以数组的不同引用形式输出数组各元素的值。# include m ai n()int n,a10,*ptr=a;f or ( n=0; n=9;n+)scanf ( % d, &a n );printf(1-output! n);f or ( n=0;n=9; n+)pr i nt f ( % 4d ,an) ;pr i nt f ( n) ;运行程序:RUN?1 2 3 4 5 6 7 8 9 0?1- - - - - - out put !1 2 3
21、4 5 6 7 8 9 0例6-6 采用指针变量表示的地址法输入输出数组各元素。# includem ai n()int n,a10,*ptr=a;/ * 定义时对指针变量初始化*/第6章指针9 7下载名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 34 页 - - - - - - - - - 9 8C语言程序设计下载f or (n=0; n=9;n+)scanf ( % d, pt r+n) ;printf(2-output! n);f or ( n=0; n=9;n+
22、)pr i nt f ( % 4d, *( ptr +n) ;pr i nt f ( n) ;运行程序:RUN?1 2 3 4 5 6 7 8 9 0?2- - - - - - output !1 2 3 4 5 6 7 8 9 0例6-7 采用数组名表示的地址法输入输出数组各元素。m ai n( )int n,a10,*ptr=a;f or ( n=0; n=9;n+)scanf ( % d, a+n) ;printf(3-output! n);f or ( n=0; n=9;n+)pri nt f( % 4d ,* (a+n) ;pri nt f ( n) ;运行程序:RUN?1 2 3
23、4 5 6 7 8 9 0?3- - - - - - output !1 2 3 4 5 6 7 8 9 0例6-8 用指针表示的下标法输入输出数组各元素。m ai n( )int n,a10,*ptr=a;f or ( n=0; n=9;n+)scanf ( % d, &pt r n );printf(4-output! n);f or ( n=0; n=9;n+)pri nt f ( % 4d, pt r n ) ;pr i nt f ( n) ;运行程序:RUN?1 2 3 4 5 6 7 8 9 0?4- - - - out put !名师资料总结 - - -精品资料欢迎下载 - -
24、- - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 34 页 - - - - - - - - - 1 2 3 4 5 6 7 8 9 0例6-9 利用指针法输入输出数组各元素。m ai n( )int n,a10,*ptr=a;f or ( n=0; n=9;n+)scanf (% d, ptr +);printf(5-output! n);pt r =a;/ * 指针变量重新指向数组首址*/f or ( n=0; n=9;n+)pri nt f ( % 4d,* pt r+) ;pr i nt f ( n) ;运行程序:R
25、UN?1 2 3 4 5 6 7 8 9 0?5- - - - - out put !1 2 3 4 5 6 7 8 9 0在程序中要注意* ptr+所表示的含义。 * ptr表示指针所指向的变量;p tr+表示指针所指向的变量地址加1个变量所占字节数,具体地说,若指向整型变量,则指针值加2,若指向实型,则加 4,依此类推。而 p rintf(“% 4d”, * ptr+)中,* ptr+所起作用为先输出指针指向的变量的值,然后指针变量加1。循环结束后,指针变量指向如图6 -6所示:图6-6 例6-9中循环结束后的指针变量指针变量的值在循环结束后,指向数组的尾部的后面。假设元素a 9的地址为
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年C语言课件 2022 语言 课件
限制150内