2014-12-04 68 views
0

在file1.h將函數作爲具有不同長度參數的指針傳遞給另一個函數?

// find the root of a function of one variable 
double rootfind(double (*fp)(double), double start, double end); 

在file2.h

// a function of multiple variables 
double myfun(double a, double b); 

double test(); 

在file2.c中

double myfun(double a, double b) 
{ 
    return (a+3.0)*(a-1.0)*(a-1.0)*b; 
} 

double test() 
{ 
    double b, start, end; 

    start = -4.0; 
    end = 4.0/3.0; 

    b = 2.0; 

    // How do I use the rootfinding function to find the root of myfun 
    // where b is set as a constant in this function? 
    // How do i find the root of myfun(x,2.0)? 
} 

我想保持rootfind功能一般在沒有額外的參數傳遞。我也不想使用gcc擴展來嵌套函數。

回答

2

您在詢問關於標準C90/C99不支持的稱爲關閉的內容。如果你打算這樣做,你必須:

  • 使用你提到的GCC擴展。
  • 使用C++的std::bind函數。
  • 使用一個庫(例如GCC附帶的libffi)來分配可寫入和運行的內存(您可以在運行時爲新的一個參數函數創建機器代碼)。
  • 編寫一個頂級靜態函數,以您希望的方式工作。
  • 使用在運行時從C代碼編譯的動態加載模塊。

多數那些可能顯得撲朔迷離/嚇人,那是因爲有真做,這是你想要的C.什麼,主要是因爲它是非常危險的(重大安全漏洞),以在運行時重寫功能沒有什麼好辦法C.


頂級靜態函數的例子(這個地方剛剛超過您main功能):

static myfun_single_b = 2.0; 

static double myfun_single(double a) { 
    return myfun(a, myfun_single_b); 
} 

我們之所以使用static keywor d這裏的變量名稱和函數名稱不會與其他源文件中的其他函數/變量名稱衝突。

+0

謝謝。我現在知道它叫什麼,所以我可以搜索它。你能解釋一下你對頂級靜態函數的含義嗎? – user1801359 2014-12-04 21:51:59

1

您可以編寫一個包裝函數:

static double wrapper(double a) { 
    return myfun(a, 3.0); 
} 

和使用上rootfind()。你可以把它較一般通過使其承擔myfun()的第二個參數從文件範圍變量中的值(即支持的第二個參數myfun()的不同值):

static double b; 

static double wrapper(double a) { 
    return myfun(a, b); 
} 

你甚至可以概括它更通過使包裝通過文件範圍函數指針調用兩個ARG功能:

static double b; 
static double (*wrapped)(double, double); 

static double wrapper(double a) { 
    return (*wrapped)(a, b); 
} 

這是你可以執行間接的限制,但它提供的緯度相當數量。

1

如果你可以修改rootfind,正確的方式來解決這將是一個上下文參數添加到函數指針,就像

double rootfind(double (*fp)(double, void *), double start, double end, void *context); 

然後,您可以創建一個上下文結構包含您的第二個參數b並傳遞通過上下文參數指向它的指針。

這樣,避免了全局狀態和運行時代碼生成。 rootfind函數也是通用的。

相關問題