陣列名與指標間的聯絡
陣列名與指標間的區別分析總結
在剛剛接觸到陣列與指標時,我想最常苦惱的問題就是陣列名與指標之間有什麼關係了吧。但是他們兩者之間真的有什麼數不清道不明的關係嗎?答案無疑是否定的,接下來就讓我們來一**竟吧!
首先我們需要了解一下陣列與指標的定義:
陣列名與指標間的聯絡
從定義中分析,不難發現陣列名與指標並沒有直接的關係,那麼為什麼會將陣列名與指標相混淆呢?
這是由於在近乎所有使用到陣列名的表示式中,陣列名都表示陣列第乙個元素的位址,可將其看作是乙個指標常量。而這個指標常量所指向的型別與陣列元素的型別一致。也正是因為如此陣列名在表示式中不能作為左值,當其作為右值時其意義與&arr[0]是一致的。
在了解到陣列名相當於是乙個指標常量後,那麼是否可以用乙個指標變數去指向乙個陣列呢?當然可以!如以下**所示:
int arr[5] = ;
int *p = arr; //用指標變數p指向arr,p中儲存的是陣列首元素的位址。
當我們在對數組成員進行訪問時就可以利用陣列名下標以及指標間接訪問兩種方式,如以下表示式所示:
arr[ 1 ]; //訪問陣列中的第2個元素。
*( arr+1 ); //與 arr[ 1 ] 作用相同。
*arr + 1 ; //*的優先順序高於+,表示第乙個元素的值+1。
arr[5]; //訪問越界,產生隨機值。
2[arr]; //與 *(arr +2)作用相同。
注意:在以上**中用到了指標+1的做法,這裡的1個偏移量代表的陣列的乙個元素大小而非byte數 !!
以上討論的是陣列名在表示式中以首元素的首位址出現的情況,但在以下兩種情況中陣列名代表的是整個陣列。
陣列名與指標間的區別分析
以上討論的是陣列名與指標之間的共通之處,但並不代表說二者就是乙個東西。接下來就指標與陣列的定義與宣告進行分析。在此之前需要再對宣告與定義二者的意義進行表述。(千萬不要覺得這很簡單,越簡單的東西越容易忽略其細節!)
注意!!: 二者之間最重要的區別就是定義為物件分配了記憶體而宣告沒有分配記憶體,只是指向了已經定義的那片記憶體。
情況一:定義為指標宣告為陣列
//在檔案text.c中對指標arr進行定義
char* arr = "abcdefg";
----------
//在檔案main.c中對arr以陣列的形式進行宣告並呼叫
#include
extern arr;
int main()
執行結果如下,其並沒有輸出我們希望的字串「abcdefg」,那麼是不是就能說明指標與陣列名是不一樣的呢?接下來對其進行分析。
在檔案test.c中將變數arr宣告為乙個指標變數,但在main.c檔案中將其宣告為乙個陣列,那麼在main函式中arr就將會以陣列的形式出現,並以陣列的方式對arr的內容進行解析。在定義中變數arr中儲存的是乙個指標也就是乙個位址,占用4個位元組,但以char型陣列進行解析時就會把位址本身的內容解析為陣列元素。而arr真正指向的字串卻完全沒有被訪問到。原理如下圖所示:
但是有沒有方法能將表示式進行改造,使arr依舊以陣列的形式正確的訪問到定義的字串常量呢?接下來進行分析。
若要訪問到字串常量就一定需要拿到字串儲存未知的位址,但是現在的位址卻以內容的方式被儲存在了乙個字元陣列裡。此時arr若作為指標其偏移量是乙個位元組,若要一次取到四個位元組的所有內容可以將arr強制轉化為int*,再將其解引用就可以一次獲取四個位元組的內容也就是字串位址。雖然現在拿到了位址的內容彈藥利用它訪問對應的位址就還需將其轉化為char*型別。總結下來其表示式就是:(char*) * (int*) arr情況一:定義為陣列宣告為指標
//在檔案text.c中對陣列arr進行定義
char arr = "abcdefg";
----------
//在檔案main.c中對arr以指標的形式進行宣告並呼叫
#include
extern
char* arr;
int main()
**執行崩潰….
在檔案test.c中將變數arr宣告為乙個字串,但在main.c檔案中將其宣告為乙個指標,那麼在main函式中變數arr中存放的資料無論是什麼型別都將以4個位元組為單位解析為位址,並按照這個位址(位置位址)在記憶體中進行訪問。從而導致程式崩潰。
原理如下圖所示:
如果讓arr繼續以指標的形式出現但想正常訪問到字元陣列的內容有什麼方法呢?接下來進行分析:
若要訪問乙個陣列首先要做的就是獲取到這個陣列的首位址,這是我們不難發現指標變數arr所占用的位址就是字元陣列arr的首位址,那麼只要對指標變數取位址就可以了(&arr)。此時雖然獲取到了陣列首元素的位址單數陣列元素型別為char,記憶體偏移量為乙個位元組,而指標的記憶體偏移量是4個位元組,如此只要將(&arr)強制轉化為char*型別就可以通過加件偏移量獲取到每乙個陣列元素。總結下來其表示式就是:(char*)& arr。
根據以上兩個例子就不難發現指標與陣列名雖然有聯絡但依舊存在有很大不同。
現將二者關係進行如下總結:
指標與陣列名的關係
1.對於一維陣列 a 10 一級指標p p a 把陣列名 常量位址 賦值給了指標p 正確 因為p是int指標,而陣列名相當於int 常量,所以正確。p a 編譯時就會出現錯誤,會顯示警告 從不相容的指標型別賦值。那是因為 a是取陣列a的位址,相當於int 10 型別的陣列指標,而指標p只是普通的一級...
陣列名與指標
引言 指標是c c 語言的特色,而陣列名與指標有太多的相似,甚至很多時候,陣列名可以作為指標使用。於是乎,很多程式設計者就被搞糊塗了。而許多的大學老師,他們在c語言的教學過程中也錯誤得給學生講解 陣列名就是指標 很幸運,我的大學老師就是其中之一。時至今日,我日復一日地進行著c c 專案的開發,而身邊...
陣列名與指標
include using namespace std int main int b 2 10 陣列名本身就是指標,再加上 就變成了雙指標,這裡的雙指標的就是指二維陣列 int p int a 1 p指向a陣列的第6個元素 雖然不存在 cout p 1 cout b 1 cout b 0 retur...