第一次寫技術類部落格,不足之處還請指出
問題最先是幫學弟改程式的時候考慮到乙個bug可能是陣列越界的原因導致,因為我們都知道,訪問二維陣列中的元素時,多採用下標的方式,如a[i][j],就表示訪問a陣列第i行,第j列的元素。
而學弟用的是指標訪問,當然本質是一樣的,只是語法上稍有不同:
* ( *( a + i ) + j ) 這樣同樣表示訪問a陣列第i行,第j列的元素,但是相較於按下標訪問很是麻煩,所以並不推薦,或者說應該是要避免這種寫法。
但是學弟 用的是另一種方式:
*(*(a + x)) 我知道學弟想表達的是如果x大於a的行數,編譯器變便會自動轉向另一列,如是迴圈。但是真的可以這樣做嗎?
我自己做了一段除錯的**:
#include "iostream"
using namespace std;
int main()
; for(int i = 0; i < 8; i++) }
cout << *(*(a + 8)) << endl;
cout << *(*(a + 9)) << endl;
system("pause");
return 0;
}
這段**輸出如下:
很奇怪的是不僅沒有報錯,而且還都有輸出,* ( * ( a + 8 ) )輸出了乙個很大的值,而* ( * ( a + 9 ) )則輸出了0,但至少有一點可以確定,那就是 不論 a + 8,還是 a + 9 都已不再是a陣列中的元素指標,但是為什麼會有這種情況呢?
詢問大神後解釋如下:
這個位置到底是不是0,這個很難確定,如果你的a[8][8]是在棧上的,那麼a後面的乙個位址是否清0和編譯器有關,一般的編譯器為了效率是不清0的,但這個不確定。因為c和c++的標準裡沒有強制規定一定要清0;如果a[8][8]是在堆上申請的,也就是通過new或者malloc,那麼這個將更複雜,因為對new的呼叫會有2套邏輯,其中有一種走mmap的邏輯是會清0的,而另一種走記憶體池的邏輯不清0
至於為什麼編譯器沒有報錯,那是因為c/c++的編譯器為了效率考慮根本不會去檢查陣列是否越界,完全要靠自己保證**的正確。
二維陣列 二維陣列和指標
include using namespace std int main 如上面這段程式所示,通過取位址符 指標 p 獲得了變數 a 的位址,那麼解引用符 就可以從 p 中得到變數 a 的值。也就是說,p a和 p a是等價的。p 是變數 a 的位址,從 p 中就可以取出 a 的值。反之,能從 p ...
陣列 二維陣列
一組相同型別的資料組合,是一種引用型別。陣列名稱不是固定的,與其存放的資料的型別有關。如 存放int型別的資料,陣列名稱 int 存放字串資料,陣列名稱 string 存放scanner型別的資料,陣列名稱 scanner陣列中的每個資料,都是這個陣列的元素。1 宣告 元素型別 變數名 元素型別 變...
陣列 二維陣列
陣列,從名字很簡單看出就是數字組合,一堆數 一堆元素 在一起。然後看一下怎麼定義,怎麼初始化。陣列的動態初始化 初始化之後每個元素的儲存內容為其對應資料型別的預設值。資料型別 陣列名 new 陣列型別 大小 int arr new int 5 資料型別 陣列名 new 陣列型別 大小 int arr...