상세 컨텐츠

본문 제목

관련된 데이터를 함수의 매개변수로 전달하는 방법

Coding/자료구조(with C)

by 세미531 2021. 10. 17. 04:33

본문

728x90

구조체 혹은 전역변수를 사용한 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);
}

 

 

728x90

'Coding > 자료구조(with C)' 카테고리의 다른 글

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

관련글 더보기

댓글 영역