收藏 分销(赏)

教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx

上传人:快乐****生活 文档编号:3165805 上传时间:2024-06-23 格式:PPTX 页数:100 大小:556.93KB
下载 相关 举报
教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx_第1页
第1页 / 共100页
教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx_第2页
第2页 / 共100页
教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx_第3页
第3页 / 共100页
教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx_第4页
第4页 / 共100页
教材原教案谭浩强C指针省公共课一等奖全国赛课获奖课件.pptx_第5页
第5页 / 共100页
点击查看更多>>
资源描述

1、第第6章章 指针指针6.1 指针概念指针概念6.2 变量与指针变量与指针6.3 数组与指针数组与指针6.4 字符串与指针字符串与指针6.5 函数与指针函数与指针6.6 返回指针值函数返回指针值函数6.7 指针数组和指向指针指针指针数组和指向指针指针6.8 相关指针数据类型和指针运算小结相关指针数据类型和指针运算小结*6.9 引用引用第1页为了说清楚什么是指针,必须搞清楚数据在内存中是为了说清楚什么是指针,必须搞清楚数据在内存中是怎样存放,又是怎样读取。怎样存放,又是怎样读取。假如在程序中定义了一个变量,在编译时就给这个变假如在程序中定义了一个变量,在编译时就给这个变量分配内存单元。系统依据程序

2、中定义变量类型,分量分配内存单元。系统依据程序中定义变量类型,分配一定长度空间。比如,配一定长度空间。比如,C+编译系统普通为整型变编译系统普通为整型变量分配量分配4个字节,为单精度浮点型变量分配个字节,为单精度浮点型变量分配4个字节,个字节,为字符型变量分配为字符型变量分配1个字节。内存区每一个字节有一个字节。内存区每一个字节有一个编号,这图个编号,这图6.1就是就是“地址地址”。6.1 指针概念指针概念第2页图图6.1第3页请务必搞清楚一个内存单元地址与内存单元内容这两请务必搞清楚一个内存单元地址与内存单元内容这两个概念区分。在程序中普通是经过变量名来对内存单个概念区分。在程序中普通是经过

3、变量名来对内存单元进行存取操作。其实程序经过编译以后已经将变量元进行存取操作。其实程序经过编译以后已经将变量名转换为变量地址,对变量值存取都是经过地址进行。名转换为变量地址,对变量值存取都是经过地址进行。这种按变量地址存取变量值方式称为直接存取方式,这种按变量地址存取变量值方式称为直接存取方式,或直接访问方式。或直接访问方式。还能够采取另一个称为间接存取还能够采取另一个称为间接存取(间接访问间接访问)方式。能方式。能够在程序中定义这么一个特殊变量,它是专门用来存够在程序中定义这么一个特殊变量,它是专门用来存放地址。放地址。图图6.2是直接访问和间接访问示意图。为了将数值是直接访问和间接访问示意

4、图。为了将数值3送送到变量中,能够有两种方法:到变量中,能够有两种方法:(1)直接将数直接将数3送到整型变量所标识单元中。见图送到整型变量所标识单元中。见图6.2(a)。第4页(2)将将3送到指针变量送到指针变量i_pointer所指向单元(这就是变所指向单元(这就是变量量i所标识单元)中。见图所标识单元)中。见图6.2(b)。图图6.2所谓指向所谓指向,就是经过地址来表达。就是经过地址来表达。因为经过地址能找到所需变量单元,所以能够说,地因为经过地址能找到所需变量单元,所以能够说,地址指向该变量单元。所以将地址形象化地称为址指向该变量单元。所以将地址形象化地称为“指针指针”。一个变量地址称为

5、该变量指针。一个变量地址称为该变量指针。假如有一个变量是专门用来存放另一变量地址(即指假如有一个变量是专门用来存放另一变量地址(即指针),则它称为指针变量。指针变量值(即指针变量针),则它称为指针变量。指针变量值(即指针变量中存放值)是地址(即指针)。中存放值)是地址(即指针)。第5页指针变量是一个特殊变量,它和以前学过其它类型变指针变量是一个特殊变量,它和以前学过其它类型变量不一样之处是:量不一样之处是:用它来指向另一个变量。为了表用它来指向另一个变量。为了表示指针变量和它所指向变量之间联络,在示指针变量和它所指向变量之间联络,在C+中用中用“*”符号表示指向,比如,符号表示指向,比如,i_

