C 語言中指標陣列和陣列指標 函式指標 指向函式的指標等等該怎麼理解?

時間 2021-06-02 08:00:17

1樓:ga6840

direct_declarator: IDENTIFIER | '(' declarator ')'direct_declarator '[' ']' | direct_declarator '[' assignment_expr ']' | direct_declarator '(' ')'

declarator: direct_declarator | pointer direct_declarator ;

然後根據這個語法,用人腦解析出一顆語法樹:

舉個例子:int *(*(*foo)[2](int (*)(float), int)[3])(int, float);

declaration

├──int

└──declarator <== 迷宮的出口在這裡

└──pointerfunctiondeclaratorpointerarray of size 3functionarray of size 2declaratorpointerfoo <== 迷宮的入口在這裡2param_listparam_declarationintabstract_declaratorfunction of size 0abstract_declaratorpointerparam_listparam_declarationfloatparam_declarationint3param_listparam_declarationintparam_declarationfloat

(注意,這個例子語義不正確,但是語法沒問題)

這個樹你從 identifier(也就是這裡的 foo) 從下往上讀,就是:

declarefooas pointer to array 2 of function (pointer to function (float) returning int, int) returning array 3 of pointer to function (int, float) returning pointer to int

好了,這是語法。語義部分注意 C 語言中陣列和函式之間不能直接宣告,所以以下宣告語義是錯誤的:

array of functions

比如 typedef int (*bar)[2]();

function returning array

比如 typedef int (*bar)()[2];

只能通過指標來「橋接」:

array of function pointers

比如 typedef int (*bar[2])();

function returning array pointer

比如 typedef int (*(*bar)())[2];

剩下的,如果還有什麼難點的話,就是 reference (&) 和 dereference (*) 裡面的型別推斷了。有了上面那顆樹以後,這兩個操作的型別推斷就變得十分簡單,只用從 identifier (上面例子的 foo)開始,結合 reference 的時候往下走乙個節點,結合 dereference 的時候往上走乙個節點。有幾點需要注意的:

在對 identifier 直接取位址的時候,想象 identifier 下面還有乙個節點,即 identifier 的 rvalue,代表他的位址)

最內層的陣列把他當作乙個指標,比如 int a[2][3] 的 a 就是 int (*)[3] 型別,dereference 一下的話(*a)型別就變成了 int * 了。

好了,這就基本覆蓋了陣列函式等指標的知識點。為啥這樣理解就沒有知識死角了呢?因為這就是 C 編譯器的工作原理。

2樓:王耀武

翻譯害死人。

指標陣列的英文是 array of points,就是定了乙個陣列,每個成員是指標,這麼理解,有一堆指標組成了陣列。根據運算法則我們是這麼寫的,乙個指標 TypepType; 兩個指標 type (*pType)[2],多個指標,就是type (*type)[N];

陣列指標。point to array。 我們是定義乙個陣列,type pType[N], 乙個指標指向它,type * pType[N].

函式指標, point to function , 首先我們表示乙個函式,retType func( type1, type2);用指標指向他, retType * func(type1, typ2);

如果被這些概念弄迷糊的時候,不妨看看原文的書刊,幫你答疑解惑,也是乙個很好的方法。

3樓:張青

用優先順序的方式去解讀乙個指標:

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 結合,說明該指標所指向的元素是整型資料.所以P是乙個指向另乙個指向整形資料的指標的指標

