C의 상태 머신
이 기사에서는 C 프로그래밍 언어로 상태 시스템을 구현하는 방법을 보여줍니다.
상태 머신 개요
상태 시스템을 사용하여 코드를 구현하는 것은 복잡한 엔지니어링 문제를 해결하는 데 유용한 설계 전략입니다. 상태 기계는 전체 설계를 취하여 상태 기계 전문 용어 내에서 상태라고 하는 여러 단계로 나눕니다.
모든 국가는 특정 기능을 수행할 책임이 있습니다. 반면에 이벤트는 상태 머신이 상태 간에 변경되도록 하는 자극입니다. “전환"이라고도 합니다.
처음 작성되었을 때 대부분의 시스템은 간단하고 잘 구성되어 있지만 새로운 기능이 추가되면 이벤트 기록을 추적하기 위해 추가 플래그와 변수가 생성됩니다.
그런 다음 if
및 else
문을 추가하여 많은 변수 및 플래그에서 생성된 훨씬 더 복잡한 논리 표현식을 테스트합니다.
이와 관련하여 상태 머신이 도움이 됩니다. 적절하게 활용하면 상태 기계는 각 분기점에서 테스트된 조건을 단순화하고 다양한 프로그램 실행 모드 간 전환
을 더 쉽게 만듭니다.
대부분의 실시간 시스템의 동작은 상대적으로 적은 수의 겹치지 않는 청크(상태)로 나눌 수 있습니다.
각 청크 내의 이벤트 응답은 현재 이벤트에만 의존하며 더 이상 과거에 발생한 일련의 이벤트에 의존하지 않습니다.
함수 포인터
를 사용하여 상태 머신 생성
다음은 C에서 상태 시스템을 구축하는 코드의 예입니다. 이 특정 예는 두 개의 상태
스위치를 앞뒤로 10번 생성합니다.
그런 다음 색인 번호와 해당 색인에 해당하는 상태를 표시합니다.
#include <stdio.h>
struct state;
typedef void state_fn(struct state *);
struct state {
state_fn *next;
int i;
};
state_fn off_state, on_state;
void off_state(struct state *state) {
printf("%s %i\n", __func__, ++state->i);
state->next = on_state;
}
void on_state(struct state *state) {
printf("%s %i\n", __func__, ++state->i);
state->next = state->i < 10 ? off_state : 0;
}
int main(void) {
struct state state = {off_state, 0};
while (state.next) state.next(&state);
}
출력:
off_state 1
on_state 2
off_state 3
on_state 4
off_state 5
on_state 6
off_state 7
on_state 8
off_state 9
on_state 10
Switch
문을 사용하여 상태 머신 생성
제대로 시작하려면 프로그램이 있을 수 있는 상태
집합과 프로그램이 처리할 수 있는 이벤트
집합을 나열해야 합니다.
이 프로그램은 START,
ITERATE,
또는 END
의 세 가지 상태 중 하나일 수 있습니다.
enum states {
START,
ITERATE,
END,
} state;
START LOOPING
, SHOW_MESSAGE
및 STOP LOOPING
이벤트를 처리할 수 있습니다. START
상태에 있는 동안 START LOOPING
이벤트를 수신한 후 프로그램은 ITERATE
상태로 전환됩니다.
ITERATE
상태에 있는 동안 SHOW_MESSAGE
이벤트를 수신하면 메시지를 표시합니다. 마지막으로 STOP LOOPING
이벤트를 수신한 후 END
상태로 전환됩니다.
enum events {
START_LOOPING,
SHOW_MESSAGE,
STOP_LOOPING,
};
현재 상태를 보고 적절한 사례를 실행하는 switch
문을 사용합시다. START
ITERATE
및 END
라고 하는 세 가지 기본 상황이 있습니다.
START
케이스 내에서 수신된 이벤트가 START LOOPING
이면 상태가 ITERATE
로 변경됩니다. 이벤트가 START LOOPING
이 아니면 케이스가 깨집니다.
마찬가지로 ITERATE
사례에서 수신된 이벤트가 SHOW MESSAGE
인 경우 메시지를 표시합니다. 그렇지 않으면 STOP LOOPING
사례를 확인하고 상태를 END
로 변경합니다.
이러한 이벤트가 수신되지 않으면 중단되고 다음 케이스로 넘어갑니다. 마지막으로 END
케이스로 인해 switch
문이 종료되고 프로그램이 종료됩니다.
void switchState(enum events event) {
switch (state) {
case START:
switch (event) {
case START_LOOPING:
state = ITERATE;
break;
default:
exit(1);
break;
}
break;
case ITERATE:
switch (event) {
case SHOW_MESSAGE:
printf("State Machine Ready!\n");
break;
case STOP_LOOPING:
state = END;
break;
default:
exit(1);
break;
}
break;
case END:
exit(1);
break;
}
}
마지막으로 switchState()
라는 메서드를 호출하고 이벤트를 인수 형식으로 한 번에 하나씩 제공합니다.
int main(void) {
switchState(START_LOOPING);
switchState(SHOW_MESSAGE);
switchState(STOP_LOOPING);
return 0;
}
다음은 switch
문을 사용하는 전체 소스 코드입니다.
#include <stdio.h>
#include <stdlib.h>
enum states {
START,
ITERATE,
END,
} state;
enum events {
START_LOOPING,
SHOW_MESSAGE,
STOP_LOOPING,
};
void switchState(enum events event) {
switch (state) {
case START:
switch (event) {
case START_LOOPING:
state = ITERATE;
break;
default:
exit(1);
break;
}
break;
case ITERATE:
switch (event) {
case SHOW_MESSAGE:
printf("State Machine Ready!\n");
break;
case STOP_LOOPING:
state = END;
break;
default:
exit(1);
break;
}
break;
case END:
exit(1);
break;
}
}
int main(void) {
switchState(START_LOOPING);
switchState(SHOW_MESSAGE);
switchState(STOP_LOOPING);
return 0;
}
출력:
State Machine Ready!
I am Waqar having 5+ years of software engineering experience. I have been in the industry as a javascript web and mobile developer for 3 years working with multiple frameworks such as nodejs, react js, react native, Ionic, and angular js. After which I Switched to flutter mobile development. I have 2 years of experience building android and ios apps with flutter. For the backend, I have experience with rest APIs, Aws, and firebase. I have also written articles related to problem-solving and best practices in C, C++, Javascript, C#, and power shell.
LinkedIn