6、pointer是一个指针变是一个指针变量,而量,而*i_pointer表示表示i_pointer所指向变量,见图所指向变量,见图6.3。下面两个语句作用相同:下面两个语句作用相同:i=3;*i_pointer=3;图图6.36.2 变量与指针变量与指针第6页C+要求全部变量在使用前必须先定义,即指定其类要求全部变量在使用前必须先定义,即指定其类型。在编译时按变量类型分配存放空间。对指针变量型。在编译时按变量类型分配存放空间。对指针变量必须将它定义为指针类型。先看一个详细例子:必须将它定义为指针类型。先看一个详细例子:int i,j;/定义整型变量定义整型变量i,jint*pointer_1,*

7、pointer_2;/定义指针变量定义指针变量*pointer_1,*pointer_2第第2行开头行开头int是指:是指:所定义指针变量是指向整型数据所定义指针变量是指向整型数据指针变量。也就是说,指针变量指针变量。也就是说,指针变量pointer_1和和pointer_2只能用来指向整型数据只能用来指向整型数据(比如比如i和和j),而不能而不能指向浮点型变量指向浮点型变量a和和b。这个这个int就是指针变量基类型。就是指针变量基类型。指针变量基类型用来指定该指针变量能够指向变量类指针变量基类型用来指定该指针变量能够指向变量类型。型。定义指针变量普通形式为定义指针变量普通形式为6.2.定义指

8、针变量定义指针变量第7页基类型基类型*指针变量名;指针变量名;下面都是正当定义:下面都是正当定义:float*pointer_3;/pointer_3是指向单精度型数据指针变量是指向单精度型数据指针变量char*pointer_4;/pointer_4是指向字符型数据指针变量是指向字符型数据指针变量请注意:请注意:指针变量名是指针变量名是pointer_3和和pointer_4,而不而不是是*pointer_3和和*pointer_4,即即“*”不是指针变量不是指针变量名一部分,在定义变量时在变量名前加一个名一部分,在定义变量时在变量名前加一个“*”表表示该变量是指针变量。示该变量是指针变量。

9、那么,怎样使一个指针变量指向另一个变量呢?只需那么,怎样使一个指针变量指向另一个变量呢?只需要把被指向变量地址赋给指针变量即可。比如:要把被指向变量地址赋给指针变量即可。比如:pointer_1=&i;/将变量将变量i地址存放到指针变量地址存放到指针变量pointer_1中中pointer_2=&j;/将变量将变量j地址存放到指针变量地址存放到指针变量pointer_2中中第8页这么,这么,pointer_1就指向了变量就指向了变量i,pointer_2就指向了就指向了变量变量j。见图见图6.4。图图6.4普通普通C+编译系统为每一个指针变量分配编译系统为每一个指针变量分配4个字节存个字节存放

10、单元,用来存放变量地址。放单元,用来存放变量地址。在定义指针变量时要注意:在定义指针变量时要注意:(1)不能用一个整数给一个指针变量赋初值。不能用一个整数给一个指针变量赋初值。(2)在定义指针变量时必须指定基类型。在定义指针变量时必须指定基类型。第9页有两个与指针变量相关运算符:有两个与指针变量相关运算符:(1)取地址运算符。取地址运算符。(2)*指针运算符(或称间接访问运算符)。指针运算符(或称间接访问运算符)。比如:比如:&a为变量为变量a地址,地址,*p为指针变量为指针变量p所指向存放所指向存放单元。单元。6.2.2 引用指针变量引用指针变量第10页例例6.1 经过指针变量访问整型变量。

11、经过指针变量访问整型变量。#include using namespace std;int main()int a,b;/定义整型变量定义整型变量a,bint*pointer_1,*pointer_2;/定义指针变量定义指针变量*pointer_1,*pointer_2 a=100;b=10;/对对a,b赋值赋值pointer_1=&a;/把变量地址赋给把变量地址赋给pointer_1pointer_2=&b;/把变量地址赋给把变量地址赋给pointer_2couta bendl;/输出输出a和和b值值cout*pointer_1*pointer_2endl;/输出输出*pointer_1和和

12、*pointer_2值值return 0;第11页运行结果为运行结果为100 10 (a和和b值值)100 10 (*pointer_1和和*pointer_2值值)请对照图请对照图6.5分析。分析。图图6.5第12页下面对下面对“&”和和“*”运算符再做些说明:运算符再做些说明:(1)假如已执行了假如已执行了“pointer_1=&a;”语句,请问语句,请问&*pointer_1含义是什么?含义是什么?“&”和和“*”两个运算符两个运算符优先级别相同,但按自右至左方向结合,所以先进行优先级别相同,但按自右至左方向结合,所以先进行*pointer_1运算,它就是变量运算,它就是变量a,再执行再

