1. 程式人生 > >指標陣列VS陣列指標,這次要搞懂!

指標陣列VS陣列指標,這次要搞懂!

指標陣列與陣列指標詳解

1.什麼是指標陣列和陣列指標?

  • 指標陣列:指標陣列可以說成是”指標的陣列”,首先這個變數是一個數組,其次,”指標”修飾這個陣列,意思是說這個陣列的所有元素都是指標型別,在32位系統中,指標佔四個位元組。
  • 陣列指標:陣列指標可以說成是”陣列的指標”,首先這個變數是一個指標,其次,”陣列”修飾這個指標,意思是說這個指標存放著一個數組的首地址,或者說這個指標指向一個數組的首地址。
    根據上面的解釋,可以瞭解到指標陣列和陣列指標的區別,因為二者根本就是種類型的變數。

2.指標陣列和陣列指標到底是什麼?

2.1指標陣列

首先先定義一個指標陣列,既然是陣列,名字就叫arr

char *arr[4] = {"hello"
, "world", "shannxi", "xian"}; //arr就是我定義的一個指標陣列,它有四個元素,每個元素是一個char *型別的指標,這些指標存放著其對應字串的首地址。

(當一個變量出現左右都出現一個運算子時,沒有記住運算子優先順序的人就會糾結arr變數到底跟哪一個運算子先結合。如果是自己定義一個指標陣列,搞不清楚運算子的優先順序,那麼就加上小括號(),比如定義一個指標陣列,可以寫成char *(arr[4]),不過在定義之前一定要清楚自己定義的變數,如果目的是一個數組,那就把arr[4]括起來,如果是一個指標,就把*arr括起來。如果是看到一段這樣的程式碼,可以從他的初始化來分別它是陣列還是指標,很明顯,我這定義的是一個數組,如果是指標,會用NULL來初始化。)

這個指標陣列有多大呢?答案是16個位元組,因為它是一個指標陣列。(這是廢話,正話下面說)
每當出現這些問題時,腦子裡一定要第一時間反應出記憶體映像圖

記憶體映像象圖 內容 許可權
棧區 函式中的普通變數 可讀可寫
堆區 動態申請的記憶體 可讀可寫
靜態變數區 static修飾的變數 可讀可寫
資料區 用於初始化變數的常量 只讀
程式碼區 程式碼指令 只讀

這裡最左側一列是一個很簡陋但能說明意思的記憶體圖,一般情況下,從棧區到程式碼區,是從高地址到低地址。棧向下增長,堆向上增長。

arr[4]是一個在主函式定義的陣列。把它對應到對應到記憶體中,arr是一個在棧區,有四個元素的陣列,而每一個數組又是一個指標,所以說它的四個元素各佔四個位元組,所以變數arr的大小是16個位元組。

那麼就有人問了?初始化arr的{“hello”, “world”, “shannxi”, “xian”};的是什麼鬼?
這四個不是什麼鬼,他們也存在在記憶體中,只是跟arr這個變數不在同一段空間,它們被分配在只讀資料區,陣列arr[4]的四個指標元素,分別存放著這四個字串的首地址,想象一下,從棧區有四隻無形的手指向資料區的空間。arr+1會跳過四個位元組,。也就是一個指標的大小
這就相當與定義char *p1 = “hello”,char *p1 = “world”,char *p3 = “shannxi”, char *p4 = “xian”,這是四個指標,每個指標存放一個字串首地址,然後用arr[4]這個陣列分別存放這四個指標,就形成了指標陣列。

2.2陣列指標

首先來定義一個數組指標,既然是指標,名字就叫pa

char (*pa)[4];

如果指標陣列和陣列指標這倆個變數名稱一樣就會是這樣:char *pa[4]和char (*pa)[4],原來指標陣列和陣列指標的形成的根本原因就是運算子的優先順序問題,所以定義變數是一定要注意這個問題,否則定義變數會有根本性差別!

pa是一個指標指向一個char [4]的陣列,每個陣列元素是一個char型別的變數,所以我們不妨可以寫成:char[4] (*pa);這樣就可以直觀的看出pa的指向的型別,不過在編輯器中不要這麼寫,因為編譯器根本不認識,這樣寫只是幫助我們理解。

既然pa是一個指標,存放一個數組的地址,那麼在我們定義一個數組時,陣列名稱就是這個陣列的首地址,那麼這二者有什麼區別和聯絡呢?

char a[4];,

a是一個長度為4的字元陣列,a是這個陣列的首元素首地址。既然a是地址,pa是指向陣列的指標,那麼能將a賦值給pa嗎?答案是不行的!因為a是陣列首元素首地址,pa存放的卻是陣列首地址,a是char 型別,a+1,a的值會實實在在的加1,而pa是char[4]型別的,pa+1,pa則會加4,雖然陣列的首地址和首元素首地址的值相同,但是兩者操作不同,所以型別不匹配不能直接賦值,但是可以這樣:pa = &a,pa相當與二維陣列的行指標,現在它指向a[4]的地址。

