2016-11-14 21 views
0

我是丹麥的一位本地程序員,試圖幫助一位朋友與他的C exsam。如何閱讀此C代碼? exsam準備

他需要學習閱讀某些代碼設計,比如這個。不過,我不能在這裏的結果來自...有人請幫助我理解它的頭部或尾部,所以我可以幫助他:

#include <stdio.h> 
#include <stdlib.h> 
int func1(int); 
void func2(int(*fp)(int), int); 
void main(){ 
    int (*fp)(int); 
    fp = func1; 
    (*fp)(1); 
    func2(fp,(*fp)(2)); 
} 
int func1(int arg){ 
    printf("Func1 %d\n", arg); 
    return arg; 
} 
void func2(int(*fp)(int), int arg){ 
    printf("Func2 %d\n",arg+fp(arg)); 
} 

我知道雁是: FUNC1 1 FUNC1 2 Func1 2 Func2 4

但是,爲什麼這樣!高於我的薪酬水平。

據我所知,在void main()我們diffine int ...但是這看起來很奇怪。

我們然後調用fp = func1;,有效地運行printf("Func1 %d\n", arg); 文本應「FUNC 1(插入ARG這裏)。我不明白爲什麼這給了一些1.

它,然後做一些事情在這裏(*fp)(1); meaby樣的一些指針的東西???

我不明白爲什麼它運行在連續3次printf("Func1 %d\n", arg);並再次,哪裏的數字從何而來?

和代碼的其餘部分是沒有更好的

+0

再看一遍:'printf(「Func1%d \ n」,arg)'。它打印什麼? –

+1

int(* fp)(int)'是一個指向一個函數的指針,該函數接受一個int並返回一個int,因此函數簽名將爲int some_name(int)。在第二行「fp = func1」中,我們將'func1'的地址賦給'fp'(注意func1的簽名是'int func1(int)',與上面的聲明匹配。用參數1調用func1的效果。我建議你們都刷新函數指針和它們的用法:)。 – thurizas

回答

0

int (*fp)(int);創建一個新的指針的函數接受命名fp

fp = func1;集的整數fpfunc1

(*fp)(1);呼叫*fp,這是func1,與1 =>打印Func1 1

func2(fp,(*fp)(2));呼叫*fp ,這是func1,與2。然後它調用func2與該結果,這是2fp這是目前2 =>打印Func1 2 Func1 2 Func2 4

+0

int(* fp)(int);'是一個函數指針,它接受一個整數並返回一個整數,而不是一個int指針。 –

+0

@MadPhysicist謝謝!我的指針知識並不是非常尖銳。編輯以顯示它是指向函數的指針 – camiblanch

+0

int(* fp)(int)是一個指向一個函數的指針,該函數接受一個int並返回一個int,因此函數簽名將爲int some_name(int)。在第二行「fp = func1」中,我們將'func1'的地址賦給'fp'(注意func1的簽名是'int func1(int)',與上面的聲明匹配。用參數1調用func1的效果。我建議你們都刷新函數指針和它們的用法:)。 – thurizas

0

此代碼的最混亂方面是令人費解的使用函數指針。

void func2(int(*fp)(int), int);函數func2的聲明接受名爲fp的函數指針和一個整數作爲參數。 fp是一個函數指針,它接受一個參數int並返回一個int。由於此行是一個聲明,因此可能會被重新編號爲void func2(int(*)(int), int);。函數指針的名字在這裏不是必須的(但是它將在後面的定義中)。

main聲明指向函數int (*fp)(int);的指針並將其設置爲指向func1。這是可能的,因爲func1的聲明與指針期望的類型匹配。

然後我們調用fp指向的函數:(*fp)(1);。請注意,第一組括號使用指針名稱對星號進行分組,而不是函數的返回值。換句話說,它表示取消引用指針並在該位置調用該函數,而不是調用該函數並取消引用返回值。

在C的大多數版本中,指針符號可以省略,函數指針可以像調用函數本身一樣調用。這條線可以改寫爲fp(1);。實際上,這是func2中用於呼叫fp的符號。

接下來我們呼籲func2fp (== func1)fp(2)的結果。

總體而言,預期的打印輸出(帶有註釋的解釋):

Func1 1 // (*fp)(1); in main() 
Func1 2 // Evaluating the argument (*fp)(2) to func2() in main() 
Func1 2 // Evaluating the argument fp(arg) to printf() in func2() 
Func2 4 // Printing the result of arg==2 + fp(arg)==2 in func2() 
0

以它逐行一些格式更改和一對夫婦更正:

#include <stdio.h> 
#include <stdlib.h> 

/** 
* Declarations for func1 and func2 
*/ 
int func1(int); 
void func2(int(*fp)(int), int); 

int main(void)  // main always returns int 
{ 
    int (*fp)(int);  // fp is a *pointer* to a function taking a single int parameter 
         // and returning an int value 
    fp = func1;   // assign the *address* of func1 to fp 
    (*fp)(1);   // call func1 through the pointer fp with an argument of 1 
    func2(fp,(*fp)(2)); // call func1 through fp again with a value of 2; 
         // pass that result, along with the value of fp 
         // (which is the address of func1) to func2. 
} 

/** 
* Print the input argument, return the value of the input argument 
*/ 
int func1(int arg){ 
    printf("Func1 %d\n", arg); 
    return arg; 
} 

/** 
* Call the function pointed to by fp with the input argument, add the 
* result to the input argument, print out the final value 
*/ 
void func2(int(*fp)(int), int arg){ 
    printf("Func2 %d\n",arg+fp(arg)); 
} 

在上面的代碼,fp是一個指針函數採取int參數並返回int結果。我們將的地址的地址爲func1分配給fp,然後我們通過 通過fp指針。該代碼基本上等同於:

int main(void) 
{ 
    func1(1); 
    func2(func1, func1(2)); 
} 

函數指針是非常有用的,和一些在標準庫中顯示,如用於qsort庫函數。