13、执行&运算。所以,运算。所以,&*pointer_1与与&a相同,即变量相同,即变量a地址。地址。假如有假如有pointer_=&*pointer_1;它作用是将它作用是将&a(a地地址址)赋给赋给pointer_2,假如假如pointer_2原来指向原来指向b,经过经过重新赋值后它已不再指向重新赋值后它已不再指向b了,而也指向了,见图了,而也指向了,见图6.6。图。图6.6(a)是原来情况,图是原来情况,图6.6(b)是执行上述赋值是执行上述赋值语句后情况。语句后情况。第13页图图6.6(2)*&a含义是什么?先进行含义是什么?先进行&a运算,得运算,得a地址,再进地址,再进行行*运算,即运

14、算,即&a所指向变量,所指向变量,*&a和和*pointer_1作用是作用是一样(假设已执行了一样(假设已执行了“pointer_1=&a;”),),它们等它们等价于变量价于变量a。即即*&a与与a等价,见图等价,见图6.7。第14页图图6.7例例6.2 输入输入a和和b两个整数,按先大后小次序输出两个整数,按先大后小次序输出a和和b(用指针变量处理用指针变量处理)。解此题思绪是:解此题思绪是:设两个指针变量设两个指针变量p1和和p2,使它们分使它们分别指向别指向a和和b。使使p1指向指向a和和b中大者,中大者,p2指向小者,指向小者,次序输出次序输出*p1,*p2就实现了按先大后小次序输出就

15、实现了按先大后小次序输出a和和b。按此思绪编写程序以下:按此思绪编写程序以下:第15页#include using namespace std;int main()int*p1,*p2,*p,a,b;cinab;/输入两个整数输入两个整数p1=&a;/使使p1指向指向ap2=&b;/使使p2指向指向bif(ab)/假如假如ab就使就使p1与与p2值交换值交换p=p1;p1=p2;p2=p;/将将p1指向与指向与p2指向交换指向交换couta=a b=bendl;coutmax=*p1 min=*p2endl;return 0;运行情况以下:运行情况以下:第16页4578 a=45 b=78ma

16、x=78 min=45输入输入a值值45,b值值78,因为,因为ab,将将p1值和值和p2值交换,值交换,即将即将p1指向与指向与p2指向交换。交换前情况见图指向交换。交换前情况见图6.8(a),交换后情况见图交换后情况见图6.8(b)。图图6.8请注意,这个问题算法是不交换整型变量值,而是交请注意,这个问题算法是不交换整型变量值,而是交换两个指针变量值。换两个指针变量值。第17页函数参数不但能够是整型、浮点型、字符型等数据,函数参数不但能够是整型、浮点型、字符型等数据,还能够是指针类型。它作用是将一个变量地址传送给还能够是指针类型。它作用是将一个变量地址传送给被调用函数形参。被调用函数形参。

17、例例6.3 题目同例题目同例6.2,即对输入两个整数按大小次序输,即对输入两个整数按大小次序输出。出。这里用函数处理,而且用指针类型数据作函数参数。这里用函数处理,而且用指针类型数据作函数参数。程序以下:程序以下:6.2.3 指针作为函数参数指针作为函数参数第18页#include using namespace std;int main()void swap(int*p1,int*p2);/函数申明函数申明int*pointer_1,*pointer_2,a,b;/定义指针变量定义指针变量pointer_1,pointer_2,整型变量整型变量a,bcinab;pointer_1=&a;/使

18、使pointer_1指向指向apointer_2=&b;/使使pointer_2指向指向bif(ab)swap(pointer_1,pointer_2);/假如假如ab,使使*pointer_1和和*pointer_2交交换换coutmax=a min=bendl;/a已是大数,已是大数,b是小数是小数 return 0;void swap(int*p1,int*p2)/函数作用是将函数作用是将*p1值与值与*p2值交换值交换 int temp;temp=*p1;*p1=*p2;*p2=temp;第19页运行情况以下:运行情况以下:45 78 max=78 min=45请注意:请注意:不要将不