3.指標陣列和陣列指標的使用

3.1指標陣列在引數傳遞時的使用

指標陣列常用在主函式傳參,在寫主函式時,引數有兩個,一個確定引數個數,一個這是指標陣列用來接收每個引數(字串)的地址

int main(int argc, char *argv[])

此時可以想象記憶體映像圖,主函式的棧區有一個叫argv的陣列,這個陣列的元素是你輸入的引數的地址,指向著只讀資料區。

如果是向子函式傳參,這和傳遞一個普通陣列的思想一樣,不能傳遞整個陣列過去,如果陣列很大,這樣記憶體利用率很低,所以應該傳遞陣列的首地址,用一個指標接收這個地址。因此,指標陣列對應著二級指標

void fun(char **pp);//子函式中的形參
fun(char *p[]);//主函式中的實參

3.2指標陣列的排序

指標陣列的排序非常有趣,因為這個陣列中存放的是指標,通過比較指標指向的空間的大小,排序這些空間的地址。函式實現如下:

void sort(char **pa, int n)//氣泡排序
{
    int i, j;
    char *tmp = NULL;

    for(i = 0; i < n-1; i++){
        for(j = 0; j < n-1-i; j++){
            if((strcmp(*pa+j), *(pa+j+1)) > 0){
                tmp = *(pa + j);
                *(pa + j) = *(pa + j + 1);
                *(pa + j + 1) = tmp;
            }
        }
    }
}

在函式中定義指標陣列,並且列印結果如下:

char *pa[4] = {"abc", "xyz", "opq", "xyz"};

[[email protected] test]# ./test 
abc
ijk
opq
xyz

陣列指標傳參時的使用

陣列指標既然是一個指標,那麼就是用來接收地址,在傳參時就接收陣列的地址,所以陣列指標對應的是二維陣列。

void fun(int (*P)[4]);//子函式中的形參,指標陣列 

a[3][4] = {0};//主函式中定義的二維陣列
fun(a);//主函式呼叫子函式的實參,是二維陣列的首元素首地址

相關推薦

指標陣列VS陣列指標次要

指標陣列與陣列指標詳解1.什麼是指標陣列和陣列指標?指標陣列:指標陣列可以說成是”指標的陣列”,首先這個變數是一個數組,其次,”指標”修飾這個陣列,意思是說這個陣列的所有元素都是指標型別,在32位系統中,指標佔四個位元組。陣列指標:陣列指標可以說成是”陣列的指標”,首先這個變

時鐘定時器 玩了這麼久微控制器這次終於 STM32的SYSTICK

