版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1,第五章 指针的应用,西南交通大学软件学院 计算机基础教研室 戴克俭制作,C+编程导论,2,第五章 指针的应用,教学目标: 1着重介绍指针与指针变量的概念; 2指针类型变量的定义、赋值以及引用的方法; 3指针与地址运算符; 4通过指针类型的变量去访问单一变量; 5通过指针类型的变量去操作一维数组; 6通过指针类型的变量去操作二维数组; 7动态存储分配的概念及应用。,3,第五章 指针的应用,教学内容: 1掌握地址和指针的概念 2掌握指针类型变量的定义、赋值以及引用的方法 3掌握将一个变量或数组的地址赋给指针类型的变量 4掌握指针操作相关的运算符; 5掌握通过指针类型的变量去访问单一变量; 6掌
2、握通过指针类型的变量去操作一维数组; 7理解通过指针类型的变量去操作二维数组; 8理解动态存储分配的概念及应用。,4,5.1 指针的概述,例5.1.1阅读如下程序: 源程序清单: #include using namespace std; void main( ) int a; int *p; a=10; p=,5,5.1 指针的概述,couta的值表示方法1:aendl; couta的值表示方法2:*pendl; couta的地址表示方法1: 编程技巧: 在源程序清单中,我们可以看到在操作变量a时,用了不同的两种方法,一种就是用我们很习惯的变量名的方式操作,另一种就是本章要学习的新概念指针的
3、方式操作。,6,5.1 指针的概述,1指针是C+从C 中继承过来的重要的概念,它提供了一种较为直观的地址操作的手段。正确地使用指针,可以方便 、灵活而有效地组织和表示复杂的数据结构。 2利用指针可以进行动态内存分配和管理,可以更灵活地使用内存空间。 3为了理解指针,要先理解关于内存地址的概念。计算机的内存储器就像一个巨大的一维数组, 每个数组元素就是一个存储单元。就像数组中的每个元素都有一个下标一样, 每个内存单元都有一个编号, 这个编号就称为内存单元的地址。在微型计算机,地址编码的基本单位是字节,每个字节是一个基本内存单元。,7,5.1 指针的概述,4在运行一个程序时, 程序本身及其所用到的
4、数据都要放在内存储器中。程序、函数、变量、常数、数组和对象等, 在内存储器中都要占有一席之地。存放在内存储器中的程序和数据都有一个地址, 用它们占用的那片存储单元中的第一个存储单元的地址表示。 5在C+中,为某个变量、函数常数、数组和对象等分配内存储器的工作由编译程序完成。计算机通过这种地址编号的方式来管理内存数据读写的准确定位。程序中声明的变量是要占据一定的内存空间的,不同的数据类型占用的字节数是不一样的,例如:char型占1个字节,short型占2个字节,int型和long型都占4个字节。如图5-1所示,表明了每一个内存单元都有自己的地址,在地址所标志的内存单元中可用来存放数据,一般称为内
5、存单元的内容。,8,5.1 指针的概述,9,6在C+ 程序中是如何从内存单元中存取数据的呢 (1)是通过变量名,称为直接访问方式,直接对变量的存储单元进行存取访问。在变量获得内存空间的同时,变量名也就成为了相应内存空间的名称,在变量的整个生存期内都可以用这个名字访问该内存空间,表现在程序语句中就是通过变量名存取变量内容。 例如:例5.1.1中,用语句: couta的值表示方法1:aendl; 来输出变量a的值。,5.1 指针的概述,10,(2) 是通过地址,称为间接访问方式,先找到存放变量的地址的变量,得到变量的地址,再根据变量的地址找到变量的存储单元,对它进行存取访问。例如:例5.1.1中,
6、用语句: couta的值表示方法2:*pendl; 来输出变量a的值。 (3) 有时使用变量名不够方便或者根本没有变量可用,这时就需要直接用地址来访问内存单元。例如,在不同的函数之间传送大量数据时,如果不是传递变量值,而是只传递变量的地址,就会减小开销,提高效率。如果是动态分配的内存单元,则根本就没有名称,这时只能通过地址访问。,5.1 指针的概述,11,5.1 指针的概述,1如何通过地址来操作呢? 在C+中专门用一种数据类型,称为“指针”数据类型来表示“地址”,指针实际上是某个内存单元的首地址。一个变量在内存空间中占用的地址就称为该变量的“指针”。 2程序中定义的任何变量、数组或函数等,在编
7、译时都会在内存中分配一个确定的地址单元,即都有地址。 C+ 规定:,12,(1) 变量的地址可以用 “*”表示该变量p为指针变量;且指针变量p只能操作整型数据。,5.2 指针变量的定义、赋值及使用,15,2指针变量的初始化的常用形式: 与变量定义一样,定义好指针变量后也可以对它进行初始化,指针变量可以初始化为0、NULL或一个地址。数值为0或者NULL的指针不指任何内容。数值0是可以直接赋给指针变量的唯一整数值。 (1) 指针变量的初始化常用的第一种形式: 在定义指针变量的同时进行初始化赋值,一般格式如下: 数据类型 *指针名初始地址;,5.2 指针变量的定义、赋值及使用,16,例如: int
8、 a=3; int *pa=,5.2 指针变量的定义、赋值及使用,17,(3) 使用时注意事项: 指针的类型是它所指向变量的类型。 已赋初值的指针可以初始化另一个指针变量。 例如:q=p; 由于p已经有值,可以来初始化q。 用变量地址作为初值时,该变量的定义必须在指针初始化之前定义。 例如:例5.3.1中, int a=3; int *pa= 变量的定义一定要在指针定义之前。,5.2 指针变量的定义、赋值及使用,18,不能把常量或表达式的地址赋给指针变量。 例如:P=,5.2 指针变量的定义、赋值及使用,19,3使用时要注意指针与指针变量的区别: 指针是内存单元的地址,简称地址。 指针变量是用
9、于存储变量地址的变量。,5.2 指针变量的定义、赋值及使用,20,1为了使用指针变量,要掌握两个运算符: (1) 指针运算符*,也称为“间接访问”运算符,是一个一元运算符,表示指针变量所指向的变量的值。 (2) 取地址运算符 void main( ) int x,*p; x=3; p= ,22,5.3 通过指针变量访问单一变量,编程技巧: 1程序中定义指针变量p, 它的数据类型与它要操作的变量的数据类型一致, 例5.5.1中同为int。 2定义好指针变量p后,用赋值语句p= 在该语句中,*p是一个int型指针,*在定义语句中,表示定义的是指针变量 cout*p; 在该语句中,*p是输出指针p的
10、内容,*在执行语句表示指针所指对象的内容。 (2) p= 将变量x的地址赋给指针变量p,一定要先定义x,然后才能将变量x的地址赋给指针变量p,p有明确的指向后才能操作。,5.3 通过指针变量访问单一变量,24,例5.5.2 输入a和b两个整数,运用指针技术按先大后小的顺序输出a和b。 思路分析:输入两个整数,判断谁大谁小,若a大输出a,b;若a小输出b,a。 算法描述:,5.3 通过指针变量访问单一变量,25,源程序清单: #include #include using namespace std; void main(void) int a,b; int *p1=,5.3 通过指针变量访问单
11、一变量,26,if(*p1*p2) cout按先大后小的顺序输出的a和b 为:*p2setw(4)*p1endl; else cout按先大后小的顺序输出的a和b 为:*p1setw(4)*p2endl; 编程技巧: 1利用间接访问方式来操作。,5.3 通过指针变量访问单一变量,27,5.4 通过指针变量操作一维数组,在C+中,有了指针和地址的概念,我们在操作数组时,就可以用如下的四种方法来操作数组。 使用数组名和下标 使用数组名和指针运算 使用指针变量 使用下标表示法引用指针指向的数组元素 例5.6.1设有一个int型数组a,有10个元素,请用上述的四种方法去访问数组的各个元素。,28,源程
12、序清单: #include using namespace std; void main( ) int a10; int i,*p; for(i=0; iai; / 数组名和下标来访问数组,5.4 通过指针变量操作一维数组,29,for(i=0; i10; i+) cout*(a+i); /数组名和指针运算来访问数组 for(p=a; p-a10; p+) cout*p; /指针变量的移动来访问数组 p=a; for(i=0; i10; i+) coutpi; /下标表示法 ,5.4 通过指针变量操作一维数组,30,编程技巧: 1例中第一种方法操作数组时,使用数组名和下标来访问数组,是第四章中
13、我们已经学习和掌握的方法。 2例中第二种方法操作数组时,使用数组名和指针运算来访问数组,利用了数组名a是数组首地址,是一个地址常量,是数组第一个元素的地址,但数组名所代表的首地址只是一个指针常量,是固定的指针,我们不能对数组名赋予一个新的地址值,也不能使这指针常量“移动”,指向数组的其它元素,要指向其它数组元素时,通过首地址加上一个值,使之指向其它的数组元素。例如:例5.6.1中就通过*(a+i)来指向数组中的第i个元素。,5.4 通过指针变量操作一维数组,31,3例中第三种方法操作数组时,使用指针变量来访问数组,是利用指针变量可以赋新的地址值和使指针变量“移动”而指向数组的其它元素。 4例中
14、第四种方法操作数组时,使用下标表示法引用指针指向的数组元素,注意操作时,指针要指向数组的首地址。,5.4 通过指针变量操作一维数组,32,1要使用指针变量来访问数组,关键是如何“移动” 指针变量,使指针变量指向具体要操作地数组元素的地址,就需要掌握指针变量的算术运算。 指针与整数的加减运算 指针 p 加上或减去 n ,其意义是指针当前指向位置的前方或后方第 n 个数据的地址。 指针加一,减一运算 指向下一个或前一个数据。 例如:y=*px+ 相当于 y=*(px+) *和+优先级相同,自右向左结合,5.4 通过指针变量操作一维数组,33,如: int a5=1,2,3,4,5; int *p;
15、 p=a;p+;p+=3;p-; 指针变量值每自增一次 指向后一个数组元 素的内存单元 指针变量值每自减一次 指向前一个数组元 素的内存单元,6.8 指针的算术运算,pa,34,两指针相减: 两指针相减的结果是一个整数,等于两指针指向的内存单元之间的内存单元的个数减1。 例如: int a10,*p,*q,k; p=a; q=a+10; k=q-p; /k的值等于9,5.4 通过指针变量操作一维数组,35,例5.6.3 阅读如下程序: 源程序清单: #include using namespace std; void main( ) char a10=abcdefghi; char *p1,*
16、p2; p1=a; p1+=2; p2=a+4; /指针变量p2,直接由数组名加上4,指向数组 的第五个数组元素的内存单元,5.4 通过指针变量操作一维数组,36,if(p1p2) cout“p1所指向的数组元素在p2所指向的数组元素前 面!endl; else cout“p1所指向的数组元素在p2所指向的数组元素后 面!endl; p1+; p2-; if(p1=p2) cout“p1和p2同时指向数组中的同一个元素且元素值 为:*p1endl; else coutp1和p2没有指向数组中的同一个元素! endl; ,5.4 通过指针变量操作一维数组,37,编程技巧: 1在操作数组时,有时可
17、能会用到两个指针变量指向同一个数组,例如:在例5.6.3中,用p1和p2两个指针变量指向同一个数组,此时两个指针变量之间的可以进行关系运算,其关系运算的结果表明了这两个指针变量所指向的数组元素的先后关系。 (1)若p1= =p2;表明p1和p2指向数组中的同一个数组元素; (2)若p1p2;表明p1所指向的数组元素在p2所指向的数组元素后面。 例如:,5.4 通过指针变量操作一维数组,38,例5.6.3中,第一次输出时,p1p2条件成立,表明p1所指向的数组元素在p2所指向的数组元素前面;如图5-3所示。,5.4 通过指针变量操作一维数组,39,第二次输出时,p1= =p2条件成立,表明p1和
18、p2指向数组中的同一个数组元素,如图5-4所示。 2此外,指针变量还可以和零之间进行等于或不等于的关系运算。例如:p= =0或p!=0。,5.4 通过指针变量操作一维数组,40,指针应用举例,例5.6.4 利用指针技术,将键盘输入的N个整数按相反的顺序存放并输出。 思路分析:分别取出数组最前面和最后面的元素,进行交换,即a0与aN-1交换;然后再分别取出a1与aN-2交换;直到交换完毕。 算法描述:,41,源程序清单: #include #include using namespace std; int main(void) int a10,i,j,temp,*p; cout*p;,指针应用举
19、例,42,指针应用举例,p=a; for(i=0,j=10-1;ij;i+,j-) temp=*(p+i); *(p+i)=*(p+j); *(p+j)=temp; for(p=a;pa+10;p+) coutsetw(4)*p; coutendl; return 0; ,43,指针应用举例,编程技巧: 1定义指针变量操作一维数组,定义后把指针变量指向数组的首地址,用循环输入各个数组元素的值。 2再次使用指针变量操作数组前,必须要明确指针变量的指向,即指针变量再次指向数组的首地址,用语句“p=a;”实现。 3利用了两个变量i,j并赋初值后,用*(p+i)、*(p+j)分别取出数组中首尾元素的值
20、进行交换,然后使i+、j- -分别再取出数组中第二个元素的值和倒数第二个元素的值进行交换,直到交换完毕,即条件ij 不成立。,44,例5.6.5把一个整数插入到一个由小到大的有序数列中,并仍然保持由小到大的顺序。 思路分析: 设有10个整数按由小到大的顺序存放在a数组中,待插入的数存放在变量x中,如:10个有序数依次为: 2 4 6 8 12 16 17 20 30 40,待插入的数:x=11。 要插入的数8x=11 12 ,所以x=11应放在a4中。 如何放入a4中,首先把原来a4 a9中的所有元素向后移一位,然后再把x的值放入到a4中,经过以上的操作之后,数据如下: 2 4 6 8 11
21、12 16 17 20 30 40 完成插入。,指针应用举例,45,指针应用举例,完成插入操作的关键是确定插入的位置。设一个位置变量p,令其初值为0,将x与ap进行比较,只要x大于ap就表示x所要插的位置是在ap之后,此时应该使p后移一个位置,接着再进行下一个元素的比较;不断重复以上过程,一旦x不再大于ap,这时的p就是x所要插入的位置,在没找到x所要插的位置之前,循环次数无法确定,判断循环条件可用逻辑条件: (xap void main(void) const int N=10; int aN+1,p=0,x,*t; cout*t; coutx;,48,指针应用举例,t=a; while (
22、x*(t+p) ,49,指针应用举例,编程技巧: 1在定义数组时,要考虑到插入后数组元素的长度增加了一个,定义时要在原数组长度的基础上加一。例如:例5.6.5中,定义数组为:int aN+1。 2要注意指针变量在使用后的指向,再次操作时要赋初值,例如:例5.6.5中,t=a;让指针变量再次指向数组的首地址。,50,例5.6.6编写程序,用指针技术删除字符串末尾的所有空格。 思路分析: 用指针操作字符串,首先把指针指向字符串末尾的字符,取出其末尾字符的值,进行判断是否等于空格,若等于就删除,即把指针指向前一个字符,指针减1,再取出倒数第二个字符进行判断是否等于空格,等于就进行同样的操作,直到不等
23、于,就说明字符串末尾已经没有空格,操作完成,需要给字符串末尾加上结束标志0。,指针应用举例,51,指针应用举例,52,源程序清单: #include #include using namespace std; void main(void) int n,j; string s1= ; char *p; cout输入需要删除末尾空格的字符串:endl; getline(cin,s1); cout未删除末尾空格前的字符串为:endls1 字符串结束标志!endl; n=s1.size( );,指针应用举例,53,指针应用举例,j=n-1; p= 编程技巧: 1用string数据类型,加头文件#in
24、clude 。 2由于输入字符串含有空格,输入时必须用getline(cin,s1)函数实现输入。 3用s1.size( )函数求出字符串的长度n,包含字符串的实际长度,字符数组是从下标0开始,最后一个字符的位置应为n-1。 4用语句:p= int aM,bN,cM; int d,e,f=0,*pa,*pb,*pc; coutd;,55,cout*pa; coute; cout*pb; for(pa=a,pc=c;paa+d;pa+) for(pb=b;pbb+e;pb+),应用举例,56,if(*pa=*pb) *pc+=*pa; f+; break; cout交集c的各个元素依次为:end
25、l; for (pc=c;pcc+f;pc+) coutsetw(3)*pc; ,应用举例,57,例6-2 从键盘输入整数集合a、b的元素个数和各个元素的值,计算并输出其并集。 源程序清单如下: #include #include void main(void) const int M=20,N=10; int aM,bN,cM+N; int d,e,f=0,*pa,*pb,*pc;,应用举例,58,coutd; cout*pa; coute; cout*pb;,应用举例,59,for(pa=a,pc=c;pa=a+d) *pc+=*pb; f+; cout交集c的各个元素依次为:endl;
26、for (pc=c;pcc+f;pc+) coutsetw(3)*pc; ,应用举例,60,5.5 二维数组与指针,例5.12 运用指针的方法编程实现:输出如下二维数组各元素的值。 int a34=1,2,3,4,5,6,7,8,9,10,11,12 源程序清单一: #include #include using namespace std; void main() int a34=1,2,3,4,5,6,7,8,9,10,11,12,61,int *p; for(p=a0;pa0+12;p+) if(p-a0)%4=0) coutendl; coutsetw(4)*p; coutendl;
27、,5.5 二维数组与指针,62,源程序清单二: #include #include using namespace std; void main(void) int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *p3,i,j; for(i=0;i3;i+) pi=ai;,5.5 二维数组与指针,63,for(j=0;j4;j+) coutsetw(4)*(pi+j); coutendl; 编程技巧: 通过前面的学习我们知道,二维数组在计算机里实际上是转换成一维数组来存储的,是按行方式存放的。,5.5 二维数组与指针,64, 在操作二维数组时,指向二维数组的指针变量的
28、定义、赋值和使用与指向一维数组的指针变量基本相同。 具体操作二维数组时,一般常用两种方法: 用指针变量使用数组元素,此方法是把二维数组转换成一维数组来操作,定义指针变量先指向首地址,然后通过指针变量“移动”来操作具体的数组元素。 定义指针数组使用数组元素,指针数组就是数组中每个元素是指针,用它来指向一维数组。,5.5 二维数组与指针,65,5.13 利用指针技术,求55阶方阵主对角线的和。 思路分析: 55的方阵用二维数组a55表示,定义一个指针数组*p5来操作数组;求主对角线的和,先找到主对角线上的元素,应满足条件行号等于列号,再进行累加。 算法描述:,5.5 二维数组与指针,66,源程序清单: #include using namespace std; void main(void) int a55,*p5,i,j,sum=0; cout*(pi+j); ,5.5 二维数组与指针,67,for(i=0;i5;i+) pi=ai; for(j=0;j5;j+) if(i=j)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 神经内科护理心理干预
- 2026年数据跨境流动合规审计:安全评估 标准合同 认证三种途径的执行验证
- 2026年校园安全防暴力培训
- 2026年重点小巨人“三新一强”推进计划编制与绩效目标设定
- 土木建筑工程技术与计量的基础知识
- 隧道照明技术方法
- 机动护士的护理质量与安全
- 2026年实验室化学品安全目标培训
- 智能护理技术对护理工作的影响
- 抑郁症康复护理要点与案例分析
- 机场安全生产培训内容课件
- 2026内蒙古事业单位第一阶段改报岗位(公共基础知识)测试题附答案
- 公安交通集成指挥平台操作手册(扩充版)
- DB1307∕T455-2024 谷子品种 张杂谷13号
- 自愿放弃赡养权协议书
- 备战2026年高考数学考试易错题(新高考)专题14 排列组合与二项式定理(解析版)
- 《陆上风力发电机组钢混塔架施工与质量验收规范》
- 2025年及未来5年中国对外劳务合作市场运行态势及行业发展前景预测报告
- 2025年招标采购从业人员专业技术能力考试(招标采购合同管理中级)测试题库及答案(山西阳泉)
- 老年痴呆合并激越行为护理查房
- 2025下半年新疆生产建设兵团事业单位招聘(2398人)考试参考试题及答案解析
评论
0/150
提交评论