您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)c++中數(shù)組與指針是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
1.數(shù)組
數(shù)組大?。ㄔ貍€數(shù))一般在編譯時決定,也有少部分編譯器可以運(yùn)行時動態(tài)決定數(shù)組大小,比如icpc(Intel C++編譯器)。
1.1數(shù)組名的意義
數(shù)組名的本質(zhì)是一個文字常量,代表數(shù)組第一個元素的地址和數(shù)組的首地址。數(shù)組名本身不是一個變量,不可以尋址,且不允許為數(shù)組名賦值。假設(shè)定義數(shù)組:
int A[10];
那么再定義一個引用:
int* &r=A;
這是錯誤的寫法,因為變量A是一個文字常量,不可尋址。如果要建立數(shù)組A的引用,應(yīng)該這樣定義:
int* const &r=A;
此時,現(xiàn)在數(shù)據(jù)區(qū)開辟一個無名臨時變量,將數(shù)組A代表的地址常量拷貝到該變量中,再將常引用r與此變量進(jìn)行綁定。此外,定義一個數(shù)組A,則A、&A[0]、A+0是等價的。
在sizeof()運(yùn)算中,數(shù)組名代表的是全體數(shù)組元素,而不是某個單個元素。例如,定義int A[5],生成Win32的程序,sizeof(A)就等于5*sizeof(int)=5*4=20。示例程序如下。
#include <iostream> using namespace std; int main() { int A[4]={1,2,3,4}; int B[4]={5,6,7,8}; int (&rA)[4]=A; //建立數(shù)組A的引用 cout<<"A:"<<A<<endl; cout<<"&A:"<<&A<<endl; cout<<"A+1:"<<A+1<<endl; cout<<"&A+1:"<<&A+1<<endl; cout<<"B:"<<B<<endl; cout<<"rA:"<<rA<<endl; cout<<"&rA:"<<&rA<<endl; }
運(yùn)行結(jié)果:
A:0013F76C
&A:0013F76C
A+1:0013F770
&A+1:0013F77C
B:0013F754
rA:0013F76C
&rA:0013F76C
閱讀以上程序,注意如下幾點。
(1)A與&A的結(jié)果在數(shù)值上是一樣的,但是A與&A的數(shù)據(jù)類型卻不同。A的類型是int[4],&A的類型則是int(*)[4]。它們在概念上是不一樣的,這就直接導(dǎo)致A+1與&A+1的結(jié)果完全不一樣。
(2)為變量建立引用的語法格式是type& ref,因為數(shù)組A的類型是int[4],因此為A建立引用的是int (&rA)[4]=A;
1.2數(shù)組的初始化
定義數(shù)組的時候,為數(shù)組元素賦初值,叫作數(shù)組的初始化??梢詾橐痪S數(shù)組指定初值,也可以為多維數(shù)組指定初值。例如。
Int A[5]={}; //定義長度為5的數(shù)組,所有數(shù)組元素的值都為0 int A[]={1,2,3}; //定義長度為3的數(shù)組,數(shù)組元素分別為1,2,3 int A[5]={1,2}; //定義長度為5的數(shù)組,A[0],A[1]分別為1,2,其他值均為0 int A[][2]={{1,2},{3,4},{5,6}}; //定義一個類型為int[3][2]的二維數(shù)組 int A[][2]={{1},{1},{1}}; //定義一個類型為int[3][2]的二維數(shù)組,A[0][0]、A[1][0]、A[2][0]三個元素的值為1,其他元素的值均為0 //以下是幾種錯誤的初始化方法 int A[3]={1,2,3,4}; //初始化項的個數(shù)超過數(shù)組的長度 int A[3]={1,,3}; //不允許中間跳過某項
2.指針
2.1指針的定義
指針是用來存放地址值的變量,相應(yīng)的數(shù)據(jù)類型成為指針類型。在32位平臺上,任何指針類型所占用的空間都是都是4字節(jié)。比如sizeof(int*)、sizeof(double*)、sizeof(float*)等的值都為4。
2.2定義指針的形式
定義指針的形式是:type* p,其中type是指針?biāo)赶驅(qū)ο蟮臄?shù)據(jù)類型,而*則是指針的標(biāo)志,p是指針變量的名字。由于C++中允許定義復(fù)合數(shù)據(jù)類型,因此指向復(fù)合數(shù)據(jù)類型對象的指針的定義方式可能較為復(fù)雜。理解指針,關(guān)鍵是理解指針的類型和指針?biāo)赶驍?shù)據(jù)的類型。例如:
int (*p)[5]; //指針p的類型是int(*)[5],指針?biāo)赶虻臄?shù)據(jù)類型是int[5] int* p[5]; //p是有5個分量的指針數(shù)組,每個分量的類型都是int*(指向int的指針) int** p; //指針p的類型是int**,p指向的類型是int*,p是指向指針的指針
2.3指針的初始化
定義指針變量之后,指針變量的值一般是隨機(jī)值,這樣的值不是合法訪問的地址。指針變量值的合法化途徑通常有兩個,
一是顯示置空,二是讓指針指向一個已經(jīng)存在的變量,三是為指針動態(tài)申請內(nèi)存空間。如下:
//顯示置空 int *p=NULL; //將指針指向某個變量 int i; int *p=&i; //動態(tài)申請內(nèi)存空間 int* p=new int[10];
2.4指針可以參與的運(yùn)算
由于指針是一個變量,所以指針可以參與一些運(yùn)算。假設(shè)定義指針int* p,指針p能夠參與的運(yùn)算有:
(1)解引用運(yùn)算,即獲取指針?biāo)傅膬?nèi)存地址處的數(shù)據(jù),表達(dá)式為*p,如果指針指向的是一個結(jié)構(gòu)或者類的對象,那么訪問對象成員有兩種方式:(*p).mem或p->mem。
(2)取地址運(yùn)算,即獲取指針變量的地址,表達(dá)式為&p,其數(shù)據(jù)類型為int**;
(3)指針與整數(shù)相加減。表達(dá)式p+i(或者p-i),實際上是讓指針遞增或遞減地移動i個int型變量的距離。
(4)兩個指針相減,如p-q,其結(jié)果是兩個指針?biāo)鎯Φ牡刂分g的int型數(shù)據(jù)的個數(shù)。
2.5注意指針的有效性
使用指針的關(guān)鍵就是讓指針變量指向一個它可以合法訪問的內(nèi)存地址,如果不知道它指向何處,請置為空指針NULL或者((void*)0)。
在某些情況下,指針的值開始是合法的,以后隨著某些操作的進(jìn)行,它變成了非法的值。考察如下程序。
#include <iostream> using namespace std; int* pPointer; void SomeFunction() { int nNumber=25; pPointer=&nNumber; //將指針pPointer指向nNumber } void UseStack() { int arr[100]={}; } int main() { SomeFunction(); UseStack(); cout<<"value of *pPointer:"<<*pPointer<<endl; }
輸出結(jié)果是0,并非想象中的25。原因是函數(shù)SomeFunction()運(yùn)行結(jié)束之后,局部變量nNumber已經(jīng)被清空,其占有的空間在離開函數(shù)后歸還給系統(tǒng),之后又分配給函數(shù)UseStack()中的局部變量arr。因此指針pNumber的解引用后的值變成了0。所以,要想正確的使用指針,必須保證指針?biāo)赶騿卧挠行浴?/p>
3.數(shù)組與指針的關(guān)系
數(shù)組名代表數(shù)組的首地址,而數(shù)組A的某個元素A[i]可以解釋成*(A+i),所以數(shù)組名本身可以理解為一個指針(地址),一個指針常量。所以,在很多情況下,數(shù)組與指針的用法是相同的,但是數(shù)組與指針本質(zhì)上存在一些重要的區(qū)別。
(1)數(shù)組空間是靜態(tài)分配的,編譯時決定大小。而指針在定義時,可以沒有合法訪問的地址空間,也就是野指針。
(2)數(shù)組名代表一個指針常量,企圖改變數(shù)組名所代表的地址的操作都是非法的。例如如下代碼:
int arr[5]={0,1,2,3,4}; arr++; //編譯錯誤
(3)函數(shù)形參中的數(shù)組被解釋為指針。考察如下程序:
void show0(int A[]) { A++; cout<<A[0]<<endl; } void show1(int A[5]) { A++; cout<<A[0]<<endl; } int main() { int d[5]={1,2,3,4,5}; show0(d); show1(d); }
以上程序編譯通過并輸出2和2。程序中形參數(shù)組A可以進(jìn)行自增運(yùn)算,改變了自身的值,這個說明了形參數(shù)組A被當(dāng)作指針看待。之所以這樣處理,原因有兩個,一是C++語言不對數(shù)組的下標(biāo)作越界檢查,因此可以忽略形參數(shù)組的長度;二是數(shù)組作整體進(jìn)行傳遞時,會有較大的運(yùn)行時開銷,為了提高程序運(yùn)行效率,將數(shù)組退化成了指針。
(4)如果函數(shù)的形參是數(shù)組的引用,那么數(shù)組的長度將被作為類型的一部分。實際上,對數(shù)組建立引用,就是對數(shù)組的首地址建立一個常引用。由于引用是C++引入的新機(jī)制,所以在處理引用時使用了一些與傳統(tǒng)C語言不同的規(guī)范。在傳統(tǒng)的C語言中,對數(shù)組的下標(biāo)是不做越界檢查,因此在函數(shù)的參數(shù)說明中,int[5]和int[6]都被理解為int[](也就是int*),C++語言也沿用了這種處理方式。但是,int(&)[5]與int(&)[6]被認(rèn)為是不同的數(shù)據(jù)類型,在實參與形參的匹配過程作嚴(yán)格檢查??疾烊缦鲁绦?。
#include <iostream> using namespace std; void show(int(&A)[5]) { cout<<"type is int(&)[5]"<<endl; } void show(int(&A)[6]) { cout<<"type is int(&)[5]"<<endl; } int main() { int d[5]={1,2,3,4,5}; show(d); }
程序結(jié)果:
type is int(&)[5]
(5)在概念上,指針同一維數(shù)組相對應(yīng)。多維數(shù)組是存儲在連續(xù)的存儲空間,而將多維數(shù)組當(dāng)做一維數(shù)據(jù)看待時,可以有不同的分解方式。考察如下程序。
#include <iostream> using namespace std; void show1(int A[],int n) { for(int i=0;i<n;++i) cout<<A[i]<<" "; } void show2(int A[][5],int n) { for(int i=0;i<n;++i) show1(A[i],5); } void show3(int A[][4][5],int n) { for(int i=0;i<n;++i) show2(A[i],4); } int main() { int d[3][4][5]; int i,j,k,m=0; for(int i=0;i<3;++i) for(int j=0;j<4;++j) for(int k=0;k<5;++k) d[i][j][k]=m++; show1((int*)d,3*4*5); cout<<endl; show2((int(*)[5])d,3*4); cout<<endl; show3(d,3); }
程序運(yùn)行結(jié)果可以看出,以下三條輸出語句的數(shù)據(jù)結(jié)果是相同的。
show1((int *)d,3*4*5); show2((int(*)[5])d,3*4); show3(d,3);
它們的輸出結(jié)果完全一樣,即從0到59。這說明把3維數(shù)組d當(dāng)作一維數(shù)組看待,至少可以有以下3中不同的分解方式:
a.數(shù)據(jù)類型為int,元素個數(shù)為3*4*5=60;
b.數(shù)據(jù)類型為int[5],元素個數(shù)為3*4=12;
c.數(shù)據(jù)類型為int[4][5],元素個數(shù)為3。
所以,可以將多維數(shù)組看做“數(shù)組的數(shù)組”。在將多為數(shù)組轉(zhuǎn)換為指針的時候,一定要注意多為數(shù)組的分解方式,以便進(jìn)行正確的類型轉(zhuǎn)換。
(6)字符數(shù)組與字符指針的區(qū)別。
字符數(shù)組字符指針在形式上很接近,但在內(nèi)存空間的分配和使用上還是有重大的差別。如前所述,數(shù)組名并不是一個運(yùn)行實體,它本身不能被尋址。而指針是一個變量(運(yùn)行時實體),可以被尋址,它所指向的空間是否合法要在運(yùn)行時決定。錯誤地使用指針將導(dǎo)致對內(nèi)存空間的非法訪問??疾烊缦鲁绦?。
#include <iostream> using namespace std; int main() { char s[]="abc"; //s是字符數(shù)組,空間分配在棧上。對字符數(shù)組元素的修改是合法的 char *p="abc"; s[0]='x'; cout<<s<<endl; //p[0]='x'; //此句編譯出錯,指針指向常量區(qū)的字符串,對字符串常量的修改是非法的 cout<<p<<endl; }
程序輸出結(jié)果:
xbc
abc
關(guān)于c++中數(shù)組與指針是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。