版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章指针6.1指针的概念6.2变量与指针6.3数组与指针6.4字符串与指针6.5函数与指针6.6返回指针值的函数6.7指针数组和指向指针的指针6.8有关指针的数据类型和指针运算的小结*6.9引用程序中定义的每一个变量,系统根据变量类型分配一定长度内存单元。例如,C++编译系统一般为整型变量分配4个字节,为字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址”。6.1指针的概念注意:内存单元的地址与内存单元的内容的区别。直接存取方式:按变量名存取变量值的方式。直接将数3送到整型变量i所标识的单元中。
i=3间接存取方式:将3送到指针变量i_pointer所指向的单元(这就是变量i所标识的单元)中。 *i_pointer=3变量的地址称为该变量的指针。专门存放变量地址(即指针)的变量,称为指针变量。指针变量的值是地址(即指针)。任何类型的指针变量在内存中占4个字节。指针变量:用它来指向另一个变量。“*”符号表示指向。例如,i_pointer是一个指针变量,而*i_pointer表示i_pointer所指向的变量。下面两个语句等价:①i=3;②*i_pointer=3;
6.2变量与指针定义指针变量的一般形式:
基类型*指针变量名;例:int
i,j; //定义整型变量i,j
int*pointer_1,*pointer_2;
//定义指向整型数据的指针变量*pointer_1,*pointer_26.2.1定义指针变量例6.2输入a和b两个整数,按先大后小的顺序输出a和b(用指针变量处理)。(不改变a,b的值)思考1:输入a、b、c三个整数,由大到小排序(用指针变量处理)。(不改变a,b,c的值)解题思路:通过交换指针变量的值,改变指针变量的指向来排序。思考2:输入n个整数到数组a中,由大到小排序(用指针变量处理)。(不改变a数组中各元素的值)例:通过调用函数交换a和b的值。6.2.3指针作为函数参数注意:不要将main函数中的swap函数调用写成 swap(*pointer_1,*pointer_2);注意交换*p1和*p2的值是如何实现的。如果写成以下这样就有问题了:voidswap(int*p1,int*p2){int*temp;*temp=*p1;//此语句有问题*p1=*p2;*p2=*temp;}注意:实参变量和形参变量之间的数据传递是单向的“值传递”方式。不能企图通过改变形参指针变量的值而使实参指针变量的值改变。但可改变实参指针所指向变量的值。结论:函数的调用只能有一个返回值,而使用指针变量作函数参数,可通过指针变量改变主调函数中其它变量的值,相当于通过函数调用从被调用的函数中得到多个值。指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)。inta[10]; //定义10个元素的整型数组aint*p;//定义一个基类型为整型的指针变量pp=&a[0];//将a[0]的地址赋给指针变量p,使p指向a[0]6.3数组与指针
6.3.1指向一维数组元素的指针数组名代表数组中第一个元素(即序号为0的元素)的地址。因此,下面两个语句等价:
p=&a[0]; p=a;在定义指针变量时可以给它赋初值:int*p=&a[0];//p的初值为a[0]的地址也可以写成:
int*p=a;//作用与前一行相同通过指针引用数组元素。 inta[10];
int*p=&a[4]; *p=8;
//对p当前所指向的数组元素赋予数值8,即a[4]=1。如果指针变量p已指向数组中的一个元素,如何通过p来访问数组中的其它元素?如果p的初值为&a[0],则:(1)p+i和a+i就是a[i]的地址,或者说,它们指向a数组的第i个元素。(2)*(p+i)或*(a+i)与a[i]等价。[]变址运算符。a[i]的求解过程:先按a+i×d计算数组元素的地址,然后找出此地址所指向的单元中的值。(d为单个数组元素占用的字节数)(3)指向数组元素的指针变量也可以带下标,如p[i]与*(p+i)等价。因此,引用一个数组元素,可用以下方法:(1)下标法,如a[i],p[i]
;(2)指针法,如*(a+i)或*(p+i)。假定a是数组名,p是指向数组元素的指针变量。如果已使p的值为a,则*(p+i)就是a[i]。例6.5倒序输出5个元素的数组中的全部元素。(1)下标法(2)指针法将上面程序第7行和第10行的“a[i]”改为“*(a+i)”。(3)用指针变量指向数组各个元素
注意:切实保证指针变量p指向数组中有效的元素。inta[10],*p=a;//指针变量p的初值为&a[0]cout<<*(p+10);//要输出a[10]的值在inta[10],*p=a;
前提下:(1)p++(或p+=1)。使p指向下一元素,即a[1]。如果用*p,得到下一个元素a[1]的值。(2)*p++。++和*同优先级,结合方向为自右而左,因此等价于*(p++)。作用是:先得到p指向的变量的值(即*p),然后再使p的值加1。如:for(p=a;
p<a+10;)
cout<<*p++;for(p=a;p<a+10;p++)
cout<<*p;(3)*(p++)与*(++p)的区别。前者是先取*p值,然后使p加1。后者是先使p加1,再取*p。若p的初值为a(即&a[0]),输出*(p++)得到a[0]的值,而输出*(++p)得到a[1]的值。(5)如果p当前指向a[i],则 *(p--)是先取*p值,得到a[i],然后p减1,p指向a[i-1]
。 *(--p)是先使p减1,再取*p,得到a[i-1]。(4)(*p)++表示p所指向的元素值加1,即 (a[0])++,如果a[0]=3,则(a[0])++后,a[0]的值为4。++和--运算符用于指向数组元素的指针变量十分有效,可以使指针变量自动向前或向后移动,指向下一个或上一个数组元素。p=a;while(p<a+10){cout<<*p;p++;}p=a;while(p<a+10)
cout<<*p++;循环移位问题如: 12345向左循环移动1位 23451用数组名作形参与指针变量作形参,本质相同,C++编译系统将形参数组名一律作为指针变量处理。都是接收从实参传递来的数组首元素的地址。6.3.2用指针变量作函数参数接收数组地址voidsort(inta[],intn){……}a其实就是指针变量voidsort(int*a,intn){……}例6.6将10个整数按由小到大的顺序排列。实际上函数调用时并不存在一个占有存储空间的形参数组,只有指针变量。实参与形参的结合,有以下4种形式:实参 形参数组名数组名 (如例5.7)数组名 指针变量(如例6.6)指针变量 数组名指针变量 指针变量注意:inta[10]数组名a代表一个固定的地址,或者说是指针型常量,因此不能改变a的值。如
a++;//语法错误,a是常量例:数组a和b中的元素交叉合并到数组c中。
如: a中有1,2,3
b中有5,6,7,8,9
c中有1,5,2,6,3,7,8,9
要求:用指针变量处理。1.多维数组元素的地址设有一个二维数组a,它有3行4列。它的定义为inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};6.3.3多维数组与指针可认为二维数组是“数组的数组”,数组a是由3个一维数组构成。a为二维数组首元素的地址,首元素不是一个整型变量,而是由4个整型元素所组成的一维数组。因此,*(a+0)、*(a+1)、*(a+2)分别表示:a[0],a[1],a[2];即第0、1、2行一维数组名。C++规定数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中0列元素的地址,即&a[0][0]。a[1]的值是&a[1][0],a[2]的值是&a[2][0]。因此,a[1]所代表的一维数组包含4个元素:
a[1][0]、a[1][1]、a[1][2]、a[1][3]指针法表示: *(a[1]+0)、*(a[1]+1)、
*(a[1]+2)、*(a[1]+3)也可表示为: *(*(a+1)+0)、*(*(a+1)+1)、
*(*(a+1)+2)、*(*(a+1)+3)依此类推:*(a[i]+j)或*(*(a+i)+j)是a[i][j]的值。地址2000200420082012(1)指向多维数组元素的指针变量例6.7输出二维数组各元素的值。采用基类型为整型的指针变量先后指向各元素,逐个输出它们的值。2.指向多维数组元素的指针变量说明:①p是指向整型数据的指针变量,在for语句中对p赋初值a[0],也可以写成“p=&a[0][0]”。②循环结束的条件是“p<=a[0]+11”,只要满足p<=a[0]+11,就继续执行循环体。③执行“cout<<*p;”输出p当前所指的列元素的值,然后执行p++,使p指向下一个列元素。思考:可否用p=a语句赋初值?定义一个指针变量,它不是指向一个元素,而是指向一个包含m个元素的一维数组。基类型(*数组名)[一维数组长度]如:int(*p)[4];(2)指向由m个元素组成的一维数组的指针变量如果指针变量p先指向a[0](即p=&a[0]或p=a),则p+1不是指向a[0][1],而是指向a[1],p的增值以一维数组的长度为单位,如图示。例6.8输出二维数组任意一行任意一列元素的值。(用指向一维数组的指针变量实现)*(*(p+2)+3)是a[2][3]的值。3.用指向一维数组的指针作函数参数多维数组名也可作函数参数传递。例6.9输出二维数组各元素的值。用函数实现输出,用多维数组名作函数参数。在C++中可以用3种方法访问一个字符串1.用字符数组存放一个字符串例6.10定义一个字符数组并初始化,然后输出其中的字符串。6.4字符串与指针2.用字符串变量存放字符串例6.11定义一个字符串变量并初始化,然后输出其中的字符串。3.字符指针初始化时指向一个字符串常量例6.12定义一个字符指针变量并初始化,然后输出它指向的字符串。可用下标法或指针法存取字符串中的字符。例6.13将字符串str1复制为字符串str2。如果一个数组,其元素均为指针类型数据,该数组称为指针数组。一维指针数组的定义形式为类型名*数组名[数组长度];例如:int*p[4];6.7指针数组和指向指针的指针
6.7.1指针数组的概念例6.15若干字符串按字母顺序(由小到大)输出。(不改变字符数组中字符串的位置)不区分大小写的排序问题(相同单词排在一起,顺序根据输入定。)1)、二维字符数组(charword[100][20])完成2)、用字符串数组(string
word[100])完成。6.7.2指向指针的指针intx=5;5&xint*p1=&x;xp1int*(*p2)=&p1; 或:int**p2=&p1;&p1p2定义一个指向指针数据的指针变量:
char*(*p);或char**p;用来存放指向指针型数据的指针。即: p=name;或p=&name[0];说明:p++,p指向name数组的下一个元素。由于name[i]的值是地址(即指针),因此name+i就是指向指针型数据的指针。例6.16指向字符型数据的指针变量。int
main(){char**p;char*name[]={"BASIC","FORTRAN","C++","Pascal","COBOL"};p=name+2;cout<<*p<<endl;cout<<**p<<endl;}例:用指向指针的指针方法对n个整数排序并输出。要求:整数和n在主函数中输入,排序单独在一个函数中完成。1)通过指向指针的指针访问整型数组中的元素,但不改变数组中元素的值。2)直接通过指向指针的指针访问整型数组中的元素,并数组中元素的值。int*….*p;实际上在程序中很少超过二级间址。单级间址二级间址(1)、p=NULL;//指针变量为空值
在iostream头文件中定义:
#defineNULL0
NULL代表整数0,但系统中没有地址为0的单元,因此指针变量不指向任何有效单元。注意,p的值等于NULL和p未被赋值是两个不同的概念。注意事项:(2)两个指针变量可以相减如果两个指针变量指向同一个数组的元素,则两个指针变量值之差是两个指针之间的元素个数。假如p1指向a[1],p2指向a[4],则p2-p1=(a+4)-(a+1)=4-1=3。但p1+p2并无实际意义。(3)两个指针变量比较若两个指针指向同一个数组的元素,则可进行比较。指向前面元素的指针变量小于指向后面元素的指针变量。如:p1<p2注意:如果p1和p2不指向同一数组则比较无意义。总结:使用指针的优点:①提高程序效率;②调用函数时,能在被调用函数中改变主调函数中多个变量的值;③可以实现动态存储分配。但是,指针使用太灵活,对熟练的程序员来说,可以利用它编写出颇有特色、质量优良的程序,实现许多用其他高级语言难以实现的功能,但也十分容易出错,而且这种错误往往难以发现。C++动态分配和撤销内存运算符:new和deleteC动态分配和撤销内存函数:malloc和free函数。注意:new和delete是运算符,不是函数,因此执行效率高。new运算符的例子:newint;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针)*7.1.7动态分配和撤销内存的运算符new和deletenewint(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址newchar[10];//开辟一个存放字符数组(包括10个元素)的空间,返回首元素的地址newint[5][4];//开辟一个存放二维整型数组(大小为5*4)的空间,返回首地址float*p=newfloat(3.14159);//开辟一个存放单精度数的空间,并指定该实数的初值为3.14159,将返回的该空间的地址赋给指针变量pnew运算符使用的一般格式为:
new类型[初值]用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否成功。delete运算符使用的一般格式为:delete[]指针变量撤销用new开辟的空间,如deletep; //释放单个空间delete[]pt;//释放数组空间注意:用new开辟的空间,一定要在用完后用delete释放掉。例7.6动态开辟空间以存放n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 期中考试地理总结(31篇)
- 致志愿者的加油稿(3篇)
- 护士个人实习考核工作心得总结(34篇)
- 说明文阅读-2024年中考语文一轮复习题型狂刷(原卷版)
- 综合性学习-2023年湖南长沙中考语文复习专练(原卷版)
- 江苏省五年高考语文考题汇编-作文
- 生物与环境模块(含解析)-2025年高考生物一轮复习科学史类实验专练
- 2024年云南省公务员考试《行测》真题及答案解析
- 课程设计简易家居安保
- 2024年老人雇保姆协议书
- LED屏施工方案(技术方案)
- 边坡防护作用与防护类型全解课件
- 项目收费站机电工程(三大系统)设备基本培训资料
- 难治性高血压-课件
- 混凝土搅拌站租赁合同范本(4篇)
- 烟花爆竹经营单位主要负责人安全培训
- 可疑值的取舍-Q检验法
- 大学舆论学教案
- 压铸模及零件结构专业术语
- 电工安全培训课件
- 维修工程技术标
评论
0/150
提交评论