




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机网络管理第1页,共123页,2023年,2月20日,星期二本章将深入学习数组包括多维数组的知识和应用,以及它们与指针的关系。
C++语言拥有在运行时获得变量地址和操纵地址的能力,这种可用来操纵地址的变量类型就是指针。指针可以用于数组,用于内存访问,还可作为函数的参数。本章重点第2页,共123页,2023年,2月20日,星期二2023/4/1825.1.1数组、数组元素及其存储方式
5.1.2数组名作为函数参数数组第3页,共123页,2023年,2月20日,星期二2023/4/183数组的引入:
数组(array)是一种顺序容器(sequencecontainer),是由单一类型元素组成的一个有序集合:
intfibon[10]={0,1,1,2,3,5,8,13,21,34};
数组名为fibon,这是一个包含10个元素的整型一维(dimension)数组,其第一个元素为fibon[0],存放0,最后一个元素为fibon[9],存放34。数组第4页,共123页,2023年,2月20日,星期二2023/4/184
0
1
2
3
21
34fibon[0]fibon[1]fibon[2]fibon[3]fibon[8]fibon[9]图5.1
数组在内存中的存储数组元素的访问方式:通过下标操作符(subscript),按元素在数组中的位置进行访问,称为索引访问(indexing)或下标访问(subscripting)。参见图5.1
。数组与数组元素及其存储方式第5页,共123页,2023年,2月20日,星期二2023/4/185注意:
1:数组是一种组合类型,是不能作为一个整体进行访问和处理的,只能按元素进行个别的访问和处理。
2:
C++数组第一个元素的下标为0,而不是1,且下标表达方式是固定的。
3:数组元素在内存中是从低地址开始顺序排列,各元素的存储单元占用内存大小相同,各元素的存储单元之间没有空隙,可以从数组第一个元素存储单元的起始地址计算出任意一个元素存储单元的起始地址。数组与数组元素及其存储方式第6页,共123页,2023年,2月20日,星期二2023/4/186【例5.1】找最大数和最小数
const
intSIZE=15;
intmain(){
intarr[SIZE],i,high,low;
for(i=0;i<SIZE;i++)arr[i]=rand()%100;cout<<"Herearethe"<<SIZE<<"randomnumbers:"<<endl;
for(i=0;i<SIZE;i++)cout<<arr[i]<<'\t';
cout<<endl;high=arr[0];//初始化时最大和最小值均为数组首元素
low=arr[0];
for(i=1;i<SIZE;i++){if(arr[i]>high)high=arr[i];
if(arr[i]<low)low=arr[i];}cout<<"highestvalueis"<<high<<endl;cout<<"lowestvalueis"<<low<<endl;
return0;}第7页,共123页,2023年,2月20日,星期二2023/4/187结构数组定义:
structkeyword{
charword[16];//关键字
intcount;//该关键字将在源程序中出现的次数};初始化:结构数组初始化时可以用括号来区分每一个结构,例如:keywordkeytab[]={{"auto",0},{"break",0},{"case",0},……};当提供了数组中所有结构值时,不必用这种括号的形式。keywordkeytab[]={"auto",0,"break",0,"case",0,"char",0,……"unsigned",0,"volatile",0,"while",0,};数组与数组元素及其存储方式第8页,共123页,2023年,2月20日,星期二2023/4/188对象数组定义:
CGoodsgoods[3];该商品类对象数组包含3个商品对象数组元素,系统调用3次默认的构造函数来建立这3个商品对象数组元素。初始化:应该完整书写各个元素的构造函数及成员数据初值:CGoodsgoods[3]={CGoods("夏利2000",30,98000.0),
//调用三参数构造函数,初始化goods[0]CGoods("桑塔纳2000",164000.0),
//调用两参数构造函数,初始化goods[1]CGoods()//调用默认的构造函数,初始化goods[2]};数组与数组元素及其存储方式第9页,共123页,2023年,2月20日,星期二2023/4/189数组作为参数:
数组可以作为函数的参数。在函数调用时传递实参数组的首地址,所以在被调函数中对形参数组的处理实际就是对调用函数的实参数组的处理。
C++只传递数组首地址,而对数组边界不加检查。这带来的好处是,函数对长度不等的同类数组都通用。如要指定长度可以设定另一个参数来传递数组元素的个数。数组名作为函数参数第10页,共123页,2023年,2月20日,星期二2023/4/1810数组名作为函数参数数组元素作实参,与单个变量一样。数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。第11页,共123页,2023年,2月20日,星期二2023/4/1811【例5.2】字符数组与字符数组相连接voidstrcat(chars[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;
while(ct[j]!=0)s[i++]=ct[j++];s[i]='\0';}voidmain(
){
chara[40]="李明";
charb[20]=“是华中科技大学学生";strcat(a,b);cout<<a<<endl;//打印字符数组a}第12页,共123页,2023年,2月20日,星期二2023/4/1812多维数组
C++中数组可以嵌套,就是多维数组。定义二维数组的通用格式为:
类型说明符数组名[常量行表达式][常量列表达式];行与列用常量表达式表示。第13页,共123页,2023年,2月20日,星期二2023/4/1813二维数组:一维数组可对应数学中的向量,而二维数组可对应矩阵,可用一个二维数组存储矩阵。
多维数组存储与访问方式119753117131175312108642二维数组的横向称为行,纵向称为列,上面这个数组为三行六列。第14页,共123页,2023年,2月20日,星期二2023/4/1814多维数组存储与访问方式二维数组分析:上面的数组可定义为:intmat[3][6];mat[0][0]mat[0][1]mat[0][2]mat[0][3]mat[0][4]mat[0][5]mat[1][0]mat[1][1]mat[1][2]mat[1][3]mat[1][4]mat[1][5]mat[2][0]mat[2][1]mat[2][2]mat[2][3]mat[2][4]mat[2][5]有了确定的关系后可以算出多维数组任一元素在内存的位置,设有a数组m行n列,每个元素占b个字节,a[i][j]的首地址为:数组的首地址+(i*n+j)*b;第15页,共123页,2023年,2月20日,星期二2023/4/1815多维数组存储与访问方式
图5.36*3*4的三维数组多维数组分析:
C/C++中的多维数组基本的定义是以数组作为元素构成的数组,二维数组的数组元素是一维数组,三维数组的数组元素是一个二维数组,依此类推。也就是说,多维数组用的是一个嵌套的定义。图5.3表示一个三维数组可定义为:inta3d[6][3][4];第16页,共123页,2023年,2月20日,星期二2023/4/1816多维数组存储与访问方式多维数组的数组名:代表数组中第一维(最高维)第一个元素(0号元素)在内存中的首地址,如三维数组的数组名代表的是组成三维数组的第一个二维数组的存储首地址。当数组作为函数的参数进行传递时,多维数组同样是作为第一维第一个数组的首地址传递给函数,所以物理上是传地址。在函数中对形参的数组元素的修改实际上是对作为实参的原数组的元素进行修改。第17页,共123页,2023年,2月20日,星期二2023/4/1817多维数组存储与访问方式初始化:将所有数据写在一个{}内,按顺序赋值例如:staticinta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};分行给二维数组赋初值例如:staticinta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};可以对部分元素赋初值例如:staticinta[3][4]={{1},{0,6},{0,0,11}};第18页,共123页,2023年,2月20日,星期二2023/4/1818多维数组存储与访问方式1416192589101571212182024741361091013141567511109878129412231516691153152619221445321821171693211191713117530076543210图5.4极点与鞍点示意图【例5.4】已知矩阵
intmat[8][8],找出其中的极点与鞍点。如某元素在所在行相邻点中与所在列相邻点中均为最大或最小,则为极点;如某元素在所在行(或列)相邻点中为最大,同时该元素在所在列(或行)相邻点中为最小,则为鞍点。第19页,共123页,2023年,2月20日,星期二2023/4/1819【例5.4】矩阵极点与鞍点
#include<iostream>#include<iomanip>usingnamespacestd;intmat[8][8]={0,3,5,7,11,┅,25,19,16,14};
intmaxmin(inta,intb,intc){//判断相邻3元素中间元素是否最大或最小
if(a>b&&b<c)return-1;
else
if(a<b&&b>c)return1;
else
return0;}//b为最大返回1,最小返-1,其他为0第20页,共123页,2023年,2月20日,星期二2023/4/1820intmain(
){
inti,j,k,l;
for(i=1;i<=6;i++)
for(j=1;j<=6;j++){
k=maxmin(mat[i][j-1],mat[i][j],mat[i][j+1]);
if(k==0)continue;l=maxmin(mat[i-1][j],mat[i][j],mat[i+1][j]);
if(l==0)continue;
if(k==1&&l==1)cout<<"极大点:";
elseif(k==-1&&l==-1)cout<<"极小点:";
elsecout<<“鞍点:”;cout<<setw(2)<<mat[i][j]<<";i="<<i<<";j="<<j<<endl;}
return0;}【例5.4】矩阵极点与鞍点第21页,共123页,2023年,2月20日,星期二2023/4/1821举例:使用数组名作为函数参数主函数中初始化一个矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。第22页,共123页,2023年,2月20日,星期二2023/4/1822#include<iostream>usingnamespacestd;voidRowSum(intA[][4],intnrow){ intsum; for(inti=0;i<nrow;i++) { sum=0;
for(intj=0;j<4;j++)
sum+=A[i][j]; cout<<"Sumofrow"
<<i<<"is“
<<sum
<<endl;A[i][0]=sum; }
}voidmain(void){ intTable[3][4]={{1,2,3,4},{2,3,4,5},
{3,4,5,6}}; for(inti=0;i<3;i++) { for(intj=0;j<4;j++) cout<<Table[i][j]
<<"";
cout<<endl; } RowSum(Table,3);
for(inti=0;i<3;i++)
cout<<Table[i][0]<<““;}运行结果:123423453456Sumofrow0is10Sumofrow1is14Sumofrow2is18101418第23页,共123页,2023年,2月20日,星期二2023/4/1823多维数组作为函数参数多维数组作为参数:在作为函数的形式参数时,可以省略最高维(第一维)。因为编译器只要根据后面每一维(从第二维开始)的大小,就可计算数组每一个元素的存储位置。基于同样的理由,也只能省略最高维。进一步考虑,对多维数组,编译器不检查边界,其实只是不检查最高维(第一维)的边界,较低各维的大小是在控制之中的。复合类型只能对各元素逐个操作,不能整体操作。
第24页,共123页,2023年,2月20日,星期二2023/4/1824多维数组作为函数参数【例5.5】矩阵转置与矩阵相乘。下标作为参数传递。第25页,共123页,2023年,2月20日,星期二2023/4/1825【例5.5】矩阵转置与矩阵相乘voidinverse(int[3][6],int[6][3]);//转置矩阵
voidmulti(int[6][3],int[3][4],int[6][4]);//矩阵乘法voidoutput(int[6][4]);//矩阵输出Intmain(){
intmiddle[6][3],result[6][4];
intmatrix1[3][6]={8,10,12,23,1,3,5,7,9,2,4,6, 34,45,56,2,4,6};
intmatrix2[3][4]={3,2,1,0,-1,-2,9,8,7,6,5,4};inverse(matrix1,middle);multi(middle,matrix2,result);output(result);
return0;}第26页,共123页,2023年,2月20日,星期二2023/4/1826【例5.5】矩阵转置与矩阵相乘voidinverse(intmatrix1[3][6],intmiddle[6][3]){//转置矩阵
inti,j;
for(i=0;i<3;i++)
for(j=0;j<6;j++)
middle[j][i]=matrix1[i][j];
return;}voidmulti(intmiddle[6][3],intmatrix2[3][4],intresult[6][4]){
inti,j,k;
//矩阵乘法
for(i=0;i<6;i++){
for(j=0;j<4;j++){
result[i][j]=0;
for(k=0;k<3;k++)result[i][j]+=middle[i][k]*matrix2[k][j];}}
return;}第27页,共123页,2023年,2月20日,星期二2023/4/1827【例5.5】矩阵转置与矩阵相乘voidoutput(intresult[6][4]){//矩阵输出
cout<<"result"<<'\n';intI,j;
for(i=0;i<6;i++){
for(j=0;j<4;j++)cout<<setw(4)<<result[i][j]<<"";cout<<'\n';}
return;}第28页,共123页,2023年,2月20日,星期二2023/4/1828指针与地址
5.3.1指针的概念5.3.2指针变量的赋值、初始化与简单应用第29页,共123页,2023年,2月20日,星期二2023/4/1829引例寻找保险箱密码
一个关于特工007寻找保险箱密码的故事…关键点分析得到线索:0200单元的“东九号”寄存箱提示地址:1900单元找到目标:“启明号”寄存箱取出内容:911第30页,共123页,2023年,2月20日,星期二2023/4/1830寻找密码的途径分析密码911存放在某个寄存箱内,如果我们知道这个寄存箱的名字,就能够找到密码;如果不知道密码所在的寄存箱名字,知道该寄存箱的地址也照样能够取出密码;如果寄存箱的地址也不知道,但是有另外一个地方存放这个寄存箱的地址,就能顺藤摸瓜,间接找到密码。第31页,共123页,2023年,2月20日,星期二2023/4/1831密码存放示意图启明号9111900东九号19000200名字东九号启明号地址02001900内容1900911第32页,共123页,2023年,2月20日,星期二2023/4/1832利用指针模拟寻找保险箱密码的过程
获取密码的两种方法
intmain(){ intkey=911;/*变量key存放密码*/
int*addr=NULL;/*变量addr存放地址*/
addr=&key;/*将key的地址赋给addr*/ /*通过变量key输出密码值*/cout<<“密码:“<<key;/*通过变量key的地址来输出密码值*/ cout<<“如果我知道存放密码的地址,我也能找到密码:",*addr;
return0;}密码:911如果我知道存放密码的地址,我也能找到密码:911第33页,共123页,2023年,2月20日,星期二2023/4/1833指针的概念
指针与间接访问:
按变量的地址直接存取变量的方法称为“直接访问”方式。存贮变量的内存空间的首地址称为该变量的地址。如果将一个变量的地址放在另一个变量中,则存放地址的变量称为指针(Pointer)型变量。这样存取变量,也可以间接的由指针变量取得该变量的地址进行,称为“间接访问”方式。
由于指针变量中的值是另一个变量的地址,习惯上形象地称为指针变量指向该变量。指针变量中的值也简称为指针,所以指针就是地址。第34页,共123页,2023年,2月20日,星期二2023/4/1834指针变量与间址访问
指针类型变量——能够存放对象地址的变量,简称“指针变量”例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;第35页,共123页,2023年,2月20日,星期二2023/4/1835指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;第36页,共123页,2023年,2月20日,星期二2023/4/1836指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;
int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE0第37页,共123页,2023年,2月20日,星期二2023/4/1837指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE0第38页,共123页,2023年,2月20日,星期二2023/4/1838指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta
0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF4第39页,共123页,2023年,2月20日,星期二2023/4/1839指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta
0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF4*p1*p1指针p1所指的对象第40页,共123页,2023年,2月20日,星期二2023/4/1840指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb
0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;
p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF0*p1第41页,共123页,2023年,2月20日,星期二2023/4/1841指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb
0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;
p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF4*p1*p2*p2指针p2所指的对象0X0066FDF0第42页,共123页,2023年,2月20日,星期二2023/4/1842指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10; //*p1=10b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF010*p1*p2第43页,共123页,2023年,2月20日,星期二2023/4/1843指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20; //*p2=20a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF010*p1*p220第44页,共123页,2023年,2月20日,星期二2023/4/1844指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;
a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF010*p1*p220+第45页,共123页,2023年,2月20日,星期二2023/4/1845指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;
a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220+第46页,共123页,2023年,2月20日,星期二2023/4/1846指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220间址访问读出变量p1的地址值查找该地址的存储单元用关联类型解释并读出数据第47页,共123页,2023年,2月20日,星期二2023/4/1847指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220间址访问读出变量p2的地址值查找该地址的存储单元用关联类型解释并读出数据第48页,共123页,2023年,2月20日,星期二2023/4/1848指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220间址运算(指针运算)第49页,共123页,2023年,2月20日,星期二2023/4/1849指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0例如:
inta,b;int*p1,*p2;p1=&a;p2=&b;a=10;b=20;a=*p1+*p2;int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220指针类型说明第50页,共123页,2023年,2月20日,星期二2023/4/1850
指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”inta0X0066FDF4intb0X0066FDF0int*p20X0066FDE4int*p10X0066FDE00X0066FDF40X0066FDF030*p1*p220int*p1int*p2intaintb*p1*p2第51页,共123页,2023年,2月20日,星期二2023/4/1851定义形式:
类型*标识符;指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”第52页,共123页,2023年,2月20日,星期二2023/4/1852指针变量名定义形式:
类型*标识符;指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”指针类型说明符指针所指对象的类型(指针的关联)第53页,共123页,2023年,2月20日,星期二2023/4/1853例如int*iptr;//iptr是指向整型对象的指针,可以存放一个整型变量的地址
char*s; //s是指向字符对象的指针double*dPtr; //dPtr是指向浮点对象的指针定义形式:
类型*标识符;指针变量与间址访问指针类型变量——能够存放对象地址的变量,简称“指针变量”第54页,共123页,2023年,2月20日,星期二2023/4/1854注意事项用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致。可以用一个已赋初值的指针去初始化另一个指针变量。指针变量与间址访问指针变量的初始化第55页,共123页,2023年,2月20日,星期二2023/4/1855指针名=地址“地址”中存放的数据类型与指针类型必须相符。向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsignedlongint型。允许声明指向void类型的指针。该指针可以被赋予任何类型对象的地址。例:void*general;指针变量与间址访问第56页,共123页,2023年,2月20日,星期二2023/4/1856指针赋值//空指针:int*iPtr=0;char*s=NULL;double*dPtr=NULL;iPtrsdPtr指针变量与间址访问第57页,共123页,2023年,2月20日,星期二2023/4/1857指针赋值inti=1;int*iPtr1,*iPtr2;char*cPtr;…iPtr1=&i; //合法iPtr2=iPtr1; //合法iPtr2=i;
//非法,i不是int*
对象cPtr=iPtr1;
//非法,iPtr1不是char*对象i=iPtr1; //非法,iPtr1不是int对象指针变量与间址访问第58页,共123页,2023年,2月20日,星期二2023/4/1858举例指针的声明、赋值与使用#include<iostream>usingnamespacestd;voidmain(){ int*i_pointer; //声明int型指针i_pointer inti; //声明int型数i i_pointer=&i;//取i的地址赋给i_pointer i=10; //int型数赋初值 cout<<"Outputinti="<<i<<endl;//输出int型数的值 cout<<"Outputintpointeri="<<*i_pointer<<endl;}//输出int型指针所指地址的内容程序运行的结果是:Outputinti=10Outputintpointeri=10第59页,共123页,2023年,2月20日,星期二2023/4/1859&
取地址操作 *
间址访问操作
例如
shortinta=3,b=4; floatc=4.5,d=8.6; chare='x',f='y';
int*pa=&a,*pb=&b; float*pc=&c,*pd=&d; char*pe=&e,*pf=&f;abcdef101010121014101810221023344.58.6xy指针变量与间址访问第60页,共123页,2023年,2月20日,星期二2023/4/1860abcdef101010121014101810221023344.58.6xypapbpcpdpepf20022006`20102014201820222026101010121014101810221023&a3paa,*pa&b4pbb,*pb&c4.5pcc,*pc&d8.6pdd,*pd&expee,*pe&fypff,*pf第61页,共123页,2023年,2月20日,星期二2023/4/1861//例间址访问对象voidmain(){inti,*p;
p=&i;*p=5;cout<<i<<endl;cout<<*p<<endl;cout<<p<<endl;cout<<&i<<endl;}//通过指针变量间指访问对象用名访问对象通过指针变量间址访问对象指针变量的值对象i的地址取对象i的直接地址值第62页,共123页,2023年,2月20日,星期二2023/4/1862//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pinti1=10,i2=20,*p1,*p2,*p;第63页,共123页,2023年,2月20日,星期二2023/4/1863//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp1=&i1;p2=&i2;*p1*p2第64页,共123页,2023年,2月20日,星期二2023/4/1864//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pcout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;*p1*p2Output*p1=10 *p2=20第65页,共123页,2023年,2月20日,星期二2023/4/1865//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp=p1;*p1*p2*pOutput*p1=10 *p2=20第66页,共123页,2023年,2月20日,星期二2023/4/1866//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp1=p2;*p2*pOutput*p1=10 *p2=20第67页,共123页,2023年,2月20日,星期二2023/4/1867//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp1=p2;*p1*p*p2Output*p1=10 *p2=20第68页,共123页,2023年,2月20日,星期二2023/4/1868//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp2=p;*p1*p*p2Output*p1=10 *p2=20第69页,共123页,2023年,2月20日,星期二2023/4/1869//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp2=p;*p1*pOutput
*p1=10 *p2=20第70页,共123页,2023年,2月20日,星期二2023/4/1870//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
pp2=p;*p1*p*p2Output
*p1=10 *p2=20第71页,共123页,2023年,2月20日,星期二2023/4/1871//例交换指针值voidmain(){inti1=10,i2=20,*p1,*p2,*p;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;p=p1;p1=p2;p2=p;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
p*p1*p*p2cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;*p1=20 *p2=10Output
*p1=10 *p2=20第72页,共123页,2023年,2月20日,星期二2023/4/1872//例交换指针所指对象的值#include<iostream.h>voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2
iinti1=10,i2=20,i,*p1,*p2;第73页,共123页,2023年,2月20日,星期二2023/4/1873//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2p1=&i1;p2=&i2;*p1*p2
i第74页,共123页,2023年,2月20日,星期二2023/4/1874//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;*p1*p2
iOutput*p1=10 *p2=20第75页,共123页,2023年,2月20日,星期二2023/4/1875//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2i=*p1;*p1*p2
i10Output*p1=10 *p2=20第76页,共123页,2023年,2月20日,星期二2023/4/1876//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
10i1
p2
20i2*p1=*p2;*p1*p210i
20Output*p1=10 *p2=20第77页,共123页,2023年,2月20日,星期二2023/4/1877//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
20i1
p2
20i2*p2=i;10i*p1*p2
10Output*p1=10 *p2=20第78页,共123页,2023年,2月20日,星期二2023/4/1878//例交换指针所指对象的值voidmain(){inti1=10,i2=20,i,*p1,*p2;p1=&i1;p2=&i2;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;i=*p1;*p1=*p2;*p2=i;cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;}
p1
20i1
p2
10i2cout<<"*p1="<<*p1<<'\t'<<"*p2="<<*p2<<endl;*p1=20 *p2=1010i*p1*p2Output*p1=10 *p2=20第79页,共123页,2023年,2月20日,星期二2023/4/1879【例5.6】指针变量的赋值20age218age1p_age#include<iostream>
usingnamespacestd;
intmain(){
intage1=18,age2=20,*p_age;p_age=&age1;//情况1
cout<<"age1的地址是:"<<p_age<<endl;//0012FF7Ccout<<"ageofwangpingis"<<*p_age<<endl;p_age=&age2;//情况2
cout<<"age1的地址是:"<<p_age<<endl;//0012FF78cout<<"ageofzhanglingis"<<*p_age<<endl;return0;}第80页,共123页,2023年,2月20日,星期二2023/4/1880指针变量的赋值、初始化与简单应用指针常量:指针常量是固定指向一个对象的指针,即指针本身是常量:charch=’a’,ch1=’x’;char*constptr=&ch;//注意const放在类型说明之后,变量名之前*ptr=’b’;//正确ptr=&ch1;//错误ptr本身在初始化时所指向的地址是不可改变的,但它指向的目标ch的值是可以改变的。第81页,共123页,2023年,2月20日,星期二2023/4/1881指针变量的赋值、初始化与简单应用常量指针:常量指针是指向“常量”的指针,即指针本身可以改指向别的对象,但不能通过该指针修改对象,该对象可以通过其他方式修改,常用于函数的参数,以免误改了实参。类似于在“运算符重载”一节中引用参数前加const。charch=’a’,ch1=’x’;constchar*ptr1=&ch;//ptr1是常量指针*ptr1=’b’;//错误,只能做ch=’b’ptr1=&ch1;//正确第82页,共123页,2023年,2月20日,星期二2023/4/1882this指针
问:当在对象的外部访问该对象的公有成员时,必须指明是哪一个对象。但是当我们用对象的成员函数来访问本对象的成员时,在成员函数中只要给出成员名就可以实现对该对象成员的访问。再进一步可用同一个类创建很多个对象,但它们共用同一份成员函数的代码。既然是同一份代码,那么成员函数又怎么知道是取哪一个对象的成员数据呢?答:
当调用一个成员函数时,系统自动产生一个隐藏的指针,这个指针称为this指针,它始终指向产生这个调用的对象,并将该指针作为一个参数自动传递给该成员函数。这就是说,成员操作符总是要使用的,只不过在对象内是隐式的,而在对象外是显式的。即在对象内省略了this指针。第83页,共123页,2023年,2月20日,星期二2023/4/1883this指针this指针的实现:
1.改变类成员函数的定义,用附加参数this指针来定义每个成员函数。如:voidCgoods::RegisterGoods(Cgoods*this,char*nam,
intamount,floatprice){strcpy(this->Name,name);this->Amount=amount;
this->price=price;}
2.每个类成员函数的调用,加上一个附加的实参——被调用对象的地址。如:Car1.RegisterGoods(String,number,pr);改变为:RegisterGoods(&Car1,String,number,pr);第84页,共123页,2023年,2月20日,星期二2023/4/1884this指针this指针的使用:通常this指针不必写成显式的,但是有时必须写成显式的,如在对复数类的赋值号重载中需要返回当前调用的对象时:Complex&Complex::operator=(Complex&c){real=c.real;image=c.image;
return*this;}Complex&Complex::operator+=(Complex&com){real+=com.real;image+=com.image;
return*this;}
静态成员函数没有this指针。因为普通成员函数虽然在物理上只有一份代码,但在逻辑上都认为一个对象有一份代码,所以有this指针,而静态成员函数在逻辑上也
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 江西师范高等专科学校《数学课程标准分析》2023-2024学年第二学期期末试卷
- 江苏省泰兴市济川实验中学2024-2025学年中考化学试题模拟题及解析(全国卷Ⅲ:)含解析
- 辽宁科技学院《现代办公技术应用》2023-2024学年第二学期期末试卷
- 西安城市建设职业学院《植物生物技术概论》2023-2024学年第二学期期末试卷
- 内蒙古经贸外语职业学院《国际经济地理》2023-2024学年第二学期期末试卷
- 山大附属中学2024-2025学年高三一诊练习四化学试题含解析
- 模特聘用合同书
- 二零二五版按提成收入的协议书
- 电商运营分成合同二零二五年
- 委托独家中介房屋买卖服务合同书二零二五年
- 管道完整性管理基础知识课件
- 学生户外抓鱼活动方案
- 材料方案设计
- 购车金融方案
- 墙面油漆工程的详细施工工序
- 血液透析水处理系统通用课件
- 知识产权与人工智能
- 人工晶体脱位查房
- 春季过敏性疾病预防
- 煤矿一通三防知识培训课件
- 电磁波简介完
评论
0/150
提交评论