19、要将main函数中函数中swap函数调用写成函数调用写成if(ab)swap(*pointer_1,*pointer_2);图图6.9第20页请注意交换请注意交换*p1和和*p2值是怎样实现。假如写成以下这值是怎样实现。假如写成以下这么就有问题了:么就有问题了:void swap(int*p1,int*p2)int*temp;*temp*p1;/此语句有问题此语句有问题*p1=*p2;*p2=*temp;本例采取方法是交换本例采取方法是交换a和和b值,而值,而p1和和p2值不变。这值不变。这恰和例恰和例6.2相反。相反。能够看到,在执行能够看到,在执行swap函数后,主函数中变量函数后,主函数

20、中变量a和和b值改变了。这个改变不是经过将形参值传回实参来实值改变了。这个改变不是经过将形参值传回实参来实现。请读者考虑一下能否经过调用下面函数实现现。请读者考虑一下能否经过调用下面函数实现a和和b交换。交换。第21页void swap(int x,int y)int temp;temp=x;x=y;y=temp;在在main函数中用函数中用“swap(a,b);”调用调用swap函数,会函数,会有什么结果呢?在函数调用时,有什么结果呢?在函数调用时,a值传送给值传送给x,b值传值传送给送给y,如图如图6.10(a)所表示。执行完所表示。执行完swap函数最终一函数最终一个语句后,个语句后,x

21、和和y值是交换了,但值是交换了,但main函数中函数中a和和b并并未交换,如图未交换,如图6.10(b)所表示。也就是说因为虚实结合所表示。也就是说因为虚实结合是采取单向是采取单向“值传递值传递”方式,只能从实参向形参传数方式,只能从实参向形参传数据,形参值改变无法回传给实参。据,形参值改变无法回传给实参。第22页图图6.10为了使在函数中改变了变量值能被为了使在函数中改变了变量值能被main函数所用,函数所用,不能采取把要改变值变量作为参数方法,而应该用指不能采取把要改变值变量作为参数方法,而应该用指针变量作为函数参数。在函数执行过程中使指针变量针变量作为函数参数。在函数执行过程中使指针变量

22、所指向变量值发生改变,函数调用结束后,这些变量所指向变量值发生改变,函数调用结束后,这些变量值改变依然保留下来,这么就实现了值改变依然保留下来,这么就实现了“经过调用函数经过调用函数使变量值发生改变,在主调函数中使用这些改变了值使变量值发生改变,在主调函数中使用这些改变了值”目标。目标。第23页假如想经过函数调用得到假如想经过函数调用得到n个要改变值,能够采取下个要改变值,能够采取下面步骤:面步骤:在主调函数中设在主调函数中设n个变量,用个变量,用n个指针变个指针变量指向它们;量指向它们;编写被调用函数,其形参为编写被调用函数,其形参为n个指针个指针变量,这些形参指针变量应该与主调函数中变量,

23、这些形参指针变量应该与主调函数中n个指针个指针变量含有相同基类型;变量含有相同基类型;在主调函数中将在主调函数中将n个指针变个指针变量作实参,将它们值量作实参,将它们值(是地址值是地址值)传给所调用函数传给所调用函数n个个形参指针变量,这么,形参指针变量也指向这形参指针变量,这么,形参指针变量也指向这n个变个变量;量;经过形参指针变量指向,改变该经过形参指针变量指向,改变该n个变量值;个变量值;在主调函数中就能够使用这些改变了值变量。在主调函数中就能够使用这些改变了值变量。请注意,不能企图经过改变形参指针变量值而使实参请注意,不能企图经过改变形参指针变量值而使实参指针变量值改变。请分析下面程序

24、:指针变量值改变。请分析下面程序:第24页#include using namespace std;int main()void swap(int*p1,int*p2);int*pointer_1,*pointer_2,a,b;cinab;pointer_1=&a;pointer_2=&b;if(ab)swap(pointer_1,pointer_2);coutmax=a min=bendl;return 0;void swap(int*p1,int*p2)int*temp;temp=p1;p1=p2;p2=temp;第25页图图6.11实参变量和形参变量之间数据传递是单向实参变量和形参变量之

25、间数据传递是单向“值传递值传递”方式。指针变量作函数参数也要遵照这一规则。调用方式。指针变量作函数参数也要遵照这一规则。调用函数时不会改变实参指针变量值,但能够改变实参指函数时不会改变实参指针变量值,但能够改变实参指针变量所指向变量值。针变量所指向变量值。第26页函数调用能够(而且只能够)得到一个返回值(即函函数调用能够(而且只能够)得到一个返回值(即函数值),而使用指针变量作函数参数,就能够经过指数值),而使用指针变量作函数参数,就能够经过指针变量改变主调函数中变量值,相当于经过函数调用针变量改变主调函数中变量值,相当于经过函数调用从被调用函数中得到多个值。假如不用指针变量是难从被调用函数中

