這個指針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語言學習到什麼程度?

TAG:C編程語言 | 指針 |