#include <stdio.h>
#include <stdlib.h>

typedef struct node{
	int var;
	struct node *next;
}Node_t;

Node_t *new_Node(int x, Node_t *nxt);
void clearstack(Node_t **stack);
void push(int data, Node_t **top);
void pop(Node_t **stack);
void display(Node_t *stack);


Node_t *new_Node(int x, Node_t *nxt){
	Node_t *n1;
	
	n1 = calloc(1,sizeof(Node_t));
	if(n1 == NULL){
		return NULL;	//割り当て失敗
	}else{
		n1->var = x;
		n1->next = nxt;
		return n1;
	}
}

/*
topはspのようなものでありtopがさすノードがスタックの一番上の値
つまり以下のような動作が行われる。[]で囲われたものは、リストのひとつのノードとする

@
top
 ↓
[NULL]

Apush(1)
top
 ↓
[1]→[NULL]

Bpush(8)
top
 ↓
[8]→[1]→[NULL]

*/

void push(int data, Node_t **top){
	Node_t *p;
	p = new_Node(0,NULL);
	if(p!=NULL){
		p->var = data;
		p->next = *top;
		*top = p;
	}
}

/*
popを教科書どおりに実装すると以下のコメントアウトを含める関数になるが、
実際はコメントアウト部分はなくても動作する。
ただ、メモリの解放を考えるとコメントアウト部分は必要
中身はtopのさすノードのnextをtopがさすようにするというもの

@
top
 ↓
[8]→[1]→[NULL]

Apop

	top
 	 ↓
[8]→[1]→[NULL]

・[8]を解放

top
 ↓
[1]→[NULL]

*/
void pop(Node_t **top){
	Node_t *p;		//ここはなくても良い
	if(top == NULL)
		printf("スタックに値が入っていません");
	printf("取り出した値は%d\n",(*top)->var);
	p = *top;		//ここはなくても良い
	*top = (*top)->next;
	free(p);		//ここはなくても良い
}

void display(Node_t *stack){
	Node_t *np;
	np = stack;
	while(np!=NULL){
		printf("%d\n",np->var);
		np=np->next;
	}
	printf("***************\n");
}

void clearstack(Node_t **stack){
	*stack = NULL;
	printf("スタックが初期化されました\n");
	
}


int main(void){
	Node_t *stack = NULL;
	push(1,&(stack));
	push(8,&(stack));
	push(8,&(stack));
	push(8,&(stack));
	push(8,&(stack));
	display(stack);
	pop(&(stack));
	display(stack);
	clearstack(&stack);
	display(stack);
	return 0;
}