C 動態陣列,多重指標問題

2021-06-16 08:48:13 字數 4530 閱讀 3993

今天遇到乙個問題,要開闢乙個二維指標空間,詳細的看了一下網上有關動態指標、動態陣列等開闢方法以及學習前輩們對於動態陣列問題的解決經驗!

一、 首先說明一下多重指標問題,這裡解釋到第三層,為了方便理解,我們可以將三重指標理解為三維陣列,

首先看乙個經典的例子:

int ***a,x=10,y=20;

a=(int ***)malloc(sizeof(int)*x);//分配是什麼?

for(i=1;i<10;i++)

for(i=1;i

1:   

*a=(int **)malloc(sizeof(int)*x);可以理解為二重指標的第一層,分配了10個int型的二重指標空間

a是三重指標的位址,*a是二重指標的首位址;(*a)[0];(*a)[1];(*a)[2];(*a)[3];(*a)[4]........

2:    (*a)[i]=(int *)malloc(sizeof(int)*y);這個代表每乙個二層指標又被分配了空間;這裡每一二層指標被分配了

20個(int *)的指標;即,每一二層指標又有20個孩子

3:   (*a)[i][j]=10;這樣賦值正確,前邊的(*a)是獲取乙個二維陣列,後邊是乙個二維陣列的乙個元素。直接賦值是可以的

4:  我們同樣可以理解為樹形,幾重指標就是幾層樹

以上是關於三維指標的解釋,二維指標也就是可以理解成二維陣列。

二、陣列的指標、指標陣列以及指向指標的指標

考慮陣列的指標的時候我們要同時考慮型別和維數這兩個屬性。換一句話,就是說乙個陣列排除在其中儲存的數值,那麼可以用型別和維數來位置表示他的種類。

a)一維陣列

在c和c++中陣列的指標就是陣列的起始位址(也就第乙個元素的位址),而且標準文件規定陣列名代表陣列的位址(這是位址數值層面的陣列表示)。例如:

int a[10]; int *p;

p=&a[0]//和p=a是等價的:

因為a是陣列名,所以他是該陣列的位址,同時因為第乙個元素為a[0],那麼&a[0]也代表了該陣列的位址。但是我們是不是就說乙個陣列名和該陣列的第乙個元素的&運算是一回事呢?在一維的時候當時是的,但是在高維的時候,我們要考慮到維數給陣列帶來的影響。

a[10]是乙個陣列,a是陣列名,它是乙個包含10個int型別的陣列型別,不是一般的指標變數噢!(雖然標準文件規定在c++中從int到int*直接轉換是可以的,在使用的時候似乎在函式的引數為指標的時候,我們將該陣列名賦值沒有任何異樣),a代表陣列的首位址,在數字層面和a[10]的位址一樣。這樣我們就可以使用指標變數以及a來操作這個陣列了。

所以我們要注意以下問題:

(1) p[i]和a[i]都是代表該陣列的第i+1個元素;

(2) p+i和a+i代表了第i+1個元素的位址,所以我們也可以使用 *(p+i)和*(a+i)來引用物件元素;

(3)p+1不是對於指標數量上加一,而是表示從當前的位置跳過當前指標指向型別長度的空間,對於win32的int為4byte;

b)多維陣列

對於二維陣列a[4][6];由於陣列名代表陣列的起始位址,所以a(第一層)和第乙個元素a[0][0]位址的數字是相同的,但是意義卻是不同的。對於該陣列我們可以理解為:a的一維陣列(第一層),它有四個元素a[0]、a[1]、a[2]、a[3](第二層),而每個元素又含有6個元素a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5](第三層),…到此我們終於訪問到了每個元素了,這個過程我們經歷了:a->a[0]->a[0][0];

整體來講:a是乙個4行5列的二維陣列,a表示它指向的陣列的首位址(第乙個元素位址&a[0]),同時a[0]指向一行,它是這個行的名字(和該行的第乙個元素的首位址相同(第乙個元素為位址&a[0][0]))。所以從數字角度說:a、a[0]、&a[0][0]是相同的,但是他們所處的層次是不同的。

既然a代表二維陣列,那麼a+i就表示它的第i+1個元素*(a+i)的位址,而在二維陣列中

*(a+i)又指向乙個陣列,*(a+i)+j表示這個陣列的第j+1個元素的位址,所以要訪問這個元素可以使用 *(*(a+i)+j)(也就是a[i][j])。

他們的示意圖為(虛線代表不是實際存在的):

對照這個圖,如下的一些說法都是正確的(對於a[4][6]):