SysTick定時器除了能服務於作業系統之外,還能用於其它目的:如作為一個鬧鈴,用於測量時間等。 要注意的是,當處理器在除錯期間被喊停(halt)時,則SysTick定時器亦將暫停運作。 SysTick時鐘的選擇 SysTick暫存器說明在《Cortex-M3權威指南》(chap8.SysTick

微信小程式 VS 原生APP一局你站哪邊?

微信小程式 VS 原生APP,這一局你站哪邊? 就在眾樂樂的十一假期,一項名叫“全球首屆「未來小程式」黑客馬拉松”的神奇比賽緊鑼密鼓地展開,據說8支隊伍大拼腦洞又拼體力,在短短24小時內推出到家服務、社交應用、倒計時等各類應用,準確說,是各類微信小程式。 相比之

從大山走出的阿里首席通訊科學家次要重返課堂

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

要想陣列用的 6怎能不 java.util.Arrays

java.util.Arrays 類就是為陣列而生的專用工具類,基本上常見的對陣列的操作,Arrays 類都考慮到了,這讓我由衷地覺得,是時候給該類的作者 Josh Bloch、Neal Gafter、John Rose 點個讚了。 (我是怎麼知道作者名的?看原始碼就可以,小夥伴們,裝逼吧) Arrays 都

python作圖都是小把戲python實現倒放gif動圖才牛逼

  現在的各種動圖層出不窮,深受大家喜歡,今天給大家介紹一個可以把gif動圖倒放的python程式,先來看下效果。 學習Python中有不明白推薦加入交流群                 號:5

超越明日之後評分最高末日生存遊戲:地球末日生存才是末日

除了最近比較火的明日之後還是什麼比較好玩的末日生存手遊?玩過明日之後不得不安利一款TAPTAP上評分高達9.0的末日生存手遊:地球末日生存。網友:這才是末日! 地球末日生存(Last Day on Earth )是一款海外發行的免費的 MMORPG 殭屍射擊生存和策略遊戲。算是比較早期的一款末日

Java架構體系學習路線圖六點尤為重要

Web應用,最常見的研發語言是Java和PHP。後端服務,最常見的研發語言是Java和C/C++

linux中Oops資訊的除錯及棧回溯—Linux人都知道是好東西

============================================================================= 看後感想:這點比 ldd3上講的都仔細 2012年11月29日11:24:17:有BUG_ON就不用反彙編了。

C語言重點——指標篇(一文讓你完全指標)| 從記憶體理解指標 | 指標完全解析

> 有乾貨、更有故事,微信搜尋【**程式設計指北**】關注這個不一樣的程式設計師,等你來撩~ **注:這篇文章好好看完一定會讓你掌握好指標的本質** C語言最核心的知識就是指標,所以,這一篇的文章主題是「指標與記憶體模型」 說到指標,就不可能脫離開記憶體,學會指標的人分為兩種,一種是不瞭解記憶體

監控系統選型篇不可不讀

![](https://oscimg.oschina.net/oscnet/cebf05ee-ac24-4e18-b8ea-6397c460b7b7.jpg) 之前,我寫過幾篇有關「線上問題排查」的文章,文中附帶了一些監控圖,有些讀者對此很感興趣,問我監控系統選型上有沒有好的建議? 目前我所經歷的幾家公司

精通MySQL之索引篇篇注重練習

老劉是即將找工作的研究生,自學大資料開發,一路走來,感慨頗深,網上大資料的資料良莠不齊,於是想寫一份詳細的大資料開發指南。這份指南把大資料的【基礎知識】【框架分析】【原始碼理解】都用自己的話描述出來,讓夥伴自學從此不求人。大資料開發指南地址如下: github:https://github.com/Bi

別再關心AI怎麽好了我們要AI怎麽用

ant 坐標 rgb weight 部分 基本 安利 世界 ali 在今天的中國,想要了解AI,最怕的是什麽?答案也許只有一個,那就是開會。如今的人工智能大會基本是有套路的:首先要提問AI到底會不會取代人類;然後各個專家發言,暢想一下AI的美好未來;最後炫一張復雜的PPT或

【免費直播】3.12-3.158場公開課大“惠”聚——知識幹貨、專屬優惠一晚

人工智能 網絡技術 軟考 數據庫 課程安排一覽: 3月12號晚20:00-21:30如何一次通過軟考【小任老師】(系統集成項目管理師/高級信息系統項目管理師) 3月13號晚20:00-21:00如何成為高端IT運維人才【韓立剛老師】 3月13號晚20:00-21:30【楊哥】權威解析紅帽

程式設計師晒出實習生的一段程式碼表示看不網友:out了新寫法

技術總是在不停的更新迭代,這就是程式設計師為什麼要保持學習能力的原因了,與其他行業相比,程式設計師不學習新知識,只是保持現有的技術,幾年後再回頭看看,就可能與同行落下去一大截,當然,對於技術的更新也是徐徐漸進的,只要有一定的技術嗅覺,多留意一些技術官方網站的最新發布, 多留意一下發展的動向就不會那麼

網上看中一篇好文章無法複製?不要著急一個程式碼教你

不知道大家有沒有和我一樣的苦惱,在網上看到自己很感興趣,很喜歡的文章,卻不能複製!真的很討厭! 後來我學會了一個小技巧——一個程式碼,即可複製你看中的任何內容! 你想學習嗎?想的話,就接著往下看喲! 應用舉例: 如圖,這篇文章想要下載,就需要註冊登入才可以。 其

Spring Boot 返回 JSON 資料一分鐘

在 WEB 專案中返回 JSON 資料是常見的互動形式,在 Spring Boot 中這一切都變得十分簡單。So easy!!! 你所需具備的基礎 什麼是 Spring Boot? Spring Boot 核心配置檔案詳解 Spring Boot 開啟的 2 種方式 Spring Boot 自動配置原理、實

Spring Boot 返回 XML 資料一分鐘

Spring Boot 返回 XML 資料,前提必須已經搭建了 Spring Boot 專案,所以這一塊程式碼就不貼了,可以點選檢視之前分享的 Spring Boot 返回 JSON 資料,一分鐘搞定!。 你所需具備的基礎 什麼是 Spring Boot? Spring Boot 核心配置檔案詳

Spring Boot 返回 XML 數據一分鐘

傳遞 med web tid cati write tac java技術 工具 Spring Boot 返回 XML 數據,前提必須已經搭建了 Spring Boot 項目,所以這一塊代碼就不貼了,可以點擊查看之前分享的 Spring Boot 返回 JSON 數據,一分鐘