26、得到多个值。假如不用指针变量是难以做到这一点。以做到这一点。例例6.4 输入输入a,b,c 3个整数,按由大到小次序输出。个整数,按由大到小次序输出。用上面介绍方法,用用上面介绍方法,用3个指针变量指向个指针变量指向3个整型变量,个整型变量,然后用然后用swap函数来实现交换函数来实现交换3个整型变量值。个整型变量值。程序以下:程序以下:#include using namespace std;int main()void exchange(int*,int*,int*);/对对exchange函数申明函数申明int a,b,c,*p1,*p2,*p3;cinabc;/输入输入3个整数个整数第

27、27页p1=&a;p2=&b;p3=&c;/指向指向3个整型变量个整型变量exchange(p1,p2,p3);/交换交换p1,p2,p3指向指向3个整型变量值个整型变量值couta b cendl;/按由大到小次序输出按由大到小次序输出3个整数个整数void exchange(int*q1,int*q2,int*q3)void swap(int*,int*);/对对swap函数申明函数申明if(*q1*q2)swap(q1,q2);/调用调用swap,将将q1与与q2所指向变量值交换所指向变量值交换if(*q1*q3)swap(q1,q3);/调用调用swap,将将q1与与q3所指向变量值交

28、换所指向变量值交换if(*q2*q3)swap(q2,q3);/调用调用swap,将将q2与与q3所指向变量值交换所指向变量值交换void swap(int*pt1,int*pt2)/将将pt1与与pt2所指向变量值交换所指向变量值交换int temp;temp=*pt1;*pt1=*pt2;*pt2=temp;运行情况以下:运行情况以下:12-56 87 87 12-56第28页一个变量有地址,一个数组包含若干元素,每个数组一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存放单元,它们都有对应地址。元素都在内存中占用存放单元,它们都有对应地址。指针变量既然能够指向变量,当然也

29、能够指向数组元指针变量既然能够指向变量,当然也能够指向数组元素(把某一元素地址放到一个指针变量中)。所谓数素(把某一元素地址放到一个指针变量中)。所谓数组元素指针就是数组元素地址。组元素指针就是数组元素地址。int a10;/定义一个整型数组定义一个整型数组a,它有它有10个元素个元素int*p;/定义一个基类型为整型指针变量定义一个基类型为整型指针变量pp=&a0;/将元素将元素a0地址赋给指针变量地址赋给指针变量p,使使p指向指向a0在在C+中,数组名代表数组中第一个元素中,数组名代表数组中第一个元素(即序号为即序号为0元素元素)地址。所以,下面两个语句等价:地址。所以,下面两个语句等价:

30、6.3 数组与指针数组与指针 6.3.1 指向数组元素指针指向数组元素指针第29页p=&a0;p=a;在定义指针变量时能够给它赋初值:在定义指针变量时能够给它赋初值:int*p=&a0;/p初值为初值为a0地址地址也能够写成也能够写成int*p=a;/作用与前一行相同作用与前一行相同能够经过指针引用数组元素。假设能够经过指针引用数组元素。假设p已定义为一个基已定义为一个基类型为整型指针变量,并已将一个整型数组元素地址类型为整型指针变量,并已将一个整型数组元素地址赋给了它,使它指向某一个数组元素。假如有以下赋赋给了它,使它指向某一个数组元素。假如有以下赋值语句:值语句:*p=1;/对对p当前所指

31、向数组元素赋予数值当前所指向数组元素赋予数值1假如指针变量假如指针变量p已指向数组中一个元素,则已指向数组中一个元素,则p+1指向指向同一数组中下一个元素。同一数组中下一个元素。第30页假如假如p初值为初值为&a0,则:则:(1)p+i和和a+i就是就是ai地址,或者说,它们指向地址,或者说,它们指向a数组数组第第i个元素,见图个元素,见图6.12。图图6.12第31页(2)*(p+i)或或*(a+i)是是p+i或或a+i所指向数组元素,即所指向数组元素,即ai。能够看出,能够看出,实际上是变址运算符。对实际上是变址运算符。对ai求解过程求解过程是:是:先按先按a+id计算数组元素地址,然后找

