C語言指標講解

來源:互聯網
上載者:User

標籤:函式宣告   優先   sizeof   開始   1.2   []   元素   結合   指標運算式   

一、指標簡介

  從根本上來看,指標(pointer)是一個值為記憶體位址的變數(或資料對象)。指標有四個方面的需要掌握,指標的類型、指標所指向的類型、指標所指向的記憶體區、指標本身所佔據的記憶體區。在講解這四個方面前我們先來瞭解間接運算子和取地址運算子。

1. 間接運算子:* 和 取地址運算子:&

  (1)間接運算子:*

    在聲明時使用,表示聲明了一個指標變數,例如 int *p 的p表示一個指向整型資料的指標變數;*後跟一個指標名或地址時,表示儲存在指標指向地址上的值,例如 a = *p 表示將p指向的地址上的資料賦值給a。

  (2)取地址運算子:&

    &後跟一個變數名時,表示該變數的地址,例如 int a = 1,&a的結果就是a的地址。

2. 指標的類型

  指標的類型只需將聲明時的指標去掉就是該指標的類型,例如int *p的p的指標類型就為Int *,即指向int類型的指標。

3. 指標所指向的類型

  指標所指向的類型決定了編譯器把記憶體區裡的內容當作什麼來看待,該類型即聲明時的類型,例如int *p的指標所指向的類型是int型。

4. 指標所指向的記憶體區

  指標的值是本身儲存的數值,這個數值是一個記憶體區地址,它的位元取決於電腦位元,32位即指標有32位整數組成,指標所指向的記憶體區就是從指標的值所代表的那個記憶體位址開始,長度為指標所指向的類型的所佔位元組數(例如int型的為sizeof(int))。

5. 指標本身所佔據的記憶體區

  指標本身是由一個不帶正負號的整數表示,但指標不是整數類型,也就是說,不能把指標之間相加減,指標的相加減和整型的相加減含義是不同的,所以指標實際上是一個新類型,不是整數類型,所佔記憶體大小為sizeof(指標的類型),例如sizeof(int *)。

二、指標的算術運算

  指標是可以進行加減的,只不過加減的含義和整型加減不一樣。例如:

int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int *p = a;p++;

  上述中,將指標p初始化指向數組的a的第一個元素的地址(數組與指標的關係後面會說),然後指標p自增一,編譯器是將指標p的值加上了sizeof(int),由於地址是用位元組做單位的,所以p所指向的地址由原來的變數a的地址增加了四個位元組,換句話說,此時p指向了數組a的第二個元素。同理,加一個數與減一個數,即n*sizeof(int)和-n*sizeof(int)。注意:*(p+1)和*p+1是不一樣的,前者代表p+sizeof(int)的記憶體位置上的值,後者代表p的記憶體位址上的值加一。

三、指標和數組

  我們平時一直在使用的數組本質上也是一個指標:數組名是數組首元素的地址。

    int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};    int b;    int c = a; ///數組a的首元素地址    int e = a + 1; ///數組a的第二個元素地址    int f = *a; ///和 f = a[0]一致

  聲明了一個數組TYPE array[n],則數組名稱array 就有了兩重含義:
  第一,它代表整個數組,它的類型是TYPE[n];
  第二,它是一個常量指標,該指標的類型是TYPE*,該指標指向的類型是TYPE,也就是數組單元的類型,該指標指向的記憶體區就是數組第0 號單元,該指標自己佔有單獨的記憶體區,注意它和數組第0 號單元佔據的記憶體區是不同的。該指標的值是不能修改的,即類似array++的運算式是錯誤的。在不同的運算式中數組名array 可以扮演不同的角色。在運算式sizeof(array)中,數組名array 代表數組本身,故這時sizeof 函數測出的是整個數組的大小。

四、指標和函數

  假設編寫一個處理數組的函數,並返回數組中的所有元素之和,那麼函數的聲明和調用就應該是:

/*函數的使用*/int marbles[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};total = sum(marbles); /*函數的聲明*/int sum(int *array);

  我們可以數組名是該數組首元素的地址,所以實參marbles是一個儲存int類型值的地址,應把它賦給一個指標形式參數,該形參是一個指向int的指標。既然可以使用指標表示數組名,也可以用數組名表示指標,上面的函式宣告可以是:int sum(int array[])。注意:只有在函數原型或函數定義頭中,才可以使用數組名形參代替指標形參。

  函數的操作過程中是可以通過return傳回值的,但是引入了指標,那麼可以直接修改指標指向的值而不用return,體現了指標的靈活。

五、指標類型轉換

  先來看一下指標的類型轉換的例子:

    float a = 1.23f;    float *b = &a;  ///將變數a的地址賦予指標b    int *c = (int *)&a;  ///將變數a的地址強制類型轉換為int *型並賦予指標c

  當我們初始化一個指標時,將一個指標運算式賦予它,一般情況下指標的類型和指標運算式的類型是一樣的,指標所指向的類型和指標運算式所指向的類型是一樣的,但是,如果出現兩者的類型不一致的情況,就得強制類型轉換了。

  如果有一個指標p,我們需要把它的類型和所指向的類型改為TYEP *TYPE, 那麼文法格式是: (TYPE *)p;這樣強制類型轉換的結果是一個新指標,該新指標的類型是TYPE *,它指向的類型是TYPE,它指向的地址就是原指標指向的地址,而原來的指標p 的一切屬性都沒有被修改。

六、執行個體
int p; //這是一個普通的整型變數int *p; //首先從P 處開始,先與*結合,所以說明P 是一個指標,然後再與int 結合,說明指標所指向的內容的類型為int 型.所以P是一個返回整型資料的指標int p[3]; //首先從P 處開始,先與[]結合,說明P 是一個數組,然後與int 結合,說明數組裡的元素是整型的,所以P 是一個由整型資料群組成的數組int *p[3]; //首先從P 處開始,先與[]結合,因為其優先順序比*高,所以P 是一個數組,然後再與*結合,說明數組裡的元素是指標類型,然後再與int 結合,說明指標所指向的內容的類型是整型的,所以P 是一個由返回整型資料的指標所組成的數組int (*p)[3]; //首先從P 處開始,先與*結合,說明P 是一個指標然後再與[]結合(與"()"這步可以忽略,只是為了改變優先順序),說明指標所指向的內容是一個數組,然後再與int 結合,說明數組裡的元素是整型的.所以P 是一個指向由整型資料群組成的數組的指標int **p; //首先從P 開始,先與*結合,說是P 是一個指標,然後再與*結合,說明指標所指向的元素是指標,然後再與int 結合,說明該指標所指向的元素是整型資料.由於二級指標以及更進階的指標極少用在複雜的類型中,所以後面更複雜的類型我們就不考慮多級指標了,最多隻考慮一級指標.int p(int); //從P 處起,先與()結合,說明P 是一個函數,然後進入()裡分析,說明該函數有一個整型變數的參數,然後再與外面的int 結合,說明函數的傳回值是一個整型資料int (*p)(int); //從P 處開始,先與指標結合,說明P 是一個指標,然後與()結合,說明指標指向的是一個函數,然後再與()裡的int 結合,說明函數有一個int 型的參數,再與最外層的int 結合,說明函數的傳回型別是整型,所以P 是一個指向有一個整型參數且傳回型別為整型的函數的指標

 

(部分轉自51131141)

 

C語言指標講解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.