구조체 혹은 전역변수를 사용한 stack 의 단점은 하나의 프로그램에서 여러 개의 스택을 동시에 사용하기가 어렵다는 점이다. 객체지향의 개념과 유사하게 top 과 stack 배열을 하나의 구조체로 결합시키고 이 구조체의 포인터를 함수로 전달한다. 즉 StackType 이라는 새로운 구조체 타입을 만들고 여기에 stack 배열과 top 을 넣는다. 그리고 이 구조체에 대한 포인터를 각 함수의 매개변수로 전달하는 것이다. 모든 함수에서는 만약 전달된 구조체 포인터가 s이면, 기존의 top 이라고 사용하던 것을 s->top 으로 변경하면 된다. stack 배열도 s->stack 으로 변경하여 사용하면 된다. 이렇게 하면 쉽게 여러 개의 스택을 쉽게 만드는 것이 가능해진다. 즉 필요할 때마다 StackType 을 사용하여 구조체를 만들면 된다. 아래에 이러한 구현을 해보았다. 앞으로의 자료구조는 이러한 형식으로 구현 될 것이다. 이 방법에서는 StackType 구조체 안에 들어 있는 변수들을 초기화하기 위하여 init_stack() 함수가 필요하다. 여기서 주의할 것은 스택을 초기화하기 위하여 1차원 배열을 0으로 채울 필요는 없다. 배열에 어떤 값이 존재하더라도 top 의 값만 -1 로 하면 스택은 비어 있는 것으로 간주된다.
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <malloc.h>
#include <string.h>
//차후에 스택이 필요하면 여기만 복사하여 붙인다
//-----스택코드 시작-----
#define MAX_STACK_SIZE 100
typedef int element;
typedef struct {
element data[MAX_STACK_SIZE];
int top;
} StackType;
//스택 초기화 함수
void init_stack(StackType *s) {
s->top = -1;
}
//공백 상태 검출 함수
int is_empty(StackType *s) {
return (s->top == -1);
}
//포화 상태 검출 함수
int is_full(StackType *s) {
return (s->top == (MAX_STACK_SIZE - 1));
}
//삽입함수
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr,"스택 포화 에러\n");
return;
}
else s->data[++(s->top)] = item;
}
//삭제함수
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr,"스택 공백 에러\n");
exit(1);
}
else return s->data[(s->top)--];
}
//피크함수
element peek(StackType *s) {
if (is_empty(s)) {
fprintf(stderr,"스택 공백 에러\n");
exit(1);
}
else return s->data[s->top];
}
//----스택 코드 끝----
int main() {
StackType k; //스택을 정적으로 생성한다
init_stack(&k);
push(&k, 1); //함수를 호출할 때 스택의 주소를 전달한다
push(&k, 2);
push(&k, 3);
printf("%d\n",pop(&k));
printf("%d\n",pop(&k));
printf("%d\n",pop(&k));
}
위의 코드에서 약간 복잡해지는 요인은 구조체의 포인터를 각 함수에 전달하여야 한다는 점이다. 각 함수에서는 구조체의 포인터를 이용하여 스택을 조작한다. 이것은 c언어에서의 함수 매개변수 전달 방식이 기본적으로 값 전달 방식(call by value) 이기 때문이다. 즉 구조체를 함수의 매개변수로 전달하였을 경우, 구조체의 원본이 전달되는 것이 아니라 구조체의 복사본이 함수에 전달된다. 따라서 함수 안에서는 복사본을 수정하여도 원본에는 영향을 주지 못한다. 그러나 원본에 대한 포인터를 전달하면 원본을 변경할 수 있다. 위의 코드를 사용하면 여러 개의 스택을 동시에 만들 수 있다는 장점이 있다. 따라서 이제부터는 이 방식을 이용하여 각종 자료구조들을 구현하기로 한다.
#추가로 스택을 동적 메모리 할당을 사용하여 코드를 작성해보면
int main()
{
StackType *s;
s = (StackType *)malloc(sizeof(StackType)); //스택을 동적으로 생성한다
init_stack(s);
push(s, 1);
push(s, 2);
push(s, 3);
printf("%d\n",pop(s));
printf("%d\n",pop(s));
printf("%d\n",pop(s));
free(s);
}

| 선형큐 (0) | 2021.10.17 |
|---|---|
| 동적 배열 스택 (0) | 2021.10.17 |
| 스택의 요소를 구조체로 하기 (0) | 2021.10.17 |
| 전역 변수로 스택 구현하는 방법 (0) | 2021.10.17 |
| 구조체와 포인터 (0) | 2021.10.17 |
댓글 영역