본문 바로가기

C/자료구조

문과생이 이해한 스택(동적, 구조체)

728x90

출처 : <c언어로 쉽게 풀어쓴 자료구조> + 학교 수업

 

#include<stdio.h>
#include<stdlib.h>

typedef int element;

typedef struct node {
	element data;
	struct node* link;
}node;

node* top = NULL;

void push(element value) {
	node* new_node = (node*)malloc(sizeof(node));
	if (new_node == NULL) {
		fprintf(stderr, "메모리 할당 에러\n");
		return;
	}
	else {
		new_node->data = value;
		new_node->link = top;
		top = new_node;
	}
}

element pop() {
	if (top == NULL) {
		fprintf(stderr, "스택이 비어있음\n");
		exit(1);
	}
	else {
		node* p = top;
		int item = p->data;
		top = p->link;
		free(p);
		return item;
	}
}

int main() {
	push(1);
	push(2);
	push(3);

	printf("%d \n", pop());
	printf("%d \n", pop());
	printf("%d \n", pop());

	return 0;
}

 

 

#잠깐

 

 

 나는 c를 복전하기 전에 야매로 독학했다. 그래서인지 기초가 좀 탄탄치 못하다. 구조체 사용할 때 왜 포인터 안 쓰지? 이 생각을 했다.. 

 

 그리고 구조체를 .으로 접근하는 거랑 ->로 접근하는 거랑 무슨 차이가 있나 싶었는데 .으로 접근하는 건 구조체 변수일 때고 ->는 포인터일 때라고 한다.

 

 

 

#push(1)

(+) 뜬금없는데 왜 push에서는 그냥 return하고 pop에서는 exit(1)로 프로그램을 종료하는지 궁금했는데.

1. 일단 동적할당이다보니 MAX가 없고(==사이즈에 한계가 없다) 

2. 저 if문 조건 뜻이. 옛날 컴파일러에서는 malloc으로 데이터를 할당해줬는데 NULL로 저장되는 에러가 종종 있었다고 한다. 지금의 컴파일러는 안 그러는데 아무래도 관용적으로 굳어진 듯. 

 

 결론, return을 하던 프로그램을 종료하던 프로그래머 마음인데. 이 코드에서는 push를 하고 pop을 하는 연산만 할 건데, pop할 게 없다는 건 모두 출력했다는 의미로 받아들이기 때문인 것 같다. 

 

 

 자! 본론으로 돌아와서 14줄처럼 new_node에 동적 할당을 해준다. 

 new_node에 NULL이 아니라 10'가 들어있으니까 else문으로 간다. 

 

 

 

 

모든 push를 마치면 이런 느낌.

 

 

 사실 모양을 이렇게 쌓아서 그렇지 연결리스트랑 다를 게 없긴 하다. 

 

 

#pop()

 전역변수 top을 NULL로 초기화 해줬다. 그러므로 top이 NULL이라는 건 한 번도 push를 안 해줫다는 거. 스택이 비었는데 pop을 하면 응징으로 프로그램을 지워버린다. 기억하자. exit(1) 에러로 인한 강제종료. 

 

 

 

 pop() 끝나면 30번지를 가리키는 객체가 없으므로 자연스레 운영체제가 슥삭한다. 

 

pop()가 끝난 모습.