프로그래밍 C언어

스택 (Stack)

게임첫걸음 2024. 8. 21. 16:53
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

#define MAX_LEN 5

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

void Push(int _data);	//데이터 삽입용
int Pop();	//데이터 제거용 (스택에서 데이터를 꺼내는 기능)
void PrintAll();	//출력용
inline int CheckEmpty() { return g_curIdx == 0; }
inline int RandomRange(int _min, int _max)
{
	// 70 ~ 100
	return _min + rand() % (_max - _min + 1);
}
inline int PrintEmptyMessage() { printf("스택이 비어있음!\n"); }

void main()
{
	// 스택(Stack)
	// FILO(First In, Last Out) - 선입후출
	// Buffer
	// Random
	// Random Seed	//난수 발생 seed
	srand(time(NULL));	//시간을 다뤄 random으로 seed를 줌

	Pop();

	for (int i = 0; i < 6; ++i) 
	{
		Push(RandomRange(1, 100));	
	}
	PrintAll();

	printf("\n");

	Pop();
	Pop();

	PrintAll();
}

void Push(int _data)
{
	if (MAX_LEN <= g_curIdx)
	{
		printf("스택 오버플로우!\n");
		return;
	}

	printf("[%d]: %d\n", g_curIdx - 1, g_iarr[g_curIdx - 1]);
	g_iarr[g_curIdx] = _data;
	++g_curIdx;
}

int Pop()
{
	if (CheckEmpty())
	{
		PrintEmptyMessage();
		return INT_MIN;
	}

	printf("Pop [%d]: %d\n", g_curIdx - 1, g_iarr[g_curIdx - 1]);

	return g_iarr[--g_curIdx];
}

void PrintAll()
{
	//Function Call Overhead
	if (CheckEmpty())
	{
		PrintEmptyMessage();
		return;
	}

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

<스택>(Stack)

 스택이란 RAM(단기기억장치)의 구성 3가지 중 하나로 선입후출(First In, Last Out)의 특징을 가지고 있으며 지역 변수를 다룰 때 이용됩니다.

스택의 선입후출 방식 예시

 

<헤드파일>(Head)

stdio.h 말고도 세 개의 헤드파일을 추가호 사용하였습니다. 어느 코드에 필요한 헤드파일인지 알아보겠습니다.

  • limits.h: 다양한 데이터 타입의 최댓값과 최솟값을 정의하는 상수를 포함합니다. 위의 코드샹 INT_MIN에 사용되며 스택에서 빈 상태를 나타내는 값입니다.
  • stdlib.h: 동적 메모리 할당, 프로세스 종료, 변환 함수 등을 제공하고 위 코드에서는 rand() 함수에 사용되어 난수를 생성하는데 상요됩니다.
  • time.h: 시간과 날짜를 처리하는 함수를 제공합니다. 위 코드에서 srand()함수를 사용하고 난수 생성기의 시드를 설정하는데에 사용됩니다.
  • stdio.h: C언어 표준 라이브러리에서 자주 사용되는 헤더 파일 중 하나로 입출려과 관련된 기능 제공.

<전역변수>(Global)

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

void Push(int _data); //데이터 삽입용
int Pop(); //데이터 제거용 (스택에서 데이터를 꺼내는 기능)
void PrintAll(); //출력용
inline int CheckEmpty() { return g_curIdx == 0; }
inline int RandomRange(int _min, int _max)

{
return _min + rand() % (_max - _min + 1);
}
inline int PrintEmptyMessage() { printf("스택이 비어있음!\n"); }

 

위는 어떠한 함수에도 포함되지않은 전역변수들로 코드들을 해석하겠습니다.

  • g_iarr[MAX_LEN] = { 0 }: global의 접두사 g를 앞에 붙여 전역 변수인 것을 읽기 편하게 표시해준겁니다. 기능은 따로 없습니다. MAX_LEN은 define문으로 5로 정의했기 때문에 크기 5인 g_iarr 1차원 변수에 모든 값을 0으로 초기화한 겁니다.
  • g_curIdx=0: g의 의미는 위와 같으며 현재 스택의 상단 인덱스를 뜻하는 curIdx 변수를 0으로 초기화하겠다는 뜻.
  • void Push(int_data): Push 함수 선언으로 int_data라는 정수형 변수를 매개로 가지고 있습니다. data는 보통 삽입용의 변수로 사용합니다.
  • int Pop(): 데이터 제거용 함수로 스택에서 데이터를 꺼내는 기능입니다.
  • void PrintAll(): 출력용 함수입니다.
  • inline문: 짧고 간단하지만 자주 호출하는 함수에 사용됩니다. 다만 너무 큰 함수는 성능이 저하된다는 단점이 있습니다.

<정의된 함수 해석>

void Push(int _data)
{
if (MAX_LEN <= g_curIdx)
{
printf("스택 오버플로우!\n");
return;
}

printf("[%d]: %d\n", g_curIdx - 1, g_iarr[g_curIdx - 1]);
g_iarr[g_curIdx] = _data;
++g_curIdx;
}

 

 Push 함수는 데이터를 삽입할 때 사용하는 함수입니다.

  • MAX_LEN은 처음 코드를 짤 때 배열의 최대 길이를 5라고 표현한 것이므로 배열의 마지막 인덱스 변수인 g_curIdx가 MAX_LEN보다 크거나 같으면 꽉 차거나 넘치는 것으로 스택 오버플로우! 출력과 함께 함수를 종료해달라는 뜻입니다.
  • g_curIdx가 배열의 마지막 요소 인덱스라는 뜻이므로 (g_curIdx-1)이 인덱스입니다. 그리고 그 인덱스의 값 g_iarr[g_curIdx - 1]을 출력해달라는 뜻입니다.
  • 이후 상단 인덱스를 +1만큼 증가

int Pop()
{
if (CheckEmpty())
{
PrintEmptyMessage();
return INT_MIN;
}

printf("Pop [%d]: %d\n", g_curIdx - 1, g_iarr[g_curIdx - 1]);

return g_iarr[--g_curIdx];
}

  • CheckEmpty는 inline문으로 if( g_curIdx == 0 ) 와 같습니다. 즉, 인덱스가 0으로 배열이 비어있냐는 조건문입니다.
  • PrintEmptyMessage또한 inline문으로 "스택이 비어있음!"를 출력하라는 뜻입니다.
  • INT_MIN은 스택이 비어 있을 때 사용하는 반환값을 정의합니다.
  • 현재 인덱스 g_curIdx - 1 에 있는 값을 출력하고 상단의 인덱스를 -1 감소하고 그 값을 반환합니다.

void PrintAll()
{
//Function Call Overhead
if (CheckEmpty())
{
PrintEmptyMessage();
return;
}

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

  • PrintAll함수는 출력문입니다.
  • inline에 따라 if(g_curIdx == 0) 이라면 스택이 비어있음!을 출력하고 함수를 종료
  • 이후는 출력문으로 각 요소와 값을 출력하라는 뜻
  • 마지막 출력문은 스택의 현재 상태를 출력하는 코드로 (현재 인덱스 / 최대 크기)가 출력

'프로그래밍 C언어' 카테고리의 다른 글

단일 연결 목록 (Single Linked - List)  (0) 2024.08.22
큐 (Queue)  (0) 2024.08.21
다차원배열 (Multi-Dimensional Array)  (0) 2024.08.21
상수 열거형 (Enumeration)  (0) 2024.08.20
공용체 (Union)  (0) 2024.08.20