32、出此地址计算数组元素地址,然后找出此地址所指向单元中值。所指向单元中值。(3)指向数组元素指针变量也能够带下标,如指向数组元素指针变量也能够带下标,如pi与与*(p+i)等价。等价。依据以上叙述,引用一个数组元素,可用以下方法:依据以上叙述,引用一个数组元素,可用以下方法:(1)下标法,如下标法,如ai形式;形式;(2)指针法,如指针法,如*(a+i)或或*(p+i)。其中其中a是数组名是数组名,p是指向数组元素指针变量。假如已使是指向数组元素指针变量。假如已使p值为值为a,则则*(p+i)就是就是ai。能够经过指向数组元素指针找到所能够经过指向数组元素指针找到所需元素。使用指针法能使目标程序

33、质量高。需元素。使用指针法能使目标程序质量高。第32页例例6.5 输出数组中全部元素。输出数组中全部元素。假设有一个整型数组假设有一个整型数组a,有有10个元素。要输出各元素个元素。要输出各元素值有值有3种方法:种方法:(1)下标法下标法#include using namespace std;int main()int a10;int i;for(i=0;iai;/引用数组元素引用数组元素aicoutendl;for(i=0;i10;i+)coutai;/引用数组元素引用数组元素aicoutendl;return 0;第33页运行情况以下:运行情况以下:9 8 7 6 5 4 3 2 1 0

34、 (输入输入10个元素值个元素值)9 8 7 6 5 4 3 2 1 0 (输出输出10个元素值个元素值)(2)指针法指针法 将上面程序第将上面程序第7行和第行和第10行行“ai”改为改为“*(a+i)”,运行情况与运行情况与(1)相同。相同。(3)用指针变量指向数组元素用指针变量指向数组元素#include using namespace std;int main()int a10;int i,*p=a;/指针变量指针变量p指向数组指向数组a首元素首元素a0for(i=0;i*(p+i);/输入输入a0a9共共10个元素个元素coutendl;第34页for(p=a;p(a+10);p+)c

35、out*p;/p先后指向先后指向a0a9 coutendl;return 0;运行情况与前相同。请仔细分析运行情况与前相同。请仔细分析p值改变和值改变和*p值。值。对对3种方法比较:种方法比较:方法方法(1)和和(2)执行效率是相同。第执行效率是相同。第(3)种方法比喻法种方法比喻法(1)、(2)快。这种方法能提升执行效率。快。这种方法能提升执行效率。用下标法比较直观,能直接知道是第几个元素。用地用下标法比较直观,能直接知道是第几个元素。用地址法或指针变量方法都不太直观,难以很快地判断出址法或指针变量方法都不太直观,难以很快地判断出当前处理是哪一个元素。当前处理是哪一个元素。第35页在用指针变

36、量指向数组元素时要注意:在用指针变量指向数组元素时要注意:指针变量指针变量p能能够指向有效数组元素,实际上也能够指向数组以后内够指向有效数组元素,实际上也能够指向数组以后内存单元。假如有存单元。假如有 int a10,*p=a;/指针变量指针变量p初值为初值为&a0cout*(p+10);/要输出要输出a10值值在使用指针变量指向数组元素时,应切实确保指向数在使用指针变量指向数组元素时,应切实确保指向数组中有效元素。组中有效元素。指向数组元素指针运算比较灵活,务必小心慎重。下指向数组元素指针运算比较灵活,务必小心慎重。下面举几个例子:面举几个例子:假如先使假如先使p指向数组指向数组a首元素首元

37、素(即即p=a),则:则:(1)p+(或或p+=1)。)。使使p指向下一元素,即指向下一元素,即a1。假假如用如用*p,得到下一个元素得到下一个元素a1值。值。第36页(2)*p+。因为因为+和和*同优先级,结合方向为自右而同优先级,结合方向为自右而左,所以它等价于左,所以它等价于*(p+)。作用是:作用是:先得到先得到p指向变指向变量值量值(即即*p),然后再使然后再使p值加值加1。例。例6.5(3)程序中最终程序中最终一个一个for语句:语句:for(p=a;pa+10;p+)cout*p;能够改写为能够改写为for(p=a;pa+10;)cout*p+;(3)*(p+)与与*(+p)作用

38、不一样。前者是先取作用不一样。前者是先取*p值,值,然后使然后使p加加1。后者是先使。后者是先使p加加1,再取,再取*p。若若p初值为初值为a(即即&a0),),输出输出*(p+)得到得到a0值,而输出值,而输出*(+p)则得到则得到a1值。值。第37页(4)(*p)+表示表示p所指向元素值加,即所指向元素值加,即(a0)+,假如假如a0=3,则则(a0)+值为值为4。注意:。注意:是元素值加是元素值加1,而不是指针值加,而不是指针值加1。(5)假如假如p当前指向当前指向ai,则则*(p-)先对先对p进行进行“*”运算,得到运算,得到ai,再使再使p减减1,p指向指向ai-1。*(+p)先使先

