版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第六章數(shù)組指針與字符串C++語言程序設(shè)計2本章主要內(nèi)容數(shù)組指針動態(tài)存儲分配指針與數(shù)組指針與函數(shù)vector的基本用法字符串深度探索3數(shù)組的概念數(shù)組是具有一定順序關(guān)系的若干相同類型變量的集合體,組成數(shù)組的變量稱為該數(shù)組的元素。數(shù)組屬于構(gòu)造類型。
數(shù)組4一維數(shù)組的聲明與引用一維數(shù)組的聲明類型說明符數(shù)組名[常量表達式];
例如:inta[10];
表示a為整型數(shù)組,有10個元素:a[0]...a[9]引用必須先聲明,后使用。只能逐個引用數(shù)組元素,而不能一次引用整個數(shù)組
例如:a[0]=a[5]+a[7]-a[2*3]數(shù)組名的構(gòu)成方法與一般變量名相同。
數(shù)組5例6.1一維數(shù)組的聲明與引用#include<iostream>usingnamespacestd;intmain(){inta[10],b[10];for(inti=0;i<10;i++){
a[i]=i*2-1;
b[10-i-1]=a[i];}for(inti=0;i<10;i++){cout<<"a["<<i<<"]="<<a[i]<<"";cout<<"b["<<I<<"]="<<b[i]<<endl;}return0;}
數(shù)組6一維數(shù)組的存儲順序數(shù)組元素在內(nèi)存中順次存放,它們的地址是連續(xù)的。例如:具有10個元素的數(shù)組a,在內(nèi)存中的存放次序如下:數(shù)組名字是數(shù)組首元素的內(nèi)存地址。數(shù)組名是一個常量,不能被賦值。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a
數(shù)組7一維數(shù)組的初始化可以在定義數(shù)組的同時賦給初值:在聲明數(shù)組時對數(shù)組元素賦以初值。
例如:staticinta[10]={0,1,2,3,4,5,6,7,8,9};可以只給一部分元素賦初值。
例如:staticinta[10]={0,1,2,3,4};在對全部數(shù)組元素賦初值時,可以不指定數(shù)組長度。
例如:staticinta[]={1,2,3,4,5}
數(shù)組8#include<iostream>usingnamespacestd;intmain(){intf[20]={1,1};//初始化第0、1個數(shù)
for(inti=2;i<20;i++)//求第2~19個數(shù)
f[i]=f[i-2]+f[i-1];for(i=0;i<20;i++){//輸出,每行5個數(shù)if(i%5==0)cout<<endl; cout.width(12);//設(shè)置輸出寬度為12 cout<<f[i];}return0;}例:用數(shù)組來處理求Fibonacci數(shù)列問題9例:用數(shù)組來處理求Fibonacci數(shù)列問題運行結(jié)果:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 676510一維數(shù)組應(yīng)用舉例循環(huán)從鍵盤讀入若干組選擇題答案,計算并輸出每組答案的正確率,直到輸入ctrl+z為止。每組連續(xù)輸入5個答案,每個答案可以是'a'..'d'。
數(shù)組#include<iostream>usingnamespacestd;intmain(){constcharKEY[]={'a','c','b','a','d'};constintNUM_QUES=5;charc;intques=0,numCorrect=0;cout<<"Enterthe"<<NUM_QUES<<"questiontests:"<<endl;while(cin.get(c)){if(c!='\n'){ if(c==key[ques]){numCorrect++;cout<<"";}elsecout<<"*";ques++;}else{cout<<"Score"<<static_cast<float>(numCorrect)/NUM_QUES*100<<"%";ques=0;numCorrect=0;cout<<endl;}}return0;}11運行結(jié)果:acbba**Score60%acbadScore100%abbda***Score40%bdcba*****Score0%1213二維數(shù)組的聲明及引用數(shù)據(jù)類型標識符[常量表達式1][常量表達式2]…;例:inta[5][3];
表示a為整型二維數(shù)組,其中第一維有5個下標(0~4),第二維有3個下標(0~2),數(shù)組的元素個數(shù)為15,可以用于存放5行3列的整型數(shù)據(jù)表格。
數(shù)組14存儲順序按行存放,上例中數(shù)組a的存儲順序為:
二維數(shù)組的聲明類型說明符數(shù)組名[常量表達式][常量表達式]例如:floata[3][4];a00a01a02a03a10a11a12a13a20a21a22a23a[0]——a00a01a02a03a[1]——a10a11a12a13
a[2]——a20a21a22a23a可以理解為:引用例如:b[1][2]=a[2][3]/2下標不要越界二維數(shù)組的聲明及引用
數(shù)組15將所有數(shù)據(jù)寫在一個{}內(nèi),按順序賦值例如:staticinta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};分行給二維數(shù)組賦初值例如:staticinta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};可以對部分元素賦初值例如:staticinta[3][4]={{1},{0,6},{0,0,11}};二維數(shù)組的初始化
數(shù)組16數(shù)組作為函數(shù)參數(shù)數(shù)組元素作實參,與單個變量一樣。數(shù)組名作參數(shù),形、實參數(shù)都應(yīng)是數(shù)組名,類型要一樣,傳送的是數(shù)組首地址。對形參數(shù)組的改變會直接影響到實參數(shù)組。
數(shù)組17例6-2使用數(shù)組名作為函數(shù)參數(shù)主函數(shù)中初始化一個矩陣并將每個元素都輸出,然后調(diào)用子函數(shù),分別計算每一行的元素之和,將和直接存放在每行的第一個元素中,返回主函數(shù)之后輸出各行元素的和。
數(shù)組#include<iostream>usingnamespacestd;voidrowSum(inta[][4],intnRow){
for(inti=0;i<nRow;i++){ for(intj=1;j<4;j++) a[i][0]+=a[i][j]; }}intmain(){ //主函數(shù)
inttable[3][4]={{1,2,3,4},{2,3,4,5},{3,4,5,6}};//聲明并初始化數(shù)組18//輸出數(shù)組元素
for(inti=0;i<3;i++) {
for(intj=0;j<4;j++) cout<<table[i][j]<<""; cout<<endl; } rowSum(table,3); //調(diào)用子函數(shù),計算各行和//輸出計算結(jié)果
for(inti=0;i<3;i++)
cout<<"Sumofrow"<<i<<"is"<<table[i][0]<<endl; return0;}19運行結(jié)果:123423453456Sumofrow0is10Sumofrow1is14Sumofrow2is182021對象數(shù)組聲明:類名數(shù)組名[元素個數(shù)];訪問方法:通過下標訪問數(shù)組名[下標].成員名
數(shù)組22對象數(shù)組初始化數(shù)組中每一個元素對象被創(chuàng)建時,系統(tǒng)都會調(diào)用類構(gòu)造函數(shù)初始化該對象。通過初始化列表賦值。例:
Pointa[2]={Point(1,2),Point(3,4)};如果沒有為數(shù)組元素指定顯式初始值,數(shù)組元素便使用默認值初始化(調(diào)用缺省構(gòu)造函數(shù))。
數(shù)組23數(shù)組元素所屬類的構(gòu)造函數(shù)不聲明構(gòu)造函數(shù),則采用缺省構(gòu)造函數(shù)。各元素對象的初值要求為相同的值時,可以聲明具有默認形參值的構(gòu)造函數(shù)。各元素對象的初值要求為不同的值時,需要聲明帶形參的構(gòu)造函數(shù)。當數(shù)組中每一個對象被刪除時,系統(tǒng)都要調(diào)用一次析構(gòu)函數(shù)。
數(shù)組24例6-3對象數(shù)組應(yīng)用舉例//Point.h#ifndef_POINT_H#define_POINT_HclassPoint{ //類的定義public: //外部接口
Point(); Point(intx,inty); ~Point(); voidmove(intnewX,intnewY); intgetX()const{returnx;} intgetY()const{returny;} staticvoidshowCount(); //靜態(tài)函數(shù)成員private: //私有數(shù)據(jù)成員
intx,y;};#endif //_POINT_H
數(shù)組//Point.cpp#include<iostream>#include"Point.h"usingnamespacestd;Point::Point(){ x=y=0; cout<<"DefaultConstructorcalled."<<endl;}Point::Point(intx,inty):x(x),y(y){ cout<<"Constructorcalled."<<endl;}Point::~Point(){ cout<<"Destructorcalled."<<endl;}voidPoint::move(intnewX,intnewY){ cout<<"Movingthepointto("<<newX<<","<<newY<<")"<<endl; x=newX; y=newY;}25//6-3.cpp#include"Point.h"#include<iostream>usingnamespacestd;intmain(){ cout<<"Enteringmain..."<<endl;
Point
a[2]; for(inti=0;i<2;i++)
a[i].move(i+10,i+20); cout<<"Exitingmain..."<<endl; return0;}26運行結(jié)果:Enteringmain...DefaultConstructorcalled.DefaultConstructorcalled.Movingthepointto(10,20)Movingthepointto(11,21)Exitingmain...Destructorcalled.Destructorcalled.2728關(guān)于內(nèi)存地址內(nèi)存空間的訪問方式通過變量名訪問通過地址訪問地址運算符:&例:intvar;則&var
表示變量var在內(nèi)存中的起始地址29聲明例:staticinti;staticint*ptr=&i;
指向整型變量的指針概念
指針:內(nèi)存地址,用于
間接訪問內(nèi)存單元
指針變量:
用于存放地址的變量20003ptr*ptri2000內(nèi)存用戶數(shù)據(jù)區(qū)變量i變量j變量
ptr362000200020043010引用例1:i=3;
例2:*ptr=3;
指針指針變量的概念30語法形式
存儲類型數(shù)據(jù)類型*指針名=初始地址;例:int*pa=&a;注意事項用變量地址作為初值時,該變量必須在指針初始化之前已聲明過,且變量類型應(yīng)與指針類型一致??梢杂靡粋€已賦初值的指針去初始化另一個指針變量。不要用一個內(nèi)部auto變量去初始化static指針。
指針指針變量的初始化31指針變量的賦值運算指針名=地址“地址”中存放的數(shù)據(jù)類型與指針類型必須相符。向指針變量賦的值必須是地址常量或變量,不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。指針的類型是它所指向變量的類型,而不是指針本身數(shù)據(jù)值的類型,任何一個指針本身的數(shù)據(jù)值都是unsignedlongint型。允許聲明指向void類型的指針。該指針可以被賦予任何類型對象的地址。例:void*general;
指針32例6-5指針的聲明、賦值與使用#include<iostream>usingnamespacestd;intmain(){ inti; //定義int型數(shù)i int*ptr=&i; //取i的地址賦給ptr i=10; //int型數(shù)賦初值
cout<<"i="<<i<<endl;//輸出int型數(shù)的值
cout<<"*ptr="<<*ptr<<endl;//輸出int型指針所指地址的內(nèi)容
return0;}
指針程序運行的結(jié)果是:i=10*ptr=103334例6-6void類型指針的使用#include<iostream>usingnamespacestd;intmain(){//!voidvoidObject;錯,不能聲明void類型的變量
void*pv; //對,可以聲明void類型的指針
inti=5; pv=&i; //void類型指針指向整型變量
int*pint=static_cast<int*>(pv);//void類型指針賦值給int類型指針
cout<<"*pint="<<*pint<<endl; return0;}
指針35指向常量的指針不能通過指針來改變所指對象的值,但指針本身可以改變,可以指向另外的對象。例inta;constint*p1=&a; //p1是指向常量的指針intb;p1=&b; //正確,p1本身的值可以改變*p1=1; //編譯時出錯,不能通過p1改變所指的對象
指針36指針類型的常量若聲明指針常量,則指針本身的值不能被改變。例:inta;int*constp2=&a;p2=&b;//錯誤,p2是指針常量,值不能改變
指針37指針變量的算術(shù)運算指針與整數(shù)的加減運算指針p加上或減去n,其意義是指針當前指向位置的前方或后方第n個數(shù)據(jù)的地址。這種運算的結(jié)果值取決于指針指向的數(shù)據(jù)類型。p1[n1]等價于*(p1+n1)指針加一,減一運算指向下一個或前一個數(shù)據(jù)。例如:y=*px++相當于y=*(px++)
(*和++優(yōu)先級相同,自右向左運算)
指針papa-2pa-1pa+1pa+2pa+3*(pa-2)或pa[-2]*pa或pa[0]*(pa+1)或pa[1]*(pa+2)或pa[2]*(pa+3)或pa[3]*(pa-1)或pa[-1]short*pa38pb-1pbpb+1pb+2*(pb-1)或pb[-1]*pb或pb[0]*(pb+1)或pb[1]*(pb+2)或pb[2]long*pb3940關(guān)系運算指向相同類型數(shù)據(jù)的指針之間可以進行各種關(guān)系運算。指向不同數(shù)據(jù)類型的指針,以及指針與一般整數(shù)變量之間的關(guān)系運算是無意義的。指針可以和零之間進行等于或不等于的關(guān)系運算。例如:p==0或p!=0賦值運算向指針變量賦的值必須是地址常量或變量,不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。指針變量的關(guān)系運算
指針41指向數(shù)組元素的指針聲明與賦值例:inta[10],*pa;pa=&a[0];或pa=a;通過指針引用數(shù)組元素經(jīng)過上述聲明及賦值后:*pa就是a[0],*(pa+1)就是a[1],...,*(pa+i)就是a[i].a[i],*(pa+i),*(a+i),pa[i]都是等效的。不能寫a++,因為a是數(shù)組首地址是常量。
指針42例6-7設(shè)有一個int型數(shù)組a,有10個元素。用三種方法輸出各元素:使用數(shù)組名和下標使用數(shù)組名和指針運算使用指針變量
指針#include<iostream>usingnamespacestd;intmain(){ inta[10]={1,2,3,4,5,6,7,8,9,0}; for(inti=0;i<10;i++) cout<<a[i]<<""; cout<<endl; return0;}使用數(shù)組名和下標43#include<iostream>usingnamespacestd;intmain(){ inta[10]={1,2,3,4,5,6,7,8,9,0}; for(inti=0;i<10;i++) cout<<*(a+i)<<""; cout<<endl; return0;}使用數(shù)組名指針運算44使用指針變量#include<iostream>usingnamespacestd;intmain(){ inta[10]={1,2,3,4,5,6,7,8,9,0}; for(int*p=a;p<(a+10);p++) cout<<*p<<""; cout<<endl; return0;}4546指針數(shù)組數(shù)組的元素是指針型例:Point*pa[2];
由pa[0],pa[1]兩個指針組成
指針47例6-8利用指針數(shù)組存放單位矩陣#include<iostream>usingnamespacestd;intmain(){ intline1[]={1,0,0}; //矩陣的第一行
intline2[]={0,1,0}; //矩陣的第二行
intline3[]={0,0,1}; //矩陣的第三行
//定義整型指針數(shù)組并初始化
int*pLine[3]={line1,line2,line3};
指針 cout<<"Matrixtest:"<<endl;//輸出單位矩陣
for(inti=0;i<3;i++){
for(intj=0;j<3;j++)
cout<<pLine[i][j]<<"";cout<<endl; } return0;}輸出結(jié)果為:Matrixtest:1,0,00,1,00,0,14849例6-9二維數(shù)組舉例#include<iostream>usingnamespacestd;intmain(){intarray2[3][3]={{11,12,13},{21,22,23},{31,32,33}};for(inti=0;i<3;i++){for(intj=0;j<3;j++)cout<<*(*(array2+i)+j)<<""; //逐個輸出二維數(shù)組第i行元素值
cout<<endl;}return0;}
指針程序的輸出結(jié)果為:11121321222331323350指針數(shù)組vs二維數(shù)組51pLine[0]pLine[1]pLine[2](a)指針數(shù)組array2[0]array2[1]array2[2]array2(b)二維數(shù)組52以指針作為函數(shù)參數(shù)以地址方式傳遞數(shù)據(jù),可以用來返回函數(shù)處理結(jié)果。實參是數(shù)組名時形參可以是指針。
指針與函數(shù)53例6.10題目:讀入三個浮點數(shù),將整數(shù)部分和小數(shù)部分分別輸出#include<iostream>usingnamespacestd;voidsplitFloat(floatx,int*intPart,float*fracPart){//取x的整數(shù)部分*intPart=static_cast<int>(x);//取x的小數(shù)部分*fracPart=x-*intPart;}
指針與函數(shù)intmain(){cout<<"Enter3floatpointnumbers:"<<endl;for(inti=0;i<3;i++){floatx,f;intn;cin>>x;splitFloat(x,&n,&f); //變量地址作為實參
cout<<"IntegerPart="<<n<<"FractionPart="<<f<<endl;}return0;}54運行結(jié)果:Enter3floatingpointnumbers4.7IntegerPart=4FractionPart=0.78.913IntegerPart=8FractionPart=0.913-4.7518IntegerPart=-4FractionPart=-0.75185556例:
輸出數(shù)組元素的內(nèi)容和地址#include<iostream>#include<iomanip>usingnamespacestd;voidarrayPtr(long*p,intn){cout<<"Infunc,addressofarrayis"
<<p<<endl; cout<<"Accessingarrayusingpointers"<<endl; for(inti=0;i<n;i++) {cout<<"Addressforindex"<<i<<"is"
<<p+i; cout<<"Valueis"<<*(p+i)<<endl; }}
指針與函數(shù)intmain(){ longlist[5]={50,60,70,80,90};
cout<<"Inmain,addressofarrayis"<<list<<endl; cout<<endl;
arrayPtr(list,5); return0;}57運行結(jié)果:Inmain,addressofarrayis0012FF50Infunc,addressofarrayis0012FF50AccessingarrayusingpointersAddressforindex0is0012FF50Valueis50Addressforindex1is0012FF54Valueis60Addressforindex2is0012FF58Valueis70Addressforindex3is0012FF5CValueis80Addressforindex4is0012FF60Valueis905859指向常量的指針做形參#include<iostream>usingnamespacestd;constintN=6;voidprint(constint
*p,intn);intmain(){intarray[N];for(inti=0;i<N;i++)cin>>array[i];print(array,N);return0;}
指針voidprint(constint*p,intn){cout<<"{"<<*p;for(inti=1;i<n;i++)cout<<","<<*(p+i);cout<<"}"<<endl;}6061指針型函數(shù)當函數(shù)的返回值是地址時,該函數(shù)就是指針形函數(shù)。聲明形式
存儲類型數(shù)據(jù)類型*函數(shù)名()
指針與函數(shù)62聲明形式
存儲類型數(shù)據(jù)類型(*函數(shù)指針名)();
含義:數(shù)據(jù)指針指向數(shù)據(jù)存儲區(qū),而函數(shù)指針指向的是程序代碼存儲區(qū)。指向函數(shù)的指針
指針與函數(shù)63例6-11函數(shù)指針#include<iostream>usingnamespacestd;voidprintStuff(float){ cout<<"Thisistheprintstufffunction."<<endl;}voidprintMessage(floatdata){ cout<<"Thedatatobelistedis"<<data<<endl;}voidprintFloat(floatdata){ cout<<"Thedatatobeprintedis"<<data<<endl;}
指針與函數(shù)constfloatPI=3.14159f;constfloatTWO_PI=PI*2.0f;intmain(){ //主函數(shù)
void(*functionPointer)(float);//函數(shù)指針 printStuff(PI);
functionPointer=printStuff;
functionPointer(PI); //函數(shù)指針調(diào)用
functionPointer=printMessage;
functionPointer(TWO_PI); //函數(shù)指針調(diào)用
functionPointer(13.0); //函數(shù)指針調(diào)用
functionPointer=printFloat;
functionPointer(PI); //函數(shù)指針調(diào)用
printFloat(PI); return0;}64運行結(jié)果:
Thisistheprintstufffunction.Thisistheprintstufffunction.Thedatatobelistedis6.28318Thedatatobelistedis13Thedatatobeprintedis3.14159Thedatatobeprintedis3.141596566對象指針的一般概念聲明形式類名*對象指針名;例Pointa(5,10);Piont*ptr;ptr=&a;通過指針訪問對象成員對象指針名->成員名ptr->getx()相當于(*ptr).getx();
指針67對象指針應(yīng)用舉例intmain(){Pointa(5,10);Point*ptr;
ptr=&a; intx; x=ptr->getX(); cout<<x<<endl;return0;}
指針68曾經(jīng)出現(xiàn)過的錯誤例子classFred; //前向引用聲明classBarney{Fredx; //錯誤:類Fred的聲明尚不完善
};classFred{Barneyy;};
指針69正確的程序classFred; //前向引用聲明classBarney{Fred*x; };classFred{Barneyy;};
指針70this指針隱含于每一個類的成員函數(shù)中的特殊指針。明確地指出了成員函數(shù)當前所操作的數(shù)據(jù)所屬的對象。當通過一個對象調(diào)用成員函數(shù)時,系統(tǒng)先將該對象的地址賦給this指針,然后調(diào)用成員函數(shù),成員函數(shù)對對象的數(shù)據(jù)成員進行操作時,就隱含使用了this指針。
指針71this指針例如:Point類的getX函數(shù)中的語句:returnx;相當于:returnthis->x;
指針72指向類的非靜態(tài)成員的指針通過指向成員的指針只能訪問公有成員聲明指向成員的指針聲明指向公有數(shù)據(jù)成員的指針類型說明符類名::*指針名; 聲明指向公有函數(shù)成員的指針類型說明符(類名::*指針名)(參數(shù)表);
指針73指向類的非靜態(tài)成員的指針指向數(shù)據(jù)成員的指針說明指針應(yīng)該指向哪個成員指針名=&類名::數(shù)據(jù)成員名;通過對象名(或?qū)ο笾羔槪┡c成員指針結(jié)合來訪問數(shù)據(jù)成員對象名.*類成員指針名或:對象指針名->*類成員指針名
指針74指向類的非靜態(tài)成員的指針指向函數(shù)成員的指針初始化指針名=&類名::函數(shù)成員名;通過對象名(或?qū)ο笾羔槪┡c成員指針結(jié)合來訪問函數(shù)成員(對象名.*類成員指針名)(參數(shù)表)或:(對象指針名->*類成員指針名)(參數(shù)表)
指針75指向類的非靜態(tài)成員的指針例6-13訪問對象的公有成員函數(shù)的不同方式intmain(){ //主函數(shù) Pointa(4,5); //聲明對象A Point*p1=&a;//聲明對象指針并初始化
//聲明成員函數(shù)指針并初始化
int(Point::*funcPtr)()=Point::getX;
//(1)使用成員函數(shù)指針訪問成員函數(shù)
cout<<(a.*funcPtr)()<<endl;
//(2)使用成員函數(shù)指針和對象指針訪問成員函數(shù)
cout<<(p1->*funcPtr)()<<endl;
//(3)使用對象名訪問成員函數(shù)
cout<<a.getX()<<endl;
//(4)使用對象指針訪問成員函數(shù)
cout<<p1->getX()<<endl;return0;}
指針76指向類的靜態(tài)成員的指針對類的靜態(tài)成員的訪問不依賴于對象可以用普通的指針來指向和訪問靜態(tài)成員例6-14通過指針訪問類的靜態(tài)數(shù)據(jù)成員例6-15通過指針訪問類的靜態(tài)函數(shù)成員
指針77例6-14通過指針訪問類的靜態(tài)數(shù)據(jù)成員#include<iostream>usingnamespacestd;classPoint{ //Point類定義public: //外部接口
Point(intx=0,inty=0):x(x),y(y){
count++; } Point(constPoint&p):x(p.x),y(p.y){
count++; } ~Point(){count--;} intgetX()const{returnx;} intgetY()const{returny;} staticintcount;private: //私有數(shù)據(jù)成員
intx,y;};intPoint::count=0;
指針intmain(){ //主函數(shù)實現(xiàn)//定義一個int型指針,指向類的靜態(tài)成員
int*ptr=&Point::count;
Pointa(4,5); //定義對象a cout<<"PointA:"<<a.getX()<<","<<a.getY(); cout<<"Objectcount="<<*ptr<<endl;
Pointb(a); //定義對象b cout<<"PointB:"<<b.getX()<<","<<b.getY(); cout<<"Objectcount="<<*ptr<<endl;
return0;}7879例6-15通過指針訪問類的靜態(tài)函數(shù)成員#include<iostream>usingnamespacestd;classPoint{ //Point類定義public: //外部接口
Point(intx=0,inty=0):x(x),y(y){count++;} Point(constPoint&p):x(p.x),y(p.y){count++;} ~Point(){count--;} intgetX()const{returnx;} intgetY()const{returny;} staticvoidshowCount(){cout<<"Objectcount="<<count<<endl;}private: //私有數(shù)據(jù)成員
intx,y; staticintcount;};intPoint::count=0;
指針intmain(){ //主函數(shù)實現(xiàn)//定義一個指向函數(shù)的指針,指向類的靜態(tài)成員函數(shù)
void(*funcPtr)()=Point::showCount;
Pointa(4,5); //定義對象A cout<<"PointA:"<<a.getX()<<","<<a.getY(); funcPtr(); //輸出對象個數(shù),直接通過指針訪問靜態(tài)函數(shù)成員
Pointb(a); //定義對象B cout<<"PointB:"<<b.getX()<<","<<b.getY(); funcPtr(); //輸出對象個數(shù),直接通過指針訪問靜態(tài)函數(shù)成員
return0;}8081動態(tài)申請內(nèi)存操作符newnew類型名T(初始化參數(shù)列表)功能:在程序執(zhí)行期間,申請用于存放T類型對象的內(nèi)存空間,并依初值列表賦以初值。結(jié)果值:成功:T類型的指針,指向新分配的內(nèi)存;失?。簰伋霎惓?。
動態(tài)存儲分配82釋放內(nèi)存操作符deletedelete指針p功能:釋放指針p所指向的內(nèi)存。p必須是new操作的返回值。
動態(tài)存儲分配83例6-16動態(tài)創(chuàng)建對象舉例#include<iostream>usingnamespacestd;classPoint{public: Point():x(0),y(0){ cout<<"DefaultConstructorcalled."<<endl; } Point(intx,inty):x(x),y(y){ cout<<"Constructorcalled."<<endl; } ~Point(){cout<<"Destructorcalled."<<endl;} intgetX()const{returnx;} intgetY()const{returny;} voidmove(intnewX,intnewY){ x=newX; y=newY; }private: intx,y;};
動態(tài)存儲分配intmain(){ cout<<"Stepone:"<<endl; Point*ptr1=newPoint;//調(diào)用缺省構(gòu)造函數(shù)
deleteptr1; //刪除對象,自動調(diào)用析構(gòu)函數(shù)
cout<<"Steptwo:"<<endl; ptr1=newPoint(1,2);
deleteptr1;
return0;}運行結(jié)果:StepOne:DefaultConstructorcalled.Destructorcalled.StepTwo:Constructorcalled.Destructorcalled.84申請和釋放動態(tài)數(shù)組分配:new類型名T[數(shù)組長度]數(shù)組長度可以是任何表達式,在運行時計算釋放:delete[]數(shù)組名p釋放指針p所指向的數(shù)組。p必須是用new分配得到的數(shù)組首地址。8586例6-17動態(tài)創(chuàng)建對象數(shù)組舉例#include<iostream>usingnamespacestd;classPoint{//類的聲明同例6-16,略};intmain(){ Point*ptr=newPoint[2]; //創(chuàng)建對象數(shù)組
ptr[0].move(5,10);//通過指針訪問數(shù)組元素的成員
ptr[1].move(15,20);//通過指針訪問數(shù)組元素的成員
cout<<"Deleting..."<<endl; delete[]ptr; //刪除整個對象數(shù)組
return0;}
動態(tài)存儲分配運行結(jié)果:DefaultConstructorcalled.DefaultConstructorcalled.Deleting...Destructorcalled.Destructorcalled.87將動態(tài)數(shù)組封裝成類更加簡潔,便于管理建立和刪除數(shù)組的過程比較繁瑣封裝成類后更加簡潔,便于管理可以在訪問數(shù)組元素前檢查下標是否越界用assert來檢查,assert只在調(diào)試時生效88例6-18動態(tài)數(shù)組類#include<iostream>#include<cassert>usingnamespacestd;classPoint{//類的聲明同例6-16…};classArrayOfPoints{ //動態(tài)數(shù)組類public: ArrayOfPoints(intsize):size(size){ points=newPoint[size]; } ~ArrayOfPoints(){ cout<<"Deleting..."<<endl; delete[]points; }
Point&element(intindex){ assert(index>=0&&index<size);
returnpoints[index]; }private: Point*points; //指向動態(tài)數(shù)組首地址
intsize; //數(shù)組大小};89intmain(){ intcount;cout<<"Pleaseenterthecountofpoints:"; cin>>count; ArrayOfPointspoints(count); //創(chuàng)建對象數(shù)組 //通過訪問數(shù)組元素的成員
points.element(0).move(5,0); //通過類訪問數(shù)組元素的成員
points.element(1).move(15,20);
return0;}90運行結(jié)果如下:Pleaseenterthenumberofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.Deleting...Destructorcalled.Destructorcalled.9192動態(tài)創(chuàng)建多維數(shù)組new類型名T[第1維長度][第2維長度]…;如果內(nèi)存申請成功,new運算返回一個指向新分配內(nèi)存首地址的指針,是一個T類型的數(shù)組,數(shù)組元素的個數(shù)為除最左邊一維外各維下標表達式的乘積。例如:char(*fp)[3];fp=newchar[2][3];
動態(tài)存儲分配char(*fp)[3];fpfp+1fp[0][0]fp[0][1]fp[0][2]fp[1][0]fp[1][1]fp[1][2]9394例6-19動態(tài)創(chuàng)建多維數(shù)組#include<iostream>usingnamespacestd;intmain(){float(*cp)[9][8]=newfloat[8][9][8];for(inti=0;i<8;i++)for(intj=0;j<9;j++)for(intk=0;k<8;k++)//以指針形式數(shù)組元素*(*(*(cp+i)+j)+k)=static_cast<float>(i*100+j*10+k);
動態(tài)存儲分配 for(inti=0;i<8;i++){ for(intj=0;j<9;j++){ for(intk=0;k<8;k++) //將指針cp作為數(shù)組名使用,通過數(shù)組名和下標訪問數(shù)組元素
cout<<cp[i][j][k]<<""; cout<<endl; } cout<<endl; } delete[]cp; return0;}95用vector創(chuàng)建動態(tài)數(shù)組為什么需要vector?將動態(tài)數(shù)組封裝,自動創(chuàng)建和刪除數(shù)組下標越界檢查例6-18中封裝的ArrayOfPoints也提供了類似功能,但只適用于一種類型的數(shù)組vector動態(tài)數(shù)組對象的定義vector<元素類型>數(shù)組對象名(數(shù)組長度);例:vector<int>arr(5)
建立大小為5的int數(shù)組96vector動態(tài)數(shù)組對象vector數(shù)組對象的使用對數(shù)組元素的引用與普通數(shù)組具有相同形式:數(shù)組對象名[下標表達式]但vector數(shù)組對象名不表示數(shù)組首地址獲得數(shù)組長度用size函數(shù)數(shù)組對象名.size()97vector動態(tài)數(shù)組對象例6-20vector應(yīng)用舉例#include<iostream>#include<vector>usingnamespacestd;//計算數(shù)組arr中元素的平均值doubleaverage(constvector<double>&arr){ doublesum=0; for(unsignedi=0;i<arr.size();i++) sum+=arr[i]; returnsum/arr.size();}98vector動態(tài)數(shù)組對象intmain(){ unsignedn; cout<<"n="; cin>>n;
vector<double>arr(n); //創(chuàng)建數(shù)組對象
cout<<"Pleaseinput"<<n<<"realnumbers:"<<endl; for(unsignedi=0;i<n;i++) cin>>arr[i]; cout<<"Average="<<average(arr)<<endl; return0;}99100淺拷貝與深拷貝淺拷貝實現(xiàn)對象間數(shù)據(jù)元素的一一對應(yīng)復(fù)制。深拷貝當被復(fù)制的對象數(shù)據(jù)成員是指針類型時,不是復(fù)制該指針成員本身,而是將指針所指的對象進行復(fù)制。淺拷貝與深拷貝101例6-21對象的淺拷貝#include<iostream>#include<cassert>usingnamespacestd;classPoint{//類的聲明同例6-16//……};classArrayOfPoints{//類的聲明同例6-18//……};淺拷貝與深拷貝intmain(){ intcount; cout<<"Pleaseenterthecountofpoints:"; cin>>count;
ArrayOfPointspointsArray1(count);//創(chuàng)建對象數(shù)組
pointsArray1.element(0).move(5,10); pointsArray1.element(1).move(15,20);
ArrayOfPointspointsArray2=pointsArray1;//創(chuàng)建副本
cout<<"CopyofpointsArray1:"<<endl; cout<<"Point_0ofarray2:"<<pointsArray2.element(0).getX()<<"," <<pointsArray2.element(0).getY()<<endl; cout<<"Point_1ofarray2:"<<pointsArray2.element(1).getX()<<"," <<pointsArray2.element(1).getY()<<endl;102 pointsArray1.element(0).move(25,30); pointsArray1.element(1).move(35,40); cout<<"AfterthemovingofpointsArray1:"<<endl; cout<<"Point_0ofarray2:"<<pointsArray2.element(0).getX()<<"," <<pointsArray2.element(0).getY()<<endl; cout<<"Point_1ofarray2:"<<pointsArray2.element(1).getX()<<"," <<pointsArray2.element(1).getY()<<endl; return0;}103運行結(jié)果如下:Pleaseenterthenumberofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.CopyofpointsArray1:Point_0ofarray2:5,10Point_1ofarray2:15,20AfterthemovingofpointsArray1:Point_0ofarray2:25,30Point_1ofarray2:35,40Deleting...Destructorcalled.Destructorcalled.Deleting...接下來程序出現(xiàn)異常,也就是運行錯誤。104拷貝前拷貝后pointsArray1的數(shù)組元素占用的內(nèi)存pointssizepointsArray1pointssizepointsArray1pointsArray1的數(shù)組元素占用的內(nèi)存pointssizepointsArray2105106例6-22對象的深拷貝#include<iostream>#include<cassert>usingnamespacestd;classPoint{//類的聲明同例6-16……};classArrayOfPoints{public:ArrayOfPoints(constArrayOfPoints&pointsArray);//其他成員同例6-18};淺拷貝與深拷貝ArrayOfPoints::ArrayOfPoints(constArrayOfPoints&v){ size=v.size; points=newPoint[size]; for(inti=0;i<size;i++) points[i]=v.points[i];}intmain(){ //同例6-20}107程序的運行結(jié)果如下:Pleaseenterthenumberofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.DefaultConstructorcalled.DefaultConstructorcalled.CopyofpointsArray1:Point_0ofarray2:5,10Point_1ofarray2:15,20AfterthemovingofpointsArray1:Point_0ofarray2:5,10Point_1ofarray2:15,20Deleting...Destructorcalled.Destructorcalled.Deleting...Destructorcalled.Destructorcalled.108拷貝前pointsArray1的數(shù)組元素占用的內(nèi)存pointssizepointsArray1拷貝后pointssizepointsArray1pointsArray1的數(shù)組元素占用的內(nèi)存pointssizepointsArray2109用字符數(shù)組存儲和處理字符串字符串常量(例:"program")各字符連續(xù)、順序存放,每個字符占一個字節(jié),以‘\0’結(jié)尾,相當于一個隱含創(chuàng)建的字符常量數(shù)組“program”出現(xiàn)在表達式中,表示這一char數(shù)組的首地址首地址可以賦給char常量指針:constchar*STRING1="program";字符串變量可以顯式創(chuàng)建字符數(shù)組來表示字符串變量,例如,以下三條語句具有等價的作用:charstr[8]={'p','r','o','g','r','a','m','\0'};charstr[8]="program";charstr[]="program";110
字符串program\0用字符數(shù)組表示字符串的缺點用字符數(shù)組表示字符串的缺點執(zhí)行連接、拷貝、比較等操作,都需要顯式調(diào)用庫函數(shù),很麻煩當字符串長度很不確定時,需要用new動態(tài)創(chuàng)建字符數(shù)組,最后要用delete釋放,很繁瑣字符串實際長度大于為它分配的空間時,會產(chǎn)生數(shù)組下標越界的錯誤解決方法使用字符串類string表示字符串string實際上是對字符數(shù)組操作的封裝111
字符串string的用法(1)常用構(gòu)造函數(shù)string();//缺省構(gòu)造函數(shù),建立一個長度為0的串string(constchar*s);//用指針s所指向的字符串常量初始化string類的對象string(conststring&rhs);//拷貝構(gòu)造函數(shù)例:strings1; //建立一個空字符串strings2=“abc”;//用常量建立一個初值為”abc”的字符串strings3=s2; //執(zhí)行拷貝構(gòu)造函數(shù),用s2的值作為s3的初值112
字符串string的用法(2)常用操作符s+t 將串s和t連接成一個新串s=t 用t更新ss==t 判斷s與t是否相等s!=t 判斷s與t是否不等s<t 判斷s是否小于t(按字典順序比較)s<=t 判斷s是否小于或等于t(按字典順序比較)s>t 判斷s是否大于t(按字典順序比較)s>=t 判斷s是否大于或等于t(按字典順序比較)s[i] 訪問串中下標為i的字符例:strings1=“abc”,s2=“def”;strings3=s1+s2; //結(jié)果是”abcdef”bools4=(s1<s2); //結(jié)果是truechars5=s2[1]; //結(jié)果是’e’113
字符串114例6.23string類應(yīng)用舉例#include<string>#include<iostream>usingnamespacestd;//根據(jù)value的值輸出true或false,title為提示文字inlinevoidtest(constchar*title,boolvalue){ cout<<title<<"returns"<<(value?"true":"false")<<endl;}
字符串intmain(){ strings1="DEF"; cout<<"s1is"<<s1<<endl; strings2; cout<<"Pleaseenters2:"; cin>>s2; cout<<"lengthofs2:"<<s2.length()<<endl; //比較運算符的測試
test("s1<=\"ABC\"",s1<="ABC"); test("\"DEF\"<=s1","DEF"<=s1); //連接運算符的測試
s2+=s1; cout<<"s2=s2+s1:"<<s2<<endl; cout<<"lengthofs2:"<<s2.length()<<endl; return0;}115用getline輸入整行字符串輸入整行字符串用cin的>>操作符輸入字符串,會以空格作為分隔符,空格后的內(nèi)容會在下一回輸入時被讀取用string頭文件中的getline可以輸入整行字符串,例如:getline(cin,s2);以其它字符作為分隔符輸入字符串輸入字符串時,可以使用其它分隔符作為字符串結(jié)束的標志(例如逗號、分號)把分隔符作為getline的第3個參數(shù)即可,例如:getline(cin,s2,',');116
字符串例6.24用getline輸入字符串117include<iostream>#include<string>usingnamespacestd;intmain(){ for(inti=0;i<2;i++) { stringcity,state; getline(cin,city,','); getline(cin,state); cout<<"City:"<<city<<“State:"<<state<<endl; } return0;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 拍攝合同范例3篇
- 各種物品寄售合同范例
- 國際招標貨物合同范例
- 亮化出租維修合同范例
- 日文勞務(wù)合同范例
- 漁網(wǎng)加工銷售合同范例
- 墻體內(nèi)粉刷合同范例
- 三基護理考試題與參考答案
- 急救理論知識考試模擬題(附答案)
- 債權(quán)擔(dān)保協(xié)議合同范例
- 北京開放大學(xué)《自動控制技術(shù)及應(yīng)用》終結(jié)性考試復(fù)習(xí)題庫(附答案)
- 高中高一級部拔河比賽活動實施方案
- 每日食品安全檢查記錄
- 航空機務(wù)專業(yè)職業(yè)生涯規(guī)劃書
- 八年級英語上學(xué)期期末考試(深圳卷)-2023-2024學(xué)年八年級英語上冊單元重難點易錯題精練(牛津深圳版)
- 項目成本節(jié)約措施總結(jié)報告
- 迎元旦趣味活動及知識競賽試題及答案
- SH/T 3543-2007 石油化工建設(shè)工程項目施工過程技術(shù)文件規(guī)定
- 減鹽控油控制體重規(guī)章制度
- 建筑之歌課件PPT
- (完整版)員工流失文獻綜述
評論
0/150
提交評論