프로그래밍 C언어

큐 (Queue)

게임첫걸음 2024. 8. 21. 17:34
#include <stdio.h>
#include <windows.h>

#define MAX_LEN 5
#define ERROR_CODE 0xffffffff

enum EMenu { kPut = 1, kGet, kExit };


int g_queue[MAX_LEN] = { 0 };
int g_curIdx = 0;


// Put, Get
// Enqueue, Dequeue
void Put(int _data);
int Get();
void PrintAll();
inline int CheckFull() { return g_curIdx == MAX_LEN; }
inline int CheckEmpty() { return g_curIdx == 0; }


void main()
{
	// 큐(Queue)
	// 원형 큐(Circular Queue)
	// FIFO(First In, First Out) - 선입선출
	// Framework
	int input = 0;
	int exit = 0;

	while (!exit)
	{
		// Input
		printf("기능을 선택하세요.\n");
		printf("1.삽입 2.추출 3.종료\n-> ");
		scanf_s("%d", &input);

		if (input < 1 || input > 3)
		{
			system("@cls||clear");

			printf("다시 입력해주세요.\n");
			// return, break, continue
			continue;
		}

		// Update
		switch (input)
		{
		case kPut:
			// PutProcess();
		{
			printf("삽입할 데이터를 입력해주세요.\n-> ");
			int data = 0;
			scanf_s("%d", &data);
			Put(data);
		}
		break;
		case kGet:
		{
			printf("Get data: %d\n", Get());
		}
		break;
		case kExit:
			exit = 1;
			break;
		}

		// Render
		PrintAll();

		printf("메뉴로 돌아가실려면 아무키나 누르세요.\n");

		//fflush();
		while (getchar() != '\n');

		input = getchar();
		system("@cls||clear");
	}
}


void Put(int _data)
{
	if (CheckFull()) {
		printf("Queue is full!\n");
		return;
	}

	g_queue[g_curIdx] = _data;
	++g_curIdx;
}

int Get()
{
	if (CheckEmpty())
	{
		printf("Queue is empty!\n");
		return ERROR_CODE;
	}

	int returnValue = g_queue[0];

	for (int i = 1; i < g_curIdx; ++i)
	{
		printf("Move: %d <- %d\n",
			i, i - 1);
		g_queue[i - 1] = g_queue[i];
	}

	--g_curIdx;

	return returnValue;
}

void PrintAll()
{
	if (CheckEmpty())
	{
		printf("Queue is empty!\n");
		return;
	}

	printf("[ ");
	for (int i = 0; i < g_curIdx; ++i)
	{
		printf("%d, ", g_queue[i]);
	}
	printf("] (%d / %d)\n",
		g_curIdx, MAX_LEN);
}

 Queue란 Stack과 같은 자료구조의 한 가지입니다. 둘의 다른 점은 데이터의 저장 구조입니다.

  • Stack: First In, Last Out (FILO)
  • Queue: First In, First Out (FIFO)

큐의 선입선출 방식 예시

 

설명과 같이 큐는 먼저 삽입한 데이터가 먼저 나오는 구조를 가진 자료구조를 가지고 있습니다. 위는 입출문인 scanf_s문을 이용한 입력 기능 (input)이 들어간 프로그램에서 사용하는 코드입니다. 각 함수와 조건문별 기능 요약입니다.

  • void Put(): 데이터 삽입
  • int Get(): 데이터 추출
  • void PrintAll(): 데이터 출력
  • while(!exit): exit 변수의 값이 0이 아닐 때 루프 지속, 1이면 종료

<코드의 진행설명>

조건: int _data이기 때문에 정수형 값을 기입해야함. 아니면 0 또는 오류

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 

  • 1 ~ 3 범위 밖의 값을 입력하면 다시 입력해주세요, 텍스트가 위에 추가됩니다.

다시 입력해주세요.

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 

  • 1 선택 시

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 1

삽입할 데이터를 입력해주세요.

->

  • 정수형 값 입력 시

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 1

삽입할 데이터를 입력해주세요.

-> 3

[ 3,  ] (1 / 5)

메뉴로 돌아가려면 아무키나 누르세요. ( getchat() 사용)

  • 배열을 모두 채운 후, 추가로 삽입하려할 때

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 
이후, 출력을 선택 후 임의로 정수 값을 기입하여 [ 3, 4, 7, 18, 19 ] (5 / 5) 의 배열 완성, 이후 또 출력 선택 후 정수값을 삽입하면 Queue is full!이 출력되며 메뉴로 돌아가려면 아무키나 누르세요. 출력

  • 2번 추출 선택 시

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 2

Move: 1  <-  0

Move: 2  <-  1

Move: 3  <-  2

Move: 4  <-  3

Get data: 3이 출력 (첫 번째 요소부터 자동 출력)

[ 4, 7, 18, 19,  ] (4 / 5)

메뉴로 돌아가려면 아무키나 누르세요.

  • 언제든 3번 종료 선택 시

기능을 선택하세요.

1. 삽입 2. 추출 3. 종료

-> 3

[ 4, 7, 18, 19,  ] (4 / 5)
메뉴로 돌아가려면 아무키나 누르세요.

 

여기서 추가로 다룰 기능 코드는 3가지입니다.

//fflush();
while (getchar() != '\n');


input = getchar();
system("@cls||clear");

  • fflush문: 파일 스트림의 버퍼(Buffer)를 비우는데 사용됩니다.
  • getchar()문: 어떤 키를 입력하면 ASCII CODE값을 반환합니다. 어떤 값이든 1개의 값을 반환한다는 뜻입니다.
  • system("@cls||clear"): 프로그램이 실행되고 있는 콘솔의 화면을 초기화(클리어)하는 명령어입니다.
  • Buffer는 그냥 임의의 공간이라고 생각하시면 됩니다.
  • cls||clear 함수를 사용하지 않는다면 콘솔창에 지금까지 했던 모든 글들이 모두 표시되어 더러워집니다.