int p(int);/*P 處起,先與()結合,說明P 是乙個函式,然後進入 ()裡分析,說明該函式有乙個整型變數的引數然後再與外面的int 結合,說明函式的返回值是乙個整型資料,所以P是乙個返回值時乙個整型資料的函式

int (*p)(int);/*從P 處開始,先與指標結合,說明P 是乙個指標,然後與 ()結合,說明指標指向的是乙個函式,然後再與()裡的int 結合,說明函式有乙個int 型的引數,再與最外層的int 結合,說明函式的返回型別是整型,所以P 是乙個指向有乙個整型引數且返回型別為整型的函式的指標

4樓:「已登出」

現有指標A* p = &a,你可以把p當作乙個整形變數(誤),值為a 的記憶體位址,假設為0xABCD。*p 就是在位址0xABCD找到變數 a 的過程。

指標陣列,就是一連串指標構成的陣列。

陣列指標就是指向陣列的指標。

函式指標就是 0xABCD 處是乙個函式, 這個函式可以呼叫。

請大家指正

5樓:[已重置]

我在最近幾年後才發現

學C語言是件很危險的事情

但再怎麼危險

學C語言至少是有個好處的

Microsoft Visual Studio聽說付費版有列出彙編碼的功能

那gcc我肯定是有的

指令印象中是 -S吧

其實這類可以用引數查詢來找出來

應該是Visual C++也可以用命令列找出要下的引數然後就看組合語言指令就好

可能要注意下是不是Intel x86或x64Microsoft是MASM

而gcc...

還真的不知道它的組合語言是有沒有固定採用哪個就這樣祝好運

個人原計畫是打算38歲以後再學組合語言的

6樓:YC丶凱少

這些對於我來說,先是學習應用,後來又反過頭來想記憶體與物件的關係,才逐漸明白了究竟都是怎麼回事兒。

目前來說,我認為沒什麼好辦法,只有邊敲邊想。指標與基本資料型別不同,需要有深刻的對記憶體的理解。光死記硬背各種指標,我認為是沒什麼前途的。

7樓:50包郵

首先你得理解指標的概念。

【first】你在程式裡宣告的變數,以及你寫的函式都是在電腦裡真存在的,都存放在記憶體裡。然而僅僅是存在並不代表你能夠用到他,就像你知道譚浩強(→_→c語言入門估計都知道他)住在北京城,你知道了有用嗎?你想找到他你還得需要他的位址。

同理你想訪問乙個變數或者你想執行乙個函式,你也得知道他的位址,指標就是這麼個東西,通過指標你就能找到這個變數或者函式從而執行或者呼叫他。

【then】然而有什麼用呢,首先假定你已經學習了函式,也用過scanf函式,有沒有注意到scanf和printf最大的區別就是變數前多了個&?scanf("%d",&a)你應該也知道這個語句的意思是從鍵盤輸入乙個數字並存到a裡,那麼&有什麼用?

【敲黑板】首先給乙個引數傳遞的變數只能是值,如果你在這裡沒有加&,那麼你的意思是把a裡的值傳遞給函式,電腦實際執行的時候會把a的值拷貝乙份給函式,然後和a就沒有關係啦。所以&的意思是【取位址】把a的位址傳遞給scanf函式,這樣scanf函式在從鍵盤接受完數字以後能夠直接按照傳遞給他的位址直接找a上門查水表。。。。啊不是。。。

是修改a的值,這就是指標最基本的用法。

......你也可以自己玩, int *p; int a; p=&a

現在p裡存放的就是a的位址,也就是所謂的指標。

然後你*p=2 a的值就成了2,因為*的意思是對指標指向的位址進行操作

以上就是指標的意思

那麼剩下的就好說了

你可以用變數來存指標,就如同上面的 int *p 這個p就是指標變數

你會建立陣列,比如int a[12] 這叫整形陣列,float f[123]這叫浮點陣列,那麼同理也會有指標陣列,只不過這個陣列是一串指標變數

函式也是存放在記憶體裡的,他也有位址,那麼你弄乙個指標變數,把這個函式的位址存到這個變數裡,這就是指向函式的指標變數

若有寫錯的地方還請各路大神指出

C語言裡如何按需生成函式指標陣列?

暮無井見鈴 C 怎麼生成 4096 個函式?參考這裡的巨集,編譯時生成這些函式是可行的。C 的話用 index sequence 模板就行。 VeroFess 手機回答 我是這麼做的 shellcode 彙編引擎 mmap VirtulAlloc 是不太安全 我乙個寫殼的管他安不安全 gcc下 in...

在c語言中,陣列和指標是等價的嗎?

ga6840 有些地方一樣,有些地方不一樣。所以不等價。讀內容的話 a 5 和 a 5 和 5 a 甚至和 5 a 都是等價的。有人認為陣列在編譯時自帶維度資訊,通過型別檢查可以幫助檢查越界。這一點比較勉強,畢竟 b 2 3 4 中的 b 其實也可以被稱作指標,也就是 b 3 4 在 C 語言裡,指...

C語言指標 二維陣列,為啥會這樣?

沒明白你不理解的點在哪,我猜是單純糾結於為什麼要寫成0 COLS 0而不直接寫0。答案是直接寫0也可以,其實是為了統一下格式,就是乘號,結果上和直接寫0沒區別。int a 0 COLS 0 int a 1 COLS 2 int a 3 COLS 2 統一成這種格式而已。沒啥講究的,還是 指標 破數字...