1. 程式人生 > >C/C++ 複雜的宣告

C/C++ 複雜的宣告

入門階段,看見類似void * (*(*fp1)(int))[10];的複雜宣告,暈乎。直接略過,這種複雜的東東,不應該是入門者需要去學習的知識。

進階階段,這種知識就必需得搞得清清楚楚了,不然還等到高階階段才學習這個麼?

現在,就來帶大家瞭解一下,這類複雜的宣告怎麼解?

在解之前,先看一個入門的知識點,指標函式作為引數傳遞。

  1. int func_call(string text) {  
  2.     cout <<text<<endl;  
  3.     return 5;  
  4. }  
  5. void func_pointer(int (*fp)(string)) {  
  6.     cout <<fp("func_pointer") <<endl;  
  7. }  
  8. void main() {  
  9.     int (*fp)(string);//宣告函式指標,此函式接受一個字串引數並返回一個整型  
  10.     fp = func_call;  
  11.     func_pointer(fp);//將函式指標作為引數傳遞  
  12. }  

怎麼宣告函式指標相信大家都很清楚,現在就來解複雜宣告

1. void * (*(*fp1)(int))[10];

2. float (*(*fp2)(int,int,float))(int);

解1:void * (*(*fp1)(int))[10];

(1)包含fp1的最內層小括號是(*fp1):fp1是指標
(2)往(*fp1)右邊看是(int),右邊是小括號即是函式:指向帶有一個int型引數的函式
(3)再往(*fp1)左邊看是*,當右邊是函式,左邊即是函式的返回值:且函式返回一個指標
(4)往(*(*fp1)(int))右邊看是[10],右邊中括號表示陣列:指標指向一個大小為10的陣列
(5)再往(*(*fp1)(int))左邊看是void *,即是陣列的型別:陣列型別為void *

好了,把整段話拼出來吧:

fp1是指標,指向帶有一個int型引數的函式,且函式返回一個指標,指標指向一個大小為10的陣列,陣列型別為void *

解2:float (*(*fp2)(int,int,float))(int);

(1)包含fp2的最內層小括號是(*fp2):fp2是指標
(2)往(*fp2)右邊看是(int,int,float),右邊是小括號即是函式:指向帶有3個引數的函式
(3)再往(*fp2)左邊看是*,當右邊是函式,左邊即是函式的返回值:且函式返回一個指標
(4)往(*(*fp2)(int,int,float))右邊看是(int),右邊小括號表示函式:指標指向帶1個整型引數的函式
(5)再往(*(*fp2)(int,int,float))左邊看是float,即是函式的返回值:函式返回float

把整段話拼出來:


fp2是指標,指向帶有3個引數的函式,且函式返回一個指標,指標指向帶1個整型引數的函式,函式返回float

任何複雜的宣告都按此方法解,中間的變數名開始,右--左--右--左。編譯器也是按此步驟讀宣告的。

下面程式碼示例:

  1. typedefvoid* (*AP)[10];  
  2. AP func_fp1(int i) {  
  3.     cout<< "func_fp1:" << i << endl;  
  4.     AP a = nullptr;  
  5.     return a;  
  6. }  
  7. void main() {  
  8.     void * (*(*fp1)(int))[10];  
  9.     fp1 = func_fp1;  
  10.     (*fp1)(5);  
  11. }  

宣告也使用型別定義會使宣告看起來更簡單一點
  1. void main() {  
  2.     AP (*fp1)(int);  
  3.     fp1 = func_fp1;  
  4.     (*fp1)(5);  
  5. }  


  1. float func_f(int i) {  
  2.     cout<< "func_f:" << i << endl;  
  3.     return 1.0f;  
  4. }  
  5. typedeffloat (*FP)(int);  
  6. FP func_fp2(int i,int j,float f) {  
  7.     cout<< "func_fp2 i:" << i << ", j:" << j << ", f:" << f << endl;  
  8.     //float (*fp)(int);
  9.     FP fp;  
  10.     fp = func_f;  
  11.     return fp;  
  12. }  
  13. void main() {  
  14.     float (*(*fp2)(int,int,float))(int);  
  15.     fp2 = func_fp2;  
  16.     (*(*fp2)(1,2,3))(4);  
  17. }  

一樣可以用型別定義
  1. void main() {  
  2.     FP (*fp3)(int,int,float);  
  3.     fp3 = func_fp2;  
  4.     (*(*fp3)(5,6,7))(8);  
  5. }  


從中間開始,即從變數名fp1開始解,(*fp1)

相關推薦

C語言複雜宣告解釋

這裡我自己來梳理一下: 種類把(*F)(int,int)看成fun,於是宣告A為:int (*fun)(int),哈哈!這個不是很難啊! 在cdecl裡解釋為: declare fun as pointer to function (int) returning int fun是一個函式指標,而這個函式指標是

c語言複雜宣告的解析

摘錄的別人的: C語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是一個既著名又常用的方法。不過,右左法則其實並不是C標準裡面的內容,它是從C標準的宣告規定中歸納出來的方法。C標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如

c複雜宣告

  這幾天在看c程式設計語言第二版,在看到第五章複雜宣告時,有些疑惑,在結合別人的理解上,我按自己的理解方式理解複雜宣告,並附上實際的測試例子。   1.首先選取的是      char  ( * ( * x ( ) ) [ ] ) ( ) ,由外至內分解,分解如下:  a

C語言複雜宣告解析