39、使p自加自加1,再作,再作*运算,得到运算,得到ai+1。*(-p)先使先使p自减自减1,再作,再作*运算,得到运算,得到ai-1。将将+和和-运算符用于指向数组元素指针变量十分有运算符用于指向数组元素指针变量十分有效,能够使指针变量自动向前或向后移动,指向下一效,能够使指针变量自动向前或向后移动,指向下一个或上一个数组元素。比如,想输出数组个或上一个数组元素。比如,想输出数组100个元个元素,能够用以下语句:素,能够用以下语句:第38页p=a;p=a;while(pa+100)或或 while(pa+100)cout*p+;cout*p;p+;在用在用*p+形式运算时,很轻易弄错,一定要十分

40、小心,形式运算时,很轻易弄错,一定要十分小心,搞清楚先取搞清楚先取p值还是先使值还是先使p加加1。第39页在第在第5章章5.4节中介绍过能够用数组名作函数参数。前节中介绍过能够用数组名作函数参数。前面已经屡次强调:面已经屡次强调:数组名代表数组首元素地址。用数组名代表数组首元素地址。用数组名作函数参数,传递是数组首元素地址。很轻易数组名作函数参数,传递是数组首元素地址。很轻易推想:推想:用指针变量作函数形参,一样能够接收从实用指针变量作函数形参,一样能够接收从实参传递来数组首元素地址参传递来数组首元素地址(此时,实参是数组名此时,实参是数组名)。下。下面将第面将第5章章5.4节中例节中例5.7

41、程序改写,用指针变量作函数程序改写,用指针变量作函数形参。形参。例例6.6 将将10个整数按由小到大次序排列。个整数按由小到大次序排列。在例在例5.7程序基础上,将形参改为指针变量。程序基础上,将形参改为指针变量。6.3.2 用指针变量作函数参数接收数组地址用指针变量作函数参数接收数组地址第40页#include using namespace std;int main()void select_sort(int*p,int n);/函数申明函数申明int a10,i;coutenter the originl array:endl;for(i=0;iai;coutendl;select_so

