![C++程序設(shè)計(jì)第5章 數(shù)組與指針_第1頁(yè)](http://file4.renrendoc.com/view/13587ada7c9b86923674b82a583f107d/13587ada7c9b86923674b82a583f107d1.gif)
![C++程序設(shè)計(jì)第5章 數(shù)組與指針_第2頁(yè)](http://file4.renrendoc.com/view/13587ada7c9b86923674b82a583f107d/13587ada7c9b86923674b82a583f107d2.gif)
![C++程序設(shè)計(jì)第5章 數(shù)組與指針_第3頁(yè)](http://file4.renrendoc.com/view/13587ada7c9b86923674b82a583f107d/13587ada7c9b86923674b82a583f107d3.gif)
![C++程序設(shè)計(jì)第5章 數(shù)組與指針_第4頁(yè)](http://file4.renrendoc.com/view/13587ada7c9b86923674b82a583f107d/13587ada7c9b86923674b82a583f107d4.gif)
![C++程序設(shè)計(jì)第5章 數(shù)組與指針_第5頁(yè)](http://file4.renrendoc.com/view/13587ada7c9b86923674b82a583f107d/13587ada7c9b86923674b82a583f107d5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第五章數(shù)組與指針本章將深入學(xué)習(xí)數(shù)組包括多維數(shù)組的知識(shí)和應(yīng)用,揭示數(shù)組與指針的關(guān)系。
C(C++)語(yǔ)言擁有獲得變量地址和操縱地址的能力,用來(lái)操縱地址的變量稱為指針。5.1
數(shù)組復(fù)習(xí):1、數(shù)據(jù)組織方式、定義方式、存儲(chǔ)方式、元素訪問(wèn)方式2、使用方法inta[100];charstr[40];Studentslist[50];Complexc_array[100];//結(jié)構(gòu)體數(shù)組//對(duì)象數(shù)組(1)對(duì)下標(biāo)變量做循環(huán)操作:(2)以數(shù)組做為函數(shù)參數(shù):for(i=0;i<n;i++)
cin>>a[i];Input(a,100);3、舉例:voidInput(inta[],intn);數(shù)組變量定義:例:定義數(shù)組
inta[10];doublea1[100];inta2[16],n,a3[23],m;voidf(intn,intm){
int
b[n];…}//ok//ok//錯(cuò),b的大小依賴于形參,在編譯時(shí)無(wú)法確定,因?yàn)榫幾g時(shí)無(wú)法確定數(shù)組
//大小,所以必須明確告訴數(shù)組大小數(shù)組的初始化:*定義時(shí)直接初始化例:
inta[4]={1,1,2,4};
intb[4]={1,2};
intc[]={1,2,3,4,5,6,7,8,};注意:這種寫法只能用于數(shù)組初始化時(shí)。語(yǔ)句里不允許采用這種寫法。數(shù)組元素可通過(guò)普通賦值語(yǔ)句設(shè)置。//b[2],b[3]自動(dòng)初始化為0數(shù)組的初始化:intarray[5]={1,2,3,4,5,6};//錯(cuò)intarray[]={1,2,3,4,5,6};//okintarray[5]={1,,3,4,5,6};//錯(cuò)intarray[5]={1,2,3};//okintarray[]={0};//okintarray[5]={};//錯(cuò)數(shù)組的存儲(chǔ)實(shí)現(xiàn)數(shù)組占據(jù)一連續(xù)存儲(chǔ)區(qū),元素順序排列,0號(hào)元素在最前面,各元素占相同空間。如有inta[6];
a[0]a[1]a[2]a[3]a[4]a[5]a數(shù)組名是數(shù)組元素的內(nèi)存地址,數(shù)組名是一個(gè)常量,不能被賦值。數(shù)組a200020042008201220162020a[0]a[1]a[2]a[3]a[4]a[5]例:
intfibon[10]={0,1,1,2,3,5,8,13,21,34};
0123
2134fibon[0]fibon[1]fibon[2]fibon[3]fibon[8]fibon[9]數(shù)組在內(nèi)存中的存儲(chǔ)數(shù)組名為fibon,這是一個(gè)包含10個(gè)整型元素的一維數(shù)組,第一個(gè)元素為fibon[0],存放0,最后一個(gè)元素為fibon[9],存放34。數(shù)組元素的訪問(wèn)方式:通過(guò)下標(biāo)操作符,按元素在數(shù)組中的位置進(jìn)行訪問(wèn),稱為索引訪問(wèn)或下標(biāo)訪問(wèn)。cout<<fibon[8]<<endl;輸出:21編譯程序不檢查下標(biāo)越界錯(cuò)誤。C++程序員必須保證下標(biāo)不越界。數(shù)組的使用*sizeof(a)數(shù)組a存儲(chǔ)量//40=10*4*sizeof(a[0])數(shù)組a大小//4*sizeof(a)/sizeof(a[0])數(shù)組a的元素個(gè)數(shù)//10例:
inta[10]={0,1,1,2,3,5,8,13,21,34};
例:#include<iostream.h>intx[5];//全局變量voidmain(){
inti;for(i=0;i<5;i++)cout<<x[i]<<'\t';
cout<<endl;
inty[5];//局部變量
for(i=0;i<5;i++)cout<<y[i]<<'\t';
cout<<endl; }={1,2,3}輸出:000005個(gè)隨機(jī)數(shù)輸出:0000012300
constSIZE=15;
intmain(){
int
arr[SIZE],i,high,low;
for(i=0;i<SIZE;i++)arr[i]=rand()%100;//產(chǎn)生100以內(nèi)隨機(jī)數(shù)
cout<<"Herearethe"<<SIZE<<"randomnumbers:"<<endl;
for(i=0;i<SIZE;i++)cout<<arr[i]<<'\t';
cout<<endl;high=arr[0];//初始化時(shí)最大和最小值均為數(shù)組首元素
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;}【例5.1】找出整型數(shù)組各元素中的最大數(shù)和最小數(shù)。數(shù)組中的數(shù)由隨機(jī)數(shù)函數(shù)rand()產(chǎn)生。5.1.2數(shù)組名作為函數(shù)參數(shù)數(shù)組名作為參數(shù):
數(shù)組名可以作為函數(shù)的參數(shù)。在函數(shù)調(diào)用時(shí)傳遞實(shí)參數(shù)組的首地址,所以在被調(diào)函數(shù)中對(duì)形參數(shù)組的處理實(shí)際就是對(duì)調(diào)用函數(shù)的實(shí)參數(shù)組的處理。
C++只傳遞數(shù)組首地址,而對(duì)數(shù)組邊界不加檢查。好處:
函數(shù)對(duì)長(zhǎng)度不等的同類數(shù)組都通用。如要指定長(zhǎng)度可以設(shè)定另一個(gè)參數(shù)來(lái)傳遞數(shù)組元素的個(gè)數(shù)?!纠?.2】字符數(shù)組與字符數(shù)組相連接
void
strcat(chars[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}intmain(void){
chara[40]="李明";
charb[20]="是東南大學(xué)學(xué)生";
strcat(a,b);
cout<<a<<endl;//打印字符數(shù)組a
return0;}ABCDEFG\0
HIJK\0void
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);asbctABCDEFG
HIJK\0void
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);asbctHvoid
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);as
HIJK\0bctABCDEFGH
Ivoid
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);as
HIJK\0bctABCDEFGH
IJvoid
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);as
HIJK\0bctABCDEFGH
IJKvoid
strcat(char
s[],charct[]){
inti=0,j=0;
while(s[i]!=0)i++;//指針移到s數(shù)組尾部
while(ct[j]!=0)
s[i++]=ct[j++];//將ct數(shù)組中的元素添加到s數(shù)組尾部
s[i]='\0';}
chara[40]=“ABCDEFG";charb[20]=“HIJK";
strcat(a,b);as
HIJK\0bctABCDEFGH
IJK\0例:用數(shù)組名作函數(shù)參數(shù)實(shí)現(xiàn)逆序輸出constintn=4;voidinvert(inta[]){
inti,temp;for(i=0;i<n/2;i++){
temp=a[i];
a[i]=a[n-1-i];
a[n-1-i]=temp;
}}intmain(){
int
i,b[n];for(i=0;i<n;i++)cin>>b[i];invert(b);for(i=0;i<n;i++)cout<<b[i]<<'\t';
cout<<endl;return0;}b1,2,3,4ba1,2,3,4invert(b)執(zhí)行之初ba4,3,2,1invert(b)執(zhí)行到末尾b4,3,2,1invert(b)執(zhí)行之后5.2多維數(shù)組
[6]計(jì)算機(jī)對(duì)“二維數(shù)組”的解釋處理該表的數(shù)組定義為:119753117131175312108642mat[0]mat[1]mat[2]——數(shù)組的數(shù)組mat[3]int按行存儲(chǔ)(二維拉成一維)——元素地址的計(jì)算(1)對(duì)下標(biāo)變量做循環(huán)操作:(2)以數(shù)組做為函數(shù)參數(shù):二維數(shù)組的初始化:
intmat[3][6]={1,1,2,4};
intmat[3][6]={{1,1,2,4},{3,6,2}};
intmat[][6]={{1,1,2,4},{3,6,2}};使用方法for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>a[i][j];形參數(shù)組可省略第一維
例:
floata[3][4];把二維數(shù)組看作是一種特殊的一維數(shù)組:它的元素又是一個(gè)一維數(shù)組。如:把a(bǔ)數(shù)組看成一維數(shù)組:
a[0]-----------a[0][0]a[0][1]a[0][2]a[0][3]
a
a[1]-----------a[1][0]a[1][1]a[1][2]a[1][3]
a[2]-----------a[2][0]a[2][1]a[2][2]a[2][3]二維數(shù)組的引用二維數(shù)組的元素的表示形式為:
數(shù)組名
[下標(biāo)][下標(biāo)]如
a[2][3]
下標(biāo)可以是整型表達(dá)式,如
a[2-1][2*2-1]。數(shù)組元素是左值,可以出現(xiàn)在表達(dá)式中,也可以被賦值。例
b[1][2]=a[2][3]/2;二維數(shù)組的初始化*定義時(shí)直接初始化inta[3][2]={{1,2},{3,4},{5,6}};inta[3][2]={1,2,3,4,5,6};inta[][2]={{1,2},{3,4},{5,6}};inta[][2]={1,2,3,4,5,6};兩種寫法效果一樣兩種寫法效果一樣第一維(高維)可省,低維不可省可以對(duì)部分元素賦初值
inta[3][4]={{1},{5},{9}};只對(duì)各行第1列的元素賦初值,其余元素值自動(dòng)置為0。
100050009000也可以對(duì)各行中的某一元素賦初值:
inta[3][4]={{1},{0,6},{0,0,11}};初始化后的數(shù)組元素如下:
1000060000110也可以只對(duì)某幾行元素賦初值:
inta[3][4]={{1},{5,6}};數(shù)組元素為:
100056000000
第3行不賦初值。二維數(shù)組的使用和表示設(shè):doublea[3][2];
a代表數(shù)組整體,a[0]、a[1]和a[2]是成員數(shù)組,一維數(shù)組,a[0][1]表示a的0元素?cái)?shù)組中下標(biāo)1的元素,可作為整型變量。例:
a[2][1]=a[0][1]+a[1][1];
for(i=0;i<3;i++)
for(j=0;j<2;j++)a[i][j]=i+j;二維數(shù)組的存儲(chǔ)*數(shù)組元素連續(xù)存儲(chǔ),例:doublea[3][2];
a的開始位置也是其首成員a[0]的開始位置,也是a[0]首成員a[0][0]的位置。有了確定的關(guān)系后可以算出多維數(shù)組任一元素在內(nèi)存的位置,設(shè)有a數(shù)組m行n列,每個(gè)元素占b個(gè)字節(jié),a[i][j]的首地址為:
數(shù)組的首地址+(i*n+j)*b;注意:
復(fù)合類型只能對(duì)各元素逐個(gè)操作,不能整體操作。
圖5.36*3*4的三維數(shù)組多維數(shù)組分析:
C/C++對(duì)數(shù)組的理解可推廣至所謂的“多維數(shù)組”??啥x為:int
d[6][3][4];例:輸出30個(gè)學(xué)生8門功課的成績(jī)#include<iostream.h>voidmain(){
intgrades[30][8];
inti,j;for(i=0;i<30;i++)for(j=0;j<8;j++)
cin>>grades[i][j];for(i=0;i<30;i++){
cout<<i+1<<"號(hào)學(xué)生的成績(jī):"<<endl;for(j=0;j<8;j++)cout<<grades[i][j]<<"
";
cout<<endl;}}//鍵入1號(hào)同學(xué)8門功課的成績(jī)….若,二重循環(huán)改寫成如下形式:for(j=0;j<8;j++)for(i=0;i<30;i++)
cin>>grades[i][j];//鍵入1號(hào)到30號(hào)同學(xué)的第1門功課的成績(jī)….例:用數(shù)組元素作函數(shù)的實(shí)參#include<iostream.h>voidmain(){
int
max_value(int
x,intmax);//函數(shù)聲明
inti,j,row=0,colum=0,max;
inta[3][4]={{5,12,23,56},{19,28,37,46},{-12,-34,6,8}};max=a[0][0];for(i=0;i<=2;i++)for(j=0;j<=3;j++){max=max_value(a[i][j],max);
if(max==a[i][j]){row=i;colum=j;}}//i行號(hào),j列號(hào)
cout<<"max="<<max<<",row="<<row<<",colum="<<colum<<endl;}輸出:
max=56,row=0,colum=3int
max_value(int
x,intmax){if(x>max)returnx;elsereturnmax;}1416192589101571212182024741361091013141567511109878129412231516691153152619221445321821171693211191713117530076543210圖5.4極點(diǎn)與鞍點(diǎn)示意圖【例5.4】已知矩陣
intmat[8][8],找出其中的極點(diǎn)與鞍點(diǎn)。如某元素在所在行相鄰點(diǎn)中與所在列相鄰點(diǎn)中均為最大或最小,則為極點(diǎn);如某元素在所在行(或列)相鄰點(diǎn)中為最大,同時(shí)該元素在所在列(或行)相鄰點(diǎn)中為最小,則為鞍點(diǎn)。mat[2][4]→極大點(diǎn)mat[2][6]→極大點(diǎn)mat[4][1]→極大點(diǎn)mat[5][2]→極大點(diǎn)mat[6][3]→極大點(diǎn)mat[2][5]→鞍點(diǎn)mat[3][3]→極小點(diǎn)mat[5][6]→極小點(diǎn)mat[6][1]→極小點(diǎn)#include<iostream>singnamespacestd;intmat[8][8]={0,3,5,7,11,┅,25,19,16,14};
int
maxmin(int
a,int
b,intc){
if(a>b&&b<c)//判斷相鄰3元素中間元素是否最大或最小
return-1;//b為最小返回-1
else
if(a<b&&b>c)return1;//b為最大返回1
else
return0;//其它返回0}b:為最大返回1,最小返回-1,其它返回0intmain(){
int
i,j,k,l;
for(i=1;i<=6;i++)//第1行第1列,最后1行,最后1列不在比較之列
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<<"極大點(diǎn):";elseif(k==-1&&l==-1)cout<<"極小點(diǎn):";elsecout<<“鞍點(diǎn):”;
cout<<mat[i][j]<<"i="<<i<<";j="<<j<<endl;}return0;}【例5.5】矩陣轉(zhuǎn)置與矩陣相乘。下標(biāo)作為參數(shù)傳遞。voidinverse(int[3][6],int[6][3]);//轉(zhuǎn)置矩陣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;}void
inverse(intmatrix1[3][6],intmiddle[6][3]){//轉(zhuǎn)置矩陣
int
i,j;
for(i=0;i<3;i++)
for(j=0;j<6;j++)middle[j][i]=matrix1[i][j];}810122313853457924610745344556246129562322144366matrix1[3][6]middle[6][3]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];}}}8534107451295623221443663210-1-2987654*25721022317627629823634237329654512418574845308772middle[6][3]matrix2[3][4]result[6][4]void
output(intresult[6][4]){//矩陣輸出
cout<<"result"<<'\n';
int
I,j;
for(i=0;i<6;i++){
for(j=0;j<4;j++)
cout<<setw(4)<<result[i][j]<<"";
cout<<'\n';}}5.3
指針與地址
5.3.1指針的概念5.3.2指針變量的賦值、初始化與簡(jiǎn)單應(yīng)用指針是C++語(yǔ)言中的重要概念,也是C++語(yǔ)言的重要特色。使用指針,可以使程序更加簡(jiǎn)潔、緊湊、高效。指針(Pointer)是什么?為什么要使用指針?(1)指針──即地址指針就是一個(gè)地址,它指向了內(nèi)存中的一個(gè)數(shù)據(jù)單元。在win32中,指針是一個(gè)32位無(wú)符號(hào)整數(shù)。(4字節(jié))指針就像門牌號(hào)碼,門牌號(hào)碼的長(zhǎng)度都一樣,但是對(duì)應(yīng)的房子的大小各不相同。5.3.1指針的概念1.內(nèi)存地址──內(nèi)存中存儲(chǔ)單元的編號(hào)變量地址──系統(tǒng)分配給變量的內(nèi)存單元的起始地址3.變量值的存取──通過(guò)變量在內(nèi)存中的地址進(jìn)行
(1)直接訪問(wèn)──直接利用變量的地址進(jìn)行存取(通過(guò)變量名或地址訪問(wèn)一個(gè)變量的方式)(2)間接訪問(wèn)──通過(guò)另一變量訪問(wèn)該變量的值(3)為表示指針變量和它指向的變量之間的關(guān)系,用指針運(yùn)算符“*
”表示。指針除了可以指向變量之外,還可以指向內(nèi)存中其他任何數(shù)據(jù)結(jié)構(gòu),如數(shù)組,結(jié)構(gòu)體和聯(lián)合體等,它還可以指向函數(shù)。(2)指針變量──專門用于存儲(chǔ)其它變量地址的變量。
例:inta=6;
int*p=&a;
指針變量p的值就是變量a的地址。指針與指針變量的區(qū)別,就是變量值與變量的區(qū)別。2000pa20006間接訪問(wèn)指針類型變量的定義格式:
存儲(chǔ)類型*變量名;如:int*p1;double*ptitle;char*ptr;指針類型指:它所指向變量的類型,而不是指針本身數(shù)據(jù)值的類型,任何一個(gè)指針本身的數(shù)據(jù)值都是unsignedlongint型(4字節(jié))。p1,ptitle和ptr的長(zhǎng)度相等指針的聲明:5.3.2指針變量的賦值、初始化與簡(jiǎn)單應(yīng)用指針是一個(gè)變量,在程序中使用時(shí),必須先聲明,后使用。在指針聲明的同時(shí)也可以進(jìn)行初始化。
指針的定義:
存儲(chǔ)類型數(shù)據(jù)類型*指針變量名;例:int*p1; staticint*p2; char*da;inta;int*pa=&a;合法定義&:
表示取地址*:表示取指針指向變量地址的值&a為變量a的地址;*pa為指針變量指向變量a的存儲(chǔ)單元注:
1.把一個(gè)變量的內(nèi)存地址作為初始值賦給指針時(shí),該變量必須在指針初始化之前已經(jīng)說(shuō)明過(guò)(變量只有在說(shuō)明之后才被分配一定的內(nèi)存地址)。把一個(gè)指針初始化為空指針:
int*px=0;或int*px=NULL;
稱指針px為空指針。表示當(dāng)前該指針并不指向該類型的任何一個(gè)變量(對(duì)象)。2.該變量的數(shù)據(jù)類型必須與指針的數(shù)據(jù)類型一致。為使用安全起見(jiàn),一般來(lái)說(shuō),在定義指針時(shí),最好初始化(如,初始化為空指針)。3.如果在定義指針時(shí),指針初始化為0或者根本沒(méi)有初始化。則在使用此指針前,就必須給它賦有意義的值。例:
intn,*p1;
//定義指針p1時(shí)沒(méi)有初始化
p1=&n;
//給指針p1賦值為int型變量n的地址或者:
intn,*p1=0;
//定義指針p1時(shí)初始化為0
p1=&n;
//給指針p1賦值為int型變量n的地址
C++編譯系統(tǒng)為每一個(gè)指針變量分配4個(gè)字節(jié)的存儲(chǔ)單元,用來(lái)存放變量的地址。在定義指針變量時(shí)要注意:
(1)慎用指針——對(duì)指針變量絕不可任意賦一個(gè)內(nèi)存地址。如
int*P=(int*)0xaf80;(2)在定義指針變量時(shí)必須指定基類型。
一個(gè)指針變量只能指向同一個(gè)類型的變量。(不同類型數(shù)據(jù)在計(jì)算機(jī)中存儲(chǔ)方式和所占的字節(jié)數(shù)不同)例:一個(gè)指向整數(shù)類型的指針變量,如果使指針值加1,意味使地址值加4,一個(gè)指向雙精度類型的指針變量,如果使指針值加1,意味使地址值加8。(3)常量是不可尋址的,p_age=&20是錯(cuò)的。但常變量是可尋址的,如:
constfloatPI=3.14159;float*pointer=&PI;(4)指針的類型可以強(qiáng)制轉(zhuǎn)換,有特殊應(yīng)用,例:
intm,*pm=&m;char*p1=(char*)&m,*p2=(char*)pm;
用pm讀的是整型數(shù),用p1,p2讀的是整型數(shù)的第一個(gè)字節(jié)。
C語(yǔ)言的指針容易失控,在C++中增加了引用類型,它具有指針的主要功能,但限制了靈活性,使用更加安全。建議在函數(shù)參數(shù)傳遞中,能用“引用”時(shí)絕不用“指針”。20age218age1p_age#include<iostream>
usingnamespacestd;
int
main(){
intage1=18,age2=20,*p_age;
p_age=&age1;//情況1,見(jiàn)圖
cout<<"ageofwangpingis“<<*p_age<<endl;
p_age=&age2;//情況2
cout<<"ageofzhanglingis"<<*p_age<<endl;
return0;}注意:指針變量p_age在定義說(shuō)明時(shí)要加“*”,這里“*”為說(shuō)明符;而在可執(zhí)行語(yǔ)句中p_age不用也不允許加“*”號(hào)。在可執(zhí)行語(yǔ)句中“*”為間接引用運(yùn)算符,*p_age代表p_age所指向的在內(nèi)存中可尋址的數(shù)據(jù)。在上例中最后的*p_age就是age2。【例5.6】指針賦值實(shí)例指針的關(guān)系運(yùn)算:兩個(gè)指針變量的關(guān)系運(yùn)算是根據(jù)兩個(gè)指針變量值的大?。ㄗ鳛闊o(wú)符號(hào)整數(shù))來(lái)進(jìn)行比較的(限同類型的指針變量)。注:
1.比較兩個(gè)指針變量相等,是判斷兩個(gè)指針變量是否指向相同的內(nèi)存單元,即兩個(gè)指針值是否相同。
2.不等比較,是判斷兩個(gè)指針是否指向不同的內(nèi)存單元。
3.當(dāng)指針變量與0比較時(shí),表示指針變量的值是否為空。注意:C++編譯器只對(duì)指針的運(yùn)算作語(yǔ)法上的檢查,不管指針的使用是否正確。指針的正確必須由程序的設(shè)計(jì)者自己來(lái)保證。
C++中,同一個(gè)符號(hào)可能表示不同的運(yùn)算符。如:“*”既表示乘法運(yùn)算符又表示指針運(yùn)算符,“&”可表示“按位與”又可表示取地址運(yùn)算符。所有運(yùn)算符按規(guī)定的優(yōu)先級(jí)操作:(1)運(yùn)算符“*”和“&”,優(yōu)先級(jí)相同,按自右向左方向例:
inta=3;
int*p1,*p2;p1=&a;p2=&*p1;//將a的地址賦給p2,使p2指向ap2=&*p1;&a&bp1p210010abp1&ap2&ba100b10p2=&a*&a的含義,先進(jìn)行&a的運(yùn)算,得到a的地址,再進(jìn)行*運(yùn)算,即&a所指向的變量。
\*&a和*pointer_1的作用相同等價(jià)于變量a。設(shè)已執(zhí)行:pointer_1=&a;則*&a與a等價(jià)。例:輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出a和bintmain(){
int*p1,*p2,*p,a,b;
cin>>a>>b;p1=&a;//使p1指向ap2=&b;//使p2指向bif(a<b){//如果a<b就使p1與p2的值交換
p=p1;p1=p2;p2=p;//交換p1與p2的指向
}
cout<<″a=″<<a<<″b=″<<b<<endl;
cout<<″max=″<<*p1<<″min=″<<*p2<<endl;return0;}輸入:4578
輸出:a=45b=78max=78min=45&a&bp1p24578abp1&bp2&aa45b78p1=&a;//把變量a的地址賦給p1p2=&b;//把變量a的地址賦給p2if(a<b){p=p1;p1=p2;p2=p;}
//地址交換指針常量:指針常量是固定指向一個(gè)對(duì)象的指針,即指針本身是常量:
charch=’a’,ch1=’x’;
char*const
ptr=&ch;//注意const放在類型說(shuō)明之后,變量名之前*ptr=’b’;//正確
ptr=&ch1;//錯(cuò)誤
ptr本身在初始化時(shí)所指向的地址是不可改變的,但它指向的目標(biāo)ch的值是可以改變的。常量指針:
常量指針是指向“常量”的指針,即指針本身可以改指向別的對(duì)象,但不能通過(guò)該指針修改對(duì)象,該對(duì)象可以通過(guò)其他方式修改,常用于函數(shù)的參數(shù),以免誤改了實(shí)參。charch=’a’,ch1=’x’;constchar*ptr1=&ch;
//ptr1是常量指針*ptr1=’b’;
//錯(cuò)誤,只能做ch=’b’ptr1=&ch1;
//正確4.4
引用4.4.1引用值傳遞指主調(diào)函數(shù)向被調(diào)函數(shù)傳遞的是實(shí)參的值。當(dāng)向被調(diào)函數(shù)傳遞一個(gè)變量的數(shù)據(jù)時(shí),系統(tǒng)為每一個(gè)形參變量分配相應(yīng)的臨時(shí)存儲(chǔ)空間,調(diào)用函數(shù)的實(shí)參值就復(fù)制在對(duì)應(yīng)的形參的臨時(shí)存儲(chǔ)空間中。被調(diào)函數(shù)只對(duì)形參的臨時(shí)存儲(chǔ)空間發(fā)生作用,不對(duì)實(shí)參本身進(jìn)行操作。問(wèn)題:如果要求改變實(shí)參的值,怎么辦呢?如果實(shí)參是一個(gè)復(fù)雜的對(duì)象,重新分配內(nèi)存會(huì)引起程序執(zhí)行效率下降,怎么辦呢?有一種導(dǎo)出型數(shù)據(jù)類型—引用(reference)可以解決上面的難題。引用又稱別名(alias)。引用的定義:
引用是給一個(gè)已經(jīng)定義的變量重新起一個(gè)別名,而不是定義一個(gè)新的變量,定義的格式為:
類型&引用變量名=已定義過(guò)的變量名;例:
inta;//定義a是整型變量
int&b=a;//聲明b是a的引用
b是新定義的引用類型變量,是變量a的別名。
聲明后,a或b的作用相同,都代表同一變量。(b和a占用內(nèi)存中的同一個(gè)存儲(chǔ)單元,地址相同,不另占空間)a=20;b=a;聲明一個(gè)引用型變量時(shí),必須同時(shí)使之初始化,即聲明它代表哪一個(gè)變量,并且從此不可改變。變量名和引用名都指向同一段內(nèi)存單元。如果形參為變量的引用名,實(shí)參為變量名,則在調(diào)用函數(shù)進(jìn)行虛實(shí)結(jié)合時(shí),并不是為形參另外開辟一個(gè)存儲(chǔ)空間(常稱為建立實(shí)參的一個(gè)拷貝),而是把實(shí)參變量的地址傳給形參(引用名),這樣引用名也指向?qū)崊⒆兞俊R粋€(gè)變量的引用就是變量的別名。引用主要用于函數(shù)之間的數(shù)據(jù)傳遞。【例4.3】引用作為形參Xy1.4142.7181.4142.7181.414
voidswap(double&d1,
double&d2){
doubletemp;temp=d1;d1=d2;d2=temp;}int
main(void){
doublex,y;
cout<<"請(qǐng)輸入x和y的值"<<'\n';
cin>>x>>y;
swap(x,y);
cout<<"x="<<x<<'\t'<<"y="<<y<<'\n';
return0;}圖5.5參數(shù)d1、d2為引用時(shí)內(nèi)存分配示意
d1d2temp實(shí)參傳值,形參別名#include<iostream.h>voidmain(){voidswap(int*,int*);
inti=3,j=5;swap(&i,&j);//實(shí)參是變量的地址
cout<<i<<″″<<j<<endl;//i和j的值已互換}voidswap(int*p1,int*p2){//形參是指針變量
inttemp;temp=*p1;//以下3行用來(lái)實(shí)現(xiàn)i和j的值互換*p1=*p2;*p2=temp;}實(shí)參傳地址,形參指針指向變量地址例:對(duì)3個(gè)變量按由小到大的順序排序。intmain(){ voidsort(int&,int
&,int&);
//函數(shù)聲明,形參是引用類型
inta,b,c;
//a,b,c是需排序的變量
inta1,b1,c1;
//a1,b1,c1最終的值是已排好序的數(shù)列
cout<<″Pleaseenter3integers:″;
cin>>a>>b>>c;
a1=a;b1=b;c1=c;
sort(a1,b1,c1);
//調(diào)用sort函數(shù),以a1,b1,c1為實(shí)參
cout<<″sortedorderis″<<a1<<″″<<b1<<″″<<c1<<endl;//此時(shí)a1,b1,c1已排好序
return0;}voidsort(int&i,int&j,int&k){
//對(duì)i,j,k3個(gè)數(shù)排序
voidchange(int&,int&);
//函數(shù)聲明,形參是引用類型
if(i>j)change(i,j);
//使i<=j if(i>k)change(i,k);
//使i<=k if(j>k)change(j,k);
//使j<=k}voidchange(int&x,int&y)
{
//使x和y互換
inttemp; temp=x; x=y; y=temp;}運(yùn)行結(jié)果:
Pleaseenter3integers:2312-345↙sortedorderis-3451223
【例4.4】采用不同返回方式的求正方形面積函數(shù)的比較。double
temp;//全局變量doublefsqr1(doublea){
temp=a*a;return
temp;}double&fsqr2(doublea){
temp=a*a;returntemp;}intmain(){
doublex=fsqr1(5.5);//第一種情況
doubley=fsqr2(5.5);//第二種情況
cout<<"x="<<x<<'\t‘<<"y="<<y<<endl;
return0;}引用作為返回值運(yùn)行結(jié)果為:
x=30.25y=30.25運(yùn)行結(jié)果一樣,但在內(nèi)存中的活動(dòng)卻不同。
圖4.6普通返回
圖4.7引用返回函數(shù)fsqr1返回全局變量temp,是先將temp的值賦值給那個(gè)無(wú)名臨時(shí)變量,回到主函數(shù)后,賦值語(yǔ)句x=fsqr1(5.5)把臨時(shí)變量的值賦給x,無(wú)名臨時(shí)變量生命期結(jié)束。沒(méi)有使用無(wú)名臨時(shí)變量過(guò)渡,而是直接返回temp本身,賦給y。無(wú)名臨時(shí)變量中放的是temp的地址。不產(chǎn)生拷貝,效率提高了。注:采用引用返回方式時(shí),返回的不能是函數(shù)中的局部變量(此時(shí)返回的局部變量地址已失效)。5.5數(shù)組與指針5.5.1數(shù)組名、指針和指針運(yùn)算5.5.2指針作為函數(shù)參數(shù)5.5.1數(shù)組名、指針和指針運(yùn)算數(shù)組名和指針的關(guān)系:數(shù)組名是一個(gè)指針常量a[0]a[1]a[2]a[3]a[4]a[5]inta[6];int*p=&a[0];p指針指向數(shù)組后,可以像數(shù)組名一樣使用:for(inti=0;i<6;i++)cin>>a[i];for(inti=0;i<6;i++)cout<<p[i]<<‘\t’;ints=0;for(inti=0;i<6;i++)s=s+*p++;//或*(a+i)
p=a;for(inti=0;i<6;i++)cin>>*(p+i);//或*(a+i)
//等價(jià)于p=a;指針的算術(shù)運(yùn)算:(1)++或--運(yùn)算
<指針變量>++;<指針變量>--;
計(jì)算機(jī)內(nèi)部按下式計(jì)算:
<指針變量>=<指針變量>+sizeof(<指針變量類型>)<指針變量>=<指針變量>-sizeof(<指針變量類型>)指針變量的值加或減一個(gè)常量。指針變量的值加一個(gè)常量n,類同于++運(yùn)算,計(jì)算機(jī)的實(shí)際運(yùn)算為:<指針變量>=<指針變量>+sizeof(<該指針變量的類型>)*n;例:intmain(){
inta[10]={100,200,300,400,500};
int*p1=&a[0];
cout<<"*p1="<<*p1<<"\tp1="<<(int)p1<<endl; p1=p1+4;
cout<<"*p1="<<*p1<<"\tp1="<<(int)p1<<endl;return0;}*p1=100p1=1310552*p1=500p1=1310568*P++:取P所指向單元的數(shù)據(jù)作為表達(dá)式的值,然后使
P指向下一個(gè)單元;(*P)++:
取P所指向單元的數(shù)據(jù)作為表達(dá)式的值,然后使
該單元的數(shù)據(jù)值增加1;*++P:使P指向下一個(gè)單元,然后取該單元的數(shù)據(jù)作為表達(dá)式的值;++*P:將P所指向單元的數(shù)據(jù)增加1并作為表達(dá)式的值。指針的算術(shù)運(yùn)算:(3)“++”、“--”、“*”、“&”的優(yōu)先級(jí)相同,按自右向左方向結(jié)合。例:inta[5]={100,200,300,400,500};p1=&a[0],b=*p1++;
//取*p1的值參加運(yùn)算,再使指針p1的值加1,b的值為100
p1=&a[0],b=*++p1;
//先使指針p1的值加1,再取*p1的值參加運(yùn)算,b的值為200
p1=&a[0],b=(*p1)++;
//先取*p1的值參加運(yùn)算,再完成*p1的值加1,b的值為100*(p1++);
等價(jià)于
*p++;
p1=&a[1],b=++*p1;
//取出p1所指向的內(nèi)容,使其加1后參加接著的運(yùn)算,b的值為201//a[1]的值修改為201,p1仍然指向數(shù)組a的第一個(gè)元素。如果指針p的初值為&a[0]:
(1)p+i和a+i就是a[i]的地址,或者說(shuō),它們指向a數(shù)組的第i個(gè)元素。(2)*(p+i)或*(a+i)是p+i或a+i所指向的數(shù)組元素,即a[i]。(3)指向數(shù)組元素的指針變量也可以帶下標(biāo),如p[i]和*(p+i)等價(jià)。引用一個(gè)數(shù)組元素,可用以下方法:(1)下標(biāo)法,如a[i]形式;若已使p的值為a,則*(p+i)就是a[i]。可以通過(guò)指向數(shù)組元素的指針找到所需的元素。(2)指針?lè)ǎ?(a+i)或*(p+i)。其中a是數(shù)組名,p是指向數(shù)組元素的指針變量。直觀不必每次都重新計(jì)算地址,提高執(zhí)行效率例:
設(shè)有一個(gè)int型數(shù)組,有10個(gè)元素。用三種方法輸出各元素。intmain(){
inta[10],i;
for(i=0;i<10;i++)cin>>a[i];
for(i=0;i<10;i++)cout<<a[i]<<″″;
cout<<endl;return0;}1.使用數(shù)組名和下標(biāo)2.使用數(shù)組名和指針運(yùn)算intmain(){
inta[10],i;
for(i=0;i<10;i++)cin>>*(a+i);
for(i=0;i<10;i++)cout<<*(a+i)<<″″;
cout<<endl;return0;}3.使用指針變量intmain(){
inta[10];
int*p;
for(p=a;p<(a+10);p++)cin>>*p;
for(p=a;p<(a+10);p++)
cout<<*p<<″″;
cout<<endl;return0;}intmain(){//例
inta[5]={100,200,300,400,500};
int*p1,*p2; for(p2=&a[0];p2<=&a[4];p2++)//p2指向a數(shù)組
cout<<*p2<<'\t';
cout<<endl; p1=&a[0]+5;//p1指向a數(shù)組后的地址單元
p2=&a[0];//p2指向a數(shù)組的首地址
intsum=0; while(p2!=p1){sum+=*p2++;}//累加
cout<<"元素之和為:"<<sum<<endl;return0;}輸出:100200300400500
元素之和為:15005.5.2指針作為函數(shù)參數(shù)
引用調(diào)用與指針傳值調(diào)用:建議:
在函數(shù)參數(shù)傳遞中,能用“引用”時(shí)絕不用“指針”。*參數(shù)傳遞兩種方法:傳值、傳引用。*傳指針作為特殊的傳值調(diào)用,使得形參獲得實(shí)參地址,能夠直接訪問(wèn)并修改實(shí)參數(shù)據(jù)。*傳引用邏輯上稱為別名,物理上是傳實(shí)參的地址。intmain(){
int*pointer_1,*pointer_2,a,b;
cin>>a>>b;pointer_1=&a;//使pointer_1指向apointer_2=&b;//使pointer_2指向bif(a<b)swap(pointer_1,pointer_2);//如果a<b,使*pointer_1和*pointer_2互換
cout<<″max=″<<a<<″min=″<<b<<endl;//a已是大數(shù),b是小數(shù)
return0;}voidswap(int*p1,int*p2){//將*p1的值與*p2的值交換
inttemp;temp=*p1;*p1=*p2;*p2=temp;}交換a和b的值,p1和p2的值不變不能寫成:int*temp;*temp=*p1;*p1=*p2;*p2=*temp;主函數(shù)swap(pointer_1,pointer_2)p1p2結(jié)果如果希望通過(guò)函數(shù)調(diào)用得到n個(gè)要改變的值步驟:①在主調(diào)函數(shù)中設(shè)n個(gè)變量,用n個(gè)指針變量指向它們;②被調(diào)用函數(shù)的形參為n個(gè)指針變量(與實(shí)參類型相同);③在主調(diào)函數(shù)中將n個(gè)指針變量作實(shí)參,將它們的值(是地址值)傳給所調(diào)用函數(shù)的n個(gè)形參指針變量。則,形參指針變量也指向這n個(gè)變量;④通過(guò)形參指針變量的指向,改變?cè)搉個(gè)變量的值;⑤在主調(diào)函數(shù)中就可以使用這些改變了值的變量。intmain(){voidswap(int*p1,int*p2);
int*pointer_1,*pointer_2,a,b;
cin>>a>>b;pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);
cout<<″max=″<<a<<″min=″<<b<<endl;return0;}voidswap(int*p1,int*p2){
int*temp;temp=p1;p1=p2;p2=temp;}p1、p2指向的地址改變,a、b的值沒(méi)變p1、p2指向的地址交換if(a<b)swap(pointer_1,pointer_2);voidswap(int*p1,int*p2){int*temp;temp=p1;p1=p2;p2=temp;}實(shí)參和形參之間的數(shù)據(jù)傳遞是單向的“值傳遞”方式。調(diào)用函數(shù)時(shí)不會(huì)改變實(shí)參指針變量的值,但可以改變實(shí)參指針變量所指向變量的值。使用指針變量作函數(shù)參數(shù),可以通過(guò)指針變量改變主調(diào)函數(shù)中變量的值,相當(dāng)于通過(guò)函數(shù)調(diào)用從被調(diào)用的函數(shù)中得到多個(gè)值。例輸入a,b,c3個(gè)整數(shù),按由大到小的順序輸出。intmain(){voidexchange(int*,int*,int*);//對(duì)exchange函數(shù)的聲明
inta,b,c,*p1,*p2,*p3;
cin>>a>>b>>c;p1=&a;p2=&b;p3=&c;//指向3個(gè)整型變量
exchange(p1,p2,p3);//交換p1,p2,p3指向的3個(gè)整型變量的值
cout<<a<<″″<<b<<″″<<c<<endl;//按由大到小的順序輸出3個(gè)整數(shù)
return0;}voidexchange(int*q1,int*q2,int*q3){voidswap(int*,int*);
//對(duì)swap函數(shù)的聲明
if(*q1<*q2)swap(q1,q2);
//調(diào)用swap,將q1與q2所指向的變量的值互換
if(*q1<*q3)swap(q1,q3);
//調(diào)用swap,將q1與q3所指向的變量的值互換
if(*q2<*q3)swap(q2,q3);
//調(diào)用swap,將q2與q3所指向的變量的值互換}voidswap(int*pt1,int*pt2){//將pt1與pt2所指向的變量的值互換
inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;}運(yùn)行結(jié)果:
12-5687↙
//輸入
8712-56//輸出實(shí)參與形參的結(jié)合,有4種形式:
inta[5]={1,2,3,4,5};
int*p=a;fun();
實(shí)參
形參數(shù)組名fun(a); 數(shù)組名fun(ints[])
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 預(yù)備技師申請(qǐng)書
- 2025年度大型活動(dòng)外籍嘉賓邀請(qǐng)及服務(wù)合同
- 重名改名的申請(qǐng)書
- 互聯(lián)網(wǎng)+創(chuàng)業(yè)基礎(chǔ)知到智慧樹章節(jié)測(cè)試課后答案2024年秋云南大學(xué)滇池學(xué)院
- 現(xiàn)代物流產(chǎn)業(yè)概覽發(fā)展現(xiàn)狀與未來(lái)趨勢(shì)
- 核心詞匯講堂知到智慧樹章節(jié)測(cè)試課后答案2024年秋湖南師范大學(xué)
- 化學(xué)-重慶市2024年秋高二(上)期末聯(lián)合檢測(cè)試卷試題和答案
- 電商平臺(tái)消費(fèi)者行為與市場(chǎng)預(yù)測(cè)
- 2025年度企業(yè)銀行賬戶變更委托協(xié)議
- 電商平臺(tái)的技術(shù)架構(gòu)與系統(tǒng)安全保障
- GB/Z 30966.71-2024風(fēng)能發(fā)電系統(tǒng)風(fēng)力發(fā)電場(chǎng)監(jiān)控系統(tǒng)通信第71部分:配置描述語(yǔ)言
- 腦梗死的護(hù)理查房
- 2025高考數(shù)學(xué)專項(xiàng)復(fù)習(xí):概率與統(tǒng)計(jì)的綜合應(yīng)用(十八大題型)含答案
- 產(chǎn)后抑郁癥講課課件
- 2024-2030年中國(guó)紫蘇市場(chǎng)深度局勢(shì)分析及未來(lái)5發(fā)展趨勢(shì)報(bào)告
- 銷售人員課件教學(xué)課件
- LED大屏技術(shù)方案(適用于簡(jiǎn)單的項(xiàng)目)
- 2024智慧城市數(shù)據(jù)采集標(biāo)準(zhǔn)規(guī)范
- Lesson 6 What colour is it(教學(xué)設(shè)計(jì))-2023-2024學(xué)年接力版英語(yǔ)三年級(jí)下冊(cè)
- 歷年國(guó)家二級(jí)(Python)機(jī)試真題匯編(含答案)
- 第五單元任務(wù)二《準(zhǔn)備與排練》教學(xué)設(shè)計(jì) 統(tǒng)編版語(yǔ)文九年級(jí)下冊(cè)
評(píng)論
0/150
提交評(píng)論