C語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是一個既著名又常用的方法。不過,右左法則其實並不是C標準裡面的內容,它是從C標準的宣告規定中歸納出來的方法。C標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識一個宣告的,

理解C語言中指標的宣告以及複雜宣告的語法

昨天剛把《C程式設計語言》中“指標與陣列”章節讀完,終於把心中的疑惑徹底解開了。現在記錄下我對指標宣告的理解,順便說下如何在C語言中建立複雜宣告以及讀懂複雜宣告。 本文章中的內容參考自《C程式設計語言》 指標是什麼就不詳細說明了,用一句話來總結就是:“指標是

C/C++ 複雜宣告

入門階段,看見類似void * (*(*fp1)(int))[10];的複雜宣告,暈乎。直接略過,這種複雜的東東,不應該是入門者需要去學習的知識。 進階階段,這種知識就必需得搞得清清楚楚了,不然還等到高階階段才學習這個麼? 現在,就來帶大家瞭解一下,這類複雜的宣告怎

如何理解CC++的複雜型別宣告

float ( * ( *b()) [] )();// b is a function that returns a // pointer to an array of pointers // to functions returning floats. void * ( *c) ( char, int (*

C語言基礎(二)之複雜宣告方式

我們本篇部落格的內容主要是解決如何閱讀C語言的宣告。比如: char a; char * b; const char * c; char * const d; char e[100]; char *f[100]; char (*g)[100]; struct

理解複雜C/C++宣告 const, typedef , 函式指標

讓我們從一個非常簡單的例子開始,如下: int n; 這個應該被理解為“declare n as an int”(n是一個int型的變數)。 接下去來看一下指標變數,如下: int *p; 這 個應該被理解為“declare p as an int *”(p是一個int *型的變數),或者說p是一個

C++ 複雜宣告理解

理解複雜宣告可用的“右左法則”:從變數名看起,先往右,再往左,碰到一個圓括號就調轉閱讀的方向;括號內分析完就跳出括號,還是按先右後左的順序,如此迴圈,直到整個宣告分析完。舉例:int (*func)(int *p);首先找到變數名func,外面有一對圓括號,而且左邊是一個*號

C語言的宣告與定義

keil的專案中,遇到呼叫其他C檔案函式和變數的情況: 對於函式,在a.c下面進行編寫,之後在a.h下面進行宣告,其他檔案包含a.h即可呼叫。 對於變數,在a.c下面進行定義,在a.h下面也要進行一下宣告,其他檔案使用此變數時,包含a.h即可使用。 關於變數的定義與宣告 變數定義即為

C語言高階篇 - 1.C語言複雜表示式和指標高階應用

1.指標陣列與陣列指標 1.1、字面意思來理解指標陣列與陣列指標 (1)指標陣列的實質是一個數組,這個陣列中儲存的內容全部是指標變數。 (2)陣列指標的實質是一個指標,這個指標指向的是一個數組。   1.2、分析指標陣列與陣列指標的表示式 (1)int *

C++---前置類宣告

一、類巢狀的疑問 C++標頭檔案重複包含實在是一個令人頭痛的問題,假設我們有兩個類A和B,分別定義在各自的標頭檔案A.h和B.h中,但是在A中要用到B,B中也要用到A,但是這樣的寫法當然是錯誤的:  class B;=========================這個就是前置類。

C++中如果宣告一個物件指標時,會不會呼叫建構函式?

C++中如果宣告一個物件指標時沒有分配記憶體,那麼不會呼叫建構函式 一個指標在記憶體中也是有記憶體空間的。 在現在大多數機器上指標都是32位的,也就是4個位元組。 如果你宣告指標。例如,假設A是一個類 A *pa; 這記憶體中會分配4個位元組的空間儲存一個地址。只不過地址是不可以用

為什麼我們要使用c++的前置宣告

一、正文 定義一個類 class A,這個類裡面使用了類B的物件b,然後定義了一個類B,裡面也包含了一個類A的物件a,就成了這樣: //a.h #include "b.h" class A { .... private: B b; }; //b.

C++變數的宣告、初始化、定義

宣告和定義的關係: 宣告規定了變數的型別和名字,定義申請儲存空間。 想宣告而非定義一個變數,新增extern關鍵字,extern宣告變數並初始化時即變成定義。 定義一次,宣告可多次。可參考部落格extern關鍵字 #include<iostre

C/C++陣列指標、指標陣列、函式指標變數的宣告和用法

#include <iostream> using namespace std; void fun1(int(*pArr)[3], int row) { int i,j; for (i = 0; i < row; i++) { for (j = 0; j <

C語言】宣告與定義

前言 引用性宣告 不分配儲存空間,如extern int x; 只是告訴編譯器x是整形,已經在其它地方定義了。 定義 是在記憶體中確定變數的位置、大小。 初始化 是定義變數時候賦給變數的值(從無到有)

C++ 中變數宣告中 const 用法

一直以來對 C++ 中的 const 說明符理解不夠清晰,尤其是在變數宣告時處於何種位置起到何種作用,分辨不清。 現在花費一些時間專門理清其中的關係,明白其中的道理之後,就再也不會混淆了。文中內容主要參考了這篇譯文。 1. 幾個概念 以 static unsig

C+++中的宣告和定義

《C++Primer》第四版 2.3.5節中這麼說到: ①變數定義:用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有一個定義。 ②變數宣告:用於向程式表明變數的型別和名字。 ③定義也是宣告:當定義變數時我們聲明瞭它的型別和名字。 ④extern