HI ..我想要一個如何在C中使用函數指針來實現FSM的例子。FSM中的函數指針
回答
一個例子太大了,無法在這裏寫出答案。 下面是一個例子存在的,這是我用谷歌搜索state machine c "function pointer"
發現:Implementing Efficient State Machines
感謝您的回覆。 – priya 2010-08-20 05:28:55
這是一個在ARDUINO中使用函數指針的小示例。這個例子不允許併發。它可以完美地轉換爲普通的C,如果在主內寫入設置和循環()
每個狀態都是void()函數。每個狀態功能負責讀取輸入和設置輸出。完成後,該功能應立即返回。它將被直接再次調用。通過在返回之前立即調用離開函數,該函數還負責狀態轉換。每個狀態函數都應該有一個用於計時的靜態長變量。
將全局變量狀態設置爲指向安裝例程中的初始狀態。 我想在不同的狀態下計時,所以我通過2個函數實現了狀態轉換:
void enter(long * stateTime),這應該在進入狀態函數時被稱爲第一件事。它激活狀態,如果不活躍的結束時間。
void leave(void(* next)(),long * statetime),這將更改全局狀態指針並禁用當前狀態。
void (*state)();//function pointer for state machine
long prevMillis = 0;//timekeeper
const int LEDPIN = 13;
int counter1 = 0;
void enter(long *statetime){
if(*statetime==-1){//check for passive state
prevMillis = millis();//set timemark when entering state
}//if(statetime==0)
*statetime = millis()-prevMillis;//keep time
}//enter()
void leave(void (*next)(), long *statetime){
*statetime=-1;//set state to passive
state=next;//point to next state
}//leave()
void off500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>499){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off500ms()
void off2s(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>1999){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off2s()
void on500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, HIGH);
if(stateMillis >499){//time is up
if(++counter1==6){//number of blinks
leave(off2s, &stateMillis);
counter1=0;//reset counter
}else{//if(++counter1==6)
leave(off500ms, &stateMillis);
}//if(++counter1==6)
}//if(stateMills>499)
}//on500ms
void setup(){
pinMode(LEDPIN, OUTPUT);
state = on500ms;//set initial state
}/setup()
void loop(){
state();//start FSM
}//loop
代碼躍遷可以通過陣列或開關情況下,可以利用。寫在if if指令下。
#include <stdio.h>
#include <stdlib.h>
int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
enum state_codes lookup_transitions(enum state_codes, enum ret_codes);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
enum state_codes src_state;
enum ret_codes ret_code;
enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}};
int main(int argc, char *argv[]) {
enum state_codes cur_state = entry;
enum ret_codes rc;
int (* state_fun)(void);
for (;;) {
state_fun = state[cur_state];
rc = state_fun();
if (end == cur_state)
break;
cur_state = lookup_transitions(cur_state, rc);
}
return EXIT_SUCCESS;
}
/*
* lookup_transition() function has time complexity of class O(n).
* We can optimize it.
* */
enum state_codes
lookup_transitions(enum state_codes cur_state, enum ret_codes rc)
{
#if 0
switch (cur_state) {
case entry:
cur_state = ((rc == ok) ? (foo) : (end));
break;
case foo:
cur_state = ((rc == ok) ? (bar) : ((rc == fail) ? (end) : (foo)));
break;
default:
cur_state = ((rc == ok) ? (end) : ((rc == fail) ? (end) : (foo)));
break;
}
return cur_state;
#else
char arr_size = (sizeof(state_transitions)/sizeof(state_transitions[0])); /* This can be shifted to main function to avoid redundant job. */
char count;
for (count = 0; count < arr_size; count++) {
if ((state_transitions[count].src_state == cur_state) && (state_transitions[count].ret_code == rc)) {
return (state_transitions[count].dst_state);
}
}
#endif
}
int entry_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN ENTRY STATE.\nEnter 0/1: ");
scanf("%d", &st);
rc = ((st == 1) ? (fail) : (ok));
return rc;
}
int foo_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN FOO STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int bar_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN BAR STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int exit_state(void)
{
printf("YOU ARE IN EXIT STATE.\n");
exit(EXIT_SUCCESS);
}
不,它是從github網站複製的..我寫的是lookup_transtion代碼。幾乎所有人都知道它是從github複製的。這是谷歌的第一個搜索結果。 https://gist.github.com/nmandery/1717405 並記住,從git hub複製。該stackoverflow的答案也從那裏複製。看看lookup_transition functiom ...我粘貼在這裏.. – 2017-05-28 22:29:35
隨着loopup_transtion功能,我寫了測試的小UT碼也also.and不會很快結束..「只是複製」至少了解差異。並且你引用了你自己的想法並且覺得自己想要......學生需要... – 2017-05-28 22:34:56
我不知道shino,爲什麼你不能看到區別。它被複制。這是開放的。但請找到丟失的查找功能和UT代碼... – 2017-05-28 22:36:21
- 1. 圖形函數中的FSM
- 2. C++中函數指針的指針
- 3. 函數指針指向一個函數指針的函數
- 4. c函數指針反函數指針
- 5. 指針?指針函數?
- 6. iOS中的函數指針?
- 7. 函數中的雙指針
- 8. Fortran中的函數指針
- 9. JavaScript中的函數指針
- 10. void函數中的指針
- 11. Java中的函數指針
- 12. 陣列的函數指針的指針
- 13. 指向結構函數指針的函數指針
- 14. 函數指針
- 15. 函數指針
- 16. 函數指針
- 17. 函數指針
- 18. 函數指針?
- 19. 函數指針
- 20. 函數指針
- 21. 函數指針
- 22. 函數指針
- 23. 函數指針
- 24. 函數指針
- 25. 指向函數的指針
- 26. 函數指針不帶指針參數
- 27. 函數指針數組指針用作函數的返回值
- 28. 函數指針/函數表
- 29. 成員函數指針指向函數指針?
- 30. C++通過函數指針指向另一個函數指針
我假設FSM意味着有限狀態機?你需要什麼函數指針?有關目標的更多信息將有助於獲得有用的示例。 – rubenvb 2010-08-19 09:38:51
(1)非常苛刻你。 (2)FSM代表什麼? (3)您是否已經獲得了可以向我們顯示的任何代碼,以及您目前卡住的指針? (4)這功課嗎? (如果是這樣,請編輯你的問題,並添加標籤'家庭作業'。) – stakx 2010-08-19 09:39:39
@stakx:你確定喜歡做無人認領的假設... – leppie 2010-08-19 09:44:06