42、rt(a,10);/函数调用,数组名作实参函数调用,数组名作实参coutthe sorted array:endl;for(i=0;i10;i+)/输出输出10个已排好序数个已排好序数coutai ;coutendl;return 0;void select_sort(int*p,int n)/用指针变量作形参用指针变量作形参int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(*(p+j)*(p+k)k=j;/用指针法访问数组元素用指针法访问数组元素 t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;第41页运行情况与例运行情况与

43、例5.7相同。相同。图图6.13本例与例本例与例5.7在程序表现形式上即使有不一样,但实在程序表现形式上即使有不一样,但实际上,两个程序在编译以后是完全相同。际上,两个程序在编译以后是完全相同。C+编译系编译系统将形参数组名一律作为指针变量来处理。统将形参数组名一律作为指针变量来处理。第42页实际上在函数调用时并不存在一个占有存放空间形参实际上在函数调用时并不存在一个占有存放空间形参数组,只有指针变量。数组,只有指针变量。实参加形参结合,有以下实参加形参结合,有以下4种形式:种形式:实实 参参 形形 参参数组名数组名 数组名数组名(如例如例5.7)数组名数组名 指针变量指针变量 (如例如例6.

44、6)指针变量指针变量 数组名数组名指针变量指针变量 指针变量指针变量在此基础上,还要说明一个问题:在此基础上,还要说明一个问题:实参数组名实参数组名a代表代表一个固定地址,或者说是指针型常量,所以要改变一个固定地址,或者说是指针型常量,所以要改变a值是不可能。如值是不可能。如 a+;/语法错误,语法错误,a是常量,不能改变是常量,不能改变第43页而形参数组名是指针变量,并不是一个固定地址值。而形参数组名是指针变量,并不是一个固定地址值。它值是能够改变。在函数调用开始时,它接收了实参它值是能够改变。在函数调用开始时,它接收了实参数组首元素地址,但在函数执行期间,它能够再被赋数组首元素地址,但在函

45、数执行期间,它能够再被赋值。如值。如 f(array,int n)coutarray;/输出输出array0值值array=array+3;/指针变量指针变量array值改变了,指向值改变了,指向array3cout*arrendl;/输出输出array3值值第44页用指针变量能够指向一维数组中元素,也能够指向多用指针变量能够指向一维数组中元素,也能够指向多维数组中元素。维数组中元素。1.多维数组元素地址多维数组元素地址设有一个二维数组,它有设有一个二维数组,它有3行行4列。它定义为列。它定义为int a34=1,3,5,7,9,11,13,15,17,18,21,23;a是一个数组名。是一个

46、数组名。a数组包含数组包含3行,即行,即3个元素个元素:a0,a1,a2。而每一元素又是一个一维数组,而每一元素又是一个一维数组,它包含它包含4图图6.14个元素个元素(即即4个列元素个列元素),比如,比如,a0所所代表一维数组又包含代表一维数组又包含4个元素:个元素:a00,a01,a02,a03,见图见图6.14。能够认为二维数组是。能够认为二维数组是“数数组数组组数组”,即数组,即数组a是由是由3个一维数组所组成。个一维数组所组成。6.3.3 多维数组与指针多维数组与指针第45页图图6.14从二维数组角度来看,从二维数组角度来看,a代表二维数组首元素地址,代表二维数组首元素地址,现在首元

47、素不是一个整型变量,而是由现在首元素不是一个整型变量,而是由4个整型元素个整型元素所组成一维数组,所以所组成一维数组,所以a代表是首行起始地址代表是首行起始地址(即第即第0行起始地址行起始地址,&a0),a+1代表代表a1行首地址,即行首地址,即&a1。a0,a1,a2既然是一维数组名,而既然是一维数组名,而C+又要求了数又要求了数组名代表数组首元素地址,所以组名代表数组首元素地址,所以a0代表一维数组代表一维数组a0中中0列元素地址,即列元素地址,即&a00。a1值是值是&a10,a2值是值是&a20。第46页图图6.150行行1列元素地址能够直接写为列元素地址能够直接写为&a01,也能够用

48、指也能够用指针法表示。针法表示。a0为一维数组名,该一维数组中序号为为一维数组名,该一维数组中序号为1元素显然能够用元素显然能够用a0+1来表示,见图来表示,见图6.16。欲得到欲得到a01值,用地址法怎么表示呢?既然值,用地址法怎么表示呢?既然a0+1是是a01元素地址,那么,元素地址,那么,*(a0+1)就是就是a01元元素值。而素值。而a0又是和又是和*(a+0)无条件等价,所以也能够无条件等价,所以也能够用用*(*(a+0)+1)表示表示a01元素值。依这类推,元素值。依这类推,*(ai+j)或或*(*(a+i)+j)是是aij值。值。第47页图图6.16第48页2.指向多维数组元素指

49、针变量指向多维数组元素指针变量(1)指向数组元素指针变量指向数组元素指针变量例例6.7 输出二维数组各元素值。输出二维数组各元素值。这里采取方法是用基类型为整型指针变量先后指向各这里采取方法是用基类型为整型指针变量先后指向各元素,逐一输出它们值。元素,逐一输出它们值。#include using namespace std;int main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int*p;/p是基类型为整型指针变量是基类型为整型指针变量for(p=a0;pa0+12;p+)cout*p;coutendl;return 0;第49页运行结果以下:运行结

50、果以下:1 3 5 7 9 11 13 15 17 19 21 23说明:说明:p是指向整型数据指针变量,在是指向整型数据指针变量,在for语句中对语句中对p赋初赋初值值a0,也能够写成也能够写成“p=&a00”。循环结束条件是循环结束条件是“pa0+12”,只要满足只要满足pa0+12,就继续执行循环体。就继续执行循环体。执行执行“cout*p;”输出输出p当前所指列元素值,然当前所指列元素值,然后执行后执行p+,使使p指向下一个列元素。指向下一个列元素。第50页(2)指向由个元素组成一维数组指针变量指向由个元素组成一维数组指针变量能够定义一个指针变量,它不是指向一个整型元素,能够定义一个指

展开阅读全文
部分上传会员的收益排行 01、路***(¥15400+),02、曲****(¥15300+),
03、wei****016(¥13200+),04、大***流(¥12600+),
05、Fis****915(¥4200+),06、h****i(¥4100+),
07、Q**(¥3400+),08、自******点(¥2400+),
09、h*****x(¥1400+),10、c****e(¥1100+),
11、be*****ha(¥800+),12、13********8(¥800+)。
相似文档                                   自信AI助手自信AI助手
百度文库年卡

猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服