深入理解C/C++二维数组
深入理解C/C++二維數組
前言
本來以為自己對二維數組的理解還可以,沒感覺有什么,但是今天小伙伴問了一個問題感覺迷惑了好久,于是決定細致的記錄一下,一步一步的探究各種關于二維數組的問題,鞏固基礎。
二維數組的探究之旅(初級)
首先定義二維數組
int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};然后開始研究二維數組名和地址的關系
// 打印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 : 5a+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表現的竟然像一個一維數組(因為直接按索引就可以得到元素),這里也增加了一種新的取元素方式。這可能和[]的工作方式有關,這部分還是沒弄明白,歡迎指導。
總結
這篇博客詳細的記錄了由二維數組名引出的各種細節,雖然還不完善,但是確實讓自己鞏固了基礎,以后估計應該不會倒在二維數組了……吧。
轉載于:https://www.cnblogs.com/bobxxxl/p/10438034.html
總結
以上是生活随笔為你收集整理的深入理解C/C++二维数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IP修改器的作用以及用途
- 下一篇: Markdown写作中的图床解决方案(基