高階指標話題

2021-08-04 23:15:28 字數 3450 閱讀 4017

來淺顯地**一下稍微複雜的指標.

首先要有乙個不可動搖地認識,再厲害的指標也是指標,它存的內容永遠是位址.定義了指標的型別,該指標就只能與這種型別搭配使用.

從二級指標開始說

int i;

int*p=&i;

int**pp=&p;

pp是乙個二級指標,指向指標的指標,存的內容是p的位址,型別是」指向整型的指標的指標」.

int i=1;

int*p=1;

int**pp=1;

這三條語句的作用相同,給i賦值1.

指標陣列和陣列指標

int

*p1[10];

指標陣列:它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定.它是」儲存指標的陣列」簡稱.

int (*p2)[10];
陣列指標:首先它是乙個指標,它指向乙個陣列, ,它的型別是指向整型陣列的指標,它等價於int(*)[10] p2;

必須用乙個同樣是指向整型陣列的位址來對它初始化.

另外,它指向的這個整型陣列大小與它無關.

要區分指標陣列和陣列指標,只要知道優先順序高於*,對於int *p[10],就是先定義了乙個陣列p[10],再定義這個陣列元素的型別是整型指標int *.至於 p2 就更好理解了,在這裡「()」的優先順序比「」高,「*」號和 p2 構成乙個指標的定義,指標變數名為 p2,int 修飾的是陣列的內容,即陣列的每個元素。陣列在這裡並沒有名字,是個匿名陣列。那現在我們清楚 p2 是乙個指標,它指向乙個包含 10 個 int 型別資料的陣列,即陣列指標。

值得注意的一點是對於陣列指標int (*p)[10],雖然我們想讓它指向乙個有是個整型元素的陣列,但是指向其他個數元素的陣列也可以,所以[10]表示當*(p+1),指標會跳過10*sizeof(type)的位元組數,即跳過10個元素,即使該陣列沒有這麼大空間.

陣列引數與指標引數

一維陣列引數

c 語言中,當一維陣列作為函式引數的時候,編譯器總是把它解析成乙個指向其首元素首位址的指標。我們並不能把乙個陣列傳遞給函式,因此也無法在函式能求取陣列大小.

void fun(char *p);

void fun(char a[10]);

void fun(char a[ ]);

這樣定義形參都是可以的.

一級指標引數

指標的傳參與普通變數的傳參一樣,都無法把它本身傳給函式,而是對他們的值做了乙份拷貝傳遞給函式,這樣無論在函式內部怎麼修改這個值,都不會影響函式外部該變數的值.但是對於指標我們傳遞的是乙個位址,這個位址是唯一的,指向的內容如果改變,函式外部該變數的值也改變.

也就是說對於void fun(char *p);

p無論怎樣都不受影響,而*p改變會影響函式外部的值.

二維陣列引數和二維指標引數

陣列引數

等效的指標引數

char a[3][4]

char (*p)[10]

char *a[5]

char **p

這裡需要注意的是:c 語言中,當一維陣列作為函式引數的時候,編譯器總是把它解析成乙個指向其首元素首位址的指標。這條規則並不是遞迴的,也就是說只有一維陣列才是如此,當陣列超過一維時,將第一維改寫為指向陣列首元素首位址的指標之後,後面的維再也不可改寫語言中,當一維陣列作為函式引數的時候,編譯器總是把它解析成乙個指向其首元素首位址的指標。這條規則並不是遞迴的,也就是說只有一維陣列才是如此,當陣列超過一維時,將第一維改寫為指向陣列首元素首位址的指標之後,後面的維再也不可改寫。比如:a[3][4][5]作為引數時可以被改寫為(*p)[4][5]。

函式指標

指向函式的指標

儲存的內容是函式的位址,型別是指向函式的指標.

我們這樣來定義它

char* (*fun1)(char* p1,char* p2);
下面來看乙個例子

void function()

int main()

void (*p)();

這行**定義了乙個指標變數 p,p 指向乙個函式,這個函式的引數和返回值都是 void。

&p 是求指標變數 p 本身的位址,這是乙個 32 位的二進位制常數(32 位系統)。

(int*)&p 表示將位址強制轉換成指向 int 型別資料的指標。

(int)function 表示將函式的入口位址強制轉換成 int 型別的資料。

分析到這裡,相信你已經明白*(int*)&p=(int)function;表示將函式的入口位址賦值給指標變數 p。

那麼(*p)();就是表示對函式的呼叫。

我們使用指標的時候,需要通過鑰匙(「*」)來取其指向的記憶體裡面的值,函式指標使用也如此。通過用(*p)取出存在這個位址上的函式,然後呼叫它.

給函式指標賦值時,可以用&function或直接用函式名function。這是因為函式名被編譯之後其實就是乙個位址,所以這裡兩種用法沒有本質的差別。

另外有一點值得注意的是函式本身是沒有型別的,函式的返回值才有型別。

函式指標陣列

本質上是陣列,陣列中的元素是指向函式的指標

char* (*pf[3])(char* p);
這是定義乙個函式指標陣列。它是乙個陣列,陣列名為 pf,陣列內儲存了 3 個指向函式的指標。這些指標指向一些返回值型別為指向字元的指標、引數為乙個指向字元的指標的函式。

函式指標陣列怎麼使用呢?

#include 

#include

char* fun1(char* p)

char* fun2(char* p)

char* fun3(char* p)

intmain()

函式指標陣列的指標

char* (*(*pf)[3])(char* p);
注意,這裡的 pf 和上一節的 pf 就完全是兩碼事了。上一節的 pf 並非指標,而是乙個陣列名;這裡的 pf 確實是實實在在的指標。這個指標指向乙個包含了 3 個元素的陣列;這個數字裡面存的是指向函式的指標;這些指標指向一些返回值型別為指向字元的指標、引數為乙個指向字元的指標的函式。這比上一節的函式指標陣列更拗口。其實你不用管這麼多,明白這是乙個指標就 ok 了。其用法與前面講的陣列指標沒有差別。

下面列乙個簡單的例子:

#include 

#include

char* fun1(char* p)

char* fun2(char* p)

char* fun3(char* p)

intmain()

《C與指標》 高階指標話題

指標真是讓人又愛又恨。首先還是先來看一下c語言中的高階指標宣告。不要被表面迷惑最重要。c和指標 高階指標話題 int i 定義乙個整型變數 int pi 指向整型變數的指標 int ppi 指向乙個指標,而那個指標又指向乙個整型變數 高階宣告 int fun 普通函式宣告,返回乙個整數 int fu...

C 高階指標話題之高階宣告的演進

在使用更高階的指標型別之前,我們必須觀察它們是如何宣告的。下面通過觀察一系列越來越複雜的宣告來 這個話題 int f 乙個整型變數 int f 乙個指向整型的指標這兩個例子十分簡單,我們來看下第2個宣告是如何工作的,這對後面理解更複雜的宣告非常重要。它把表示式 f 宣告為乙個整數。根據這個事實,你肯...

八 高階話題

本章描述bufferevent的一些對通常使用不必要的高階特徵。如果只想學習如何使用bufferevent,可以跳過這一章,直接閱讀下一章。有時候網路程式需要與自身通訊。比如說,通過某些協議對使用者連線進行隧道操作的程式,有時候也需要通過同樣的協議對自身的連線進行隧道操作。當然,可以通過開啟乙個到自...