a是乙個陣列型別,*a指向乙個陣列;a+i指向乙個陣列;a、*a和&a[0][0]數值相同;a[i]+j和*(a+i)+j是同乙個概念; 總結一下就是:我們對於二維指標a,他指向陣列a[0,1,2,3],使用*,可以使他降級到第二層次,這樣*a就指向了第乙個真正的陣列。對於其他的情況我們也可以採用相同的方式,對於其他維數和型別的陣列我們可以採用相類似的思想。

說到指向陣列的指標,我們還可以宣告乙個指標變數讓它指向乙個陣列。例如:

int (*p)[5];

這時p就是乙個指標,要指向乙個含有5個int型別元素的陣列,指向其他的就會出現問題。

這個時候我們可以使用上面的什麼東西來初始化呢?

我們可以使用*a,*(a+1),a[2]等。

原因很簡單:我們在乙個二維的陣列中,那麼表達方式有上面的相互類似的意義呢?只有 *a,*(a+1),a[2]等,

c)指標陣列

乙個指標陣列是指乙個陣列中的每個元素都是乙個指標,例如:

int *p[10];//而不能是int (*p)[10]

或者char *p[10];

此時p是乙個指標(數值上和&p[0]一樣);

在前面有int t[10];

int * pt=t;//使用pt指向t

那麼這裡我們用什麼指向int *t[10]中的t呢?我們要使用乙個指標的指標:

int **pt=t;

這是因為:在int *t[10]中,每個元素是指標,那麼同時t又指向這個陣列,陣列上和&t[0]相同,也就是指向t[0],指向乙個指標變數,可以說是乙個指標的指標了,所以自然要用

int **pt;

d)指標的指標

乙個指標變數內部可以儲存乙個值,這個值是另外乙個物件的位址,所以我們說乙個指標變數可以指向乙個普通變數,同樣這個指標變數也有乙個位址,也就是說有乙個東西可以指向這個指標變數,然後再通過這個指標變數指向這個物件。那麼如何來指向這個指標變數呢?由於指標變數本身已經是乙個指標了(右值),那麼我們這裡就不能用一般的指標了,需要在指標上體現出來這些特點,我們需要定義指標的指標(二重指標)。

int *p1=&i; int**p2=&p1;

綜合以上的所有點,下面是我們常常看到一些匹配(也是經常出錯的地方):

int a[3],b[2][3],c,*d[3]; void fun1(int *p); void fun2(int (*p)[3]); void fun3(int **p); void fun4(int p[3]); void fun5(int p); void fun6(int p[2][3]); void fun7(int (&p)[3]);

函式 不會產生編譯時刻的可能值(但邏輯上不一定都對)函式

不會產生編譯時刻的可能值(但邏輯上不一定都對)

fun1

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun2 b

,b+i,

fun3 d

fun4

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun5

a, &a[i], *b ,b[i],&b[i][j] ,&c ,d[i]

fun6 b

fun7 a

三、對於動態陣列問題:

參閱他人的建議得知:使用一維陣列實現多為陣列的功能。定義動態啊的一維陣列比較簡單,而且所派分的記憶體單元都是連續的,其實在記憶體中的儲存都是在一塊連續的記憶體塊上儲存,性質一樣!所以建議使用一維陣列實現多維的功能;

例項如下:

1、用一重指標

int i,j,num1,num2;

int *p=new int[num1*num2];

for(i=0;i

2、用二重指標

int num1,num2;

int **p;

p=new int*[num1];//開闢空間,理解起來有點難

for(int i=0;i

另外兩個例項:

一維動態陣列的例項:

#include

using namespace std;

int main()

cout<

for(int i=1;i<=n;i++)

delete arr;//動態空間釋放}

複製**

二維動態陣列的例項:

#include

using namespace std;

int main()

cout<<"*****************下面是輸入部分*****************"<

for(int i=0;i

}cout<<"*****************下面是輸出部分*****************"<

for(int i=0;i

}for(int i=0;i

delete arr[i];

delete arr;

arr=null;}

C 多重繼承的指標問題

下面說說c 多重繼承中關於指標的一些問題。指標指向問題 先看下面的程式 class base1 class base2 class derive public base1,public base2 virtual void fun2 int main 我電腦上的執行結果 首先,可以看到 od和pb1...

C 多重指標

首先看乙個經典的例子 int a,x 10,y 20 a int malloc sizeof int x 分配是什麼?for i 1 i 10 i for i 1 i 1 a int malloc sizeof int x 可以理解為二重指標的第一層,分配了10個int型的二重指標空間 a是三重指標...

C 指標與動態陣列

使用new 和 delete,動態地調整陣列大小,通常是當前陣列滿了的時候,將陣列容量翻倍,假設用int變數capacity代表當前陣列大小,ptr是當前陣列指標 float tempptr new float capacity 2 for int i 0 i capacity i delete p...