深入理解C C 二維陣列

2022-08-26 08:09:14 字數 3325 閱讀 9273

本來以為自己對二維陣列的理解還可以,沒感覺有什麼,但是今天小夥伴問了乙個問題感覺迷惑了好久,於是決定細緻的記錄一下,一步一步的**各種關於二維陣列的問題,鞏固基礎。

首先定義二維陣列

int a[3][3] = ;
然後開始研究二維陣列名和位址的關係

// 列印a a[0] 和 a[0][0]的位址

cout << "the value of a: " << a << endl;

cout << "the value of a[0]: " << a[0] << endl;

cout << "the address of a[0][0]: " << &a[0][0] << endl;

the value of a: 0x7ffe5b8c1ee0

the value of a[0]: 0x7ffe5b8c1ee0

the address of a[0][0]: 0x7ffe5b8c1ee0

就如各種資料說的那樣,可以看出三個表達指向的是乙個位址,繼續看

這裡看一下每一行\(a[i], 0\leq i<3\)

for (int i = 0; i < 3; ++i)

cout << "the value of a[" << i << "]" << " is " << a[i] << endl;

the value of a[0]is 0x7ffe5b8c1ee0

the value of a[1]is 0x7ffe5b8c1eec

the value of a[2]is 0x7ffe5b8c1ef8

列印的結果是每一行的首位址,可以看出來每兩個位址之間差12個位元組,也就是三個int的長度(每個int是四個位元組,大部分編譯器是這樣的)。這與我們預期的是一樣的,畢竟是每行的首位址。

繼續走,我們看到\(a, a[0], a[0][0]\)的位址是一樣的,都是最頭上的首位址,那麼這裡用這個位址推導進而顯示其他位置的元素

// 由a[0]推出其他,這裡以第1行第1列(0 base)為例

cout << "the address of a[0+1]+1 " << "is " << a[0+1]+1 << endl;

cout << "the value of a[0+1]+1 " << "is " << *(a[0+1]+1) << endl;

cout << "the address of a[0]+4 " << "is " << a[0]+4 << endl;

cout << "the value of a[0]+4 " << "is " << *(a[0]+4) << endl;

the address of a[0+1]+1 is 0x7ffe5b8c1ef0

the value of a[0+1]+1 is 5

the address of a[0]+4 is 0x7ffe5b8c1ef0

the value of a[0]+4 is 5

前兩種行是通過加a[0]的索引得到其他行的首位址,然後再加偏移量得到的,後兩行是直接計算偏移量得到的。

繼續,由\(a[0][0]\)的位址推導

// 由&a[0][0]推出其他, 這裡以第1行第1列(0 base)為例

cout << "the address of a[0][0]+4 " << "is " << &a[0][0]+4 << endl;

cout << "the value of a[0][0]+1 " << "is " << *(&a[0][0]+4) << endl;

the address of a[0][0]+4 is 0x7ffe5b8c1ef0

the value of a[0][0]+1 is 5

這裡和上面的第二中直接加偏移量的情況是一樣的。

現在是讓人有點迷惑的地方,就是陣列名a既然和\(a[0], a[0][0]\)指向的位址一樣,那麼是否用法也一樣呢?

我們先來看看如何用a得到\(a[1][1]\)

// 假設要求a[1][1](5)

cout << "a[1][1] inferred from a : " << *(*(a+1)+1) << endl;

a[1][1] inferred from a : 5
a+1指向的是\(a[1]\),這裡是第1行(0 base)的首位址,對它解引用得到a[1]的位址,然後+1就得到\(a[1][1]\)的位址了。

前面說a+1是指向位址的,那麼是不是意味a是乙個二級指標呢?

int *p = a; // 不通過
實驗發現報錯,說明a不是乙個指標型別,繼續看

int *p = *a;

cout << "the value of p is: " << p << endl;

cout << "the value of *p is: " << *p << endl;

cout << "the value of p+1 is: " << p+1 << endl;

cout << "the value of *(p+1) is: " << *(p+1) << endl;

cout << "a[1][1] inferred from p : " << *(p+1*3+1) << endl;

the value of p is: 0x7ffe5b8c1ee0

the value of *p is: 1

the value of p+1 is: 0x7ffe5b8c1ee4

the value of *(p+1) is: 2

a[1][1] inferred from p : 5

對a解引用後確實是乙個位址,所以可以定義指標,並且可以用加偏移量的方式得到\(a[1][1]\)

更為有趣的是

cout << "a[1][1] inferred from p : " << p[1*3+1] << endl;
a[1][1] inferred from p : 5
指標p表現的竟然像乙個一維陣列(因為直接按索引就可以得到元素),這裡也增加了一種新的取元素方式。這可能和的工作方式有關,這部分還是沒弄明白,歡迎指導。

這篇部落格詳細的記錄了由二維陣列名引出的各種細節,雖然還不完善,但是確實讓自己鞏固了基礎,以後估計應該不會倒在二維陣列了……吧。

深入理解二維陣列

1 include2 define debug 0 3int main 4,i,j 6 if debug 7 a 8 a 0 9 a 1 10 a 2 11 a 3 12 endif 13 printf a p a 1 p n n a,a 1 相差16位元組 1415 printf a 0 p a ...

C C 二維陣列

已知在c c 中當陣列作為函式的引數進行傳遞時,該陣列自動退化為同型別的指標。1 二維陣列的概念 在c語言中,二維陣列實際上是一種特殊的一維陣列,它的每個元素也是乙個一維陣列。因此,二維陣列下標形式正確寫法如下 int arrays i j 2 二維陣列作為函式引數 傳遞陣列時必須讓編譯器知道陣列最...

深入理解C C 陣列和指標

c語言中陣列和指標是一種很特別的關係,首先本質上肯定是不同的,本文各個角度論述陣列和指標。一 陣列與指標的關係 陣列和指標是兩種不同的型別,陣列具有確定數量的元素,而指標只是乙個標量值。陣列可以在某些情況下轉換為指標,當陣列名在表示式中使用時,編譯器會把陣列名轉換為乙個指標常量,是陣列中的第乙個元素...