這個指針C語言如何聲明?
描述是:
1.x是一個函數指針,指向的函數有一個參數和返回值。2.x指向的函數的參數和返回值都是和x同類型的函數指針。求助C語言如何聲明這樣一個指針,寫了半天沒寫出來
在 C 標準中,void 指針和函數指針不能互轉,這屬於編譯器的擴展支持[1]。所以,可用一個通用的函數指針,對不同類型函數指針轉型[2]。
#include &
//typedef void* funcptr; // 屬於編譯器的擴展支持
typedef int (*funcptr)(); // 通用的函數指針
typedef funcptr (*specific)(funcptr);
funcptr f(funcptr fp) {
return fp;
}
int main() {
specific foo = f;
assert(f == (specific)foo((funcptr)foo));
}
用 struct 包裹也是可以的。
#include &
struct FP {
struct FP (*fp)(struct FP);
};
struct FP f(struct FP fp) {
return fp;
}
int main() {
struct FP foo = { f };
assert(f == foo.fp(foo).fp);
}
[1] http://port70.net/~nsz/c/c11/n1570.html#J.5.7
[2] Question 1.22
想想這個結構在內存中是怎麼保存的struct node { node data; void* next;}
可以放棄治療了。我很好奇編譯器分析語法的時候怎麼辦,遞歸的死循環。嘗試用void*強轉吧。
真想玩這個C#還是挺舒服的。
delegate F F(F f);F f = null;f(f)(f);終於可以編譯了。然後你需要寫一個實現……你這屬於遞歸定義,直接寫是寫不出的,要實現功能可以用其他答案中用void*的做法,不過注意void*和函數指針的互轉在C標準中規定是ub
更簡化的一個類似描述是:定義一個結構體包含自身,顯然不可能
定義遞歸了
用 go 就方便多了
package main
import "fmt"
func main() {
// 定義類型,沒錯就是這麼簡單
type Foo func(Foo) Foo
// 定義並賦值變數
var id Foo
id = func(arg Foo) Foo {
return arg
}
// 調用
id(id)
// 一個狀態機的例子
var start, iter, end Foo // 三種狀態
var n int
var nums []int
start = func(prev Foo) Foo {
n = 10
return iter
}
iter = func(prev Foo) Foo {
nums = append(nums, n)
n--
if n &> 0 {
return iter
}
return end
}
end = func(prev Foo) Foo {
fmt.Printf("%#v
", nums)
return nil
}
// 執行
for state := start; state != nil; state = state(state) {
}
}
程序員都不看題目的么? C#,C++都來了啊。 這個用C的話只能用void *強轉了。
#include &
typedef void * (*FuncPtr)(void *) ;
FuncPtr foo(FuncPtr pf) {
return pf;
}
void main() {
FuncPtr pf = (FuncPtr)foo;
printf("%p, %p",foo(pf), pf(pf(pf(pf))));
}
可以用結構體來封裝
#include &
typedef struct Closure Closure;
struct Closure {
Closure (*callback)(Closure);
int acc;
};
Closure foo(Closure c)
{
Closure r = { c.callback, c.acc + 1 };
return r;
}
int main()
{
Closure acc = { foo, 0 };
acc = acc.callback(acc.callback(acc.callback(acc)));
printf("%d
", acc.acc);
return 0;
}
不完全符合題目要求,但可以實現一樣的效果,不知道是不是題主想要的。
C++:
#include&
struct Callable{
Callable* operator () (Callable* c){
std::cout &<&< "called" &<&< std::endl; return c; } };int main(void){ Callable* func = new Callable; (*func)((*func)(
(*func)(func) ) ); return 0;}template&< class T &>
哦, 是C不是C++啊, 匿了.你先確定一下這個函數的參數類型倒底是什麼?是否唯一確定?你先想好再告訴編譯器。
&<&<鹹魚書&>&>上教過"右左原理".
看懂了這種東西隨便造.
用struct迂迴一下
struct state;
typedef void(*proc)(struct state*);
struct state
{
proc input, output;
};
清晰的寫法是用typedef定義函數指針類型,然後用自定義類型定義變數。這種事中庸寫法。另一種方法是typedef定義函數類型,用自定義類型定義指針。這種語意清晰,但是總在模板中會在強制換推演時報錯。另外像生命函數一樣。可以直接定義函數指針。不過可讀性很差。為了保證優先順序要加兩層括弧。
如果可以包一層的話,就是這樣了。
按照題目理解,遞歸了。
1. x是函數指針所以x所指向的函數形式可以為:? (*x)(?),問號表示未知2. x指向的函數的參數和返回值都是和x同類型的函數指針
此時,函數的形式,替換一下參數和返回,寫成:? (*x)(?) (*x) (? (*x)(?)),還是不符合條件,需要繼續替換下去。推薦閱讀:
※不用QT,你能讓UI同時運行在Mac, IOS, Windows, Android, Linux上嗎?
※如何用C/C++動手編程一款windows平台下的屬於自己的音樂播放器軟體?
※c++中cin和scanf的區別是什麼?
※客戶端產品一般是用什麼編程語言寫的?
※應該把C語言學習到什麼程度?