#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);
int insert(Node_t *previous,int var);
int inserthead(Node_t **listhead, int var);
void delete(Node_t *previous);
void deletehead(Node_t **listhead);
void displaylist(Node_t *np);


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;
	}
}

int insert(Node_t *previous,int var){
	Node_t *node;
	node = new_Node(var, NULL);
	if(node != NULL){
		node->next = previous->next;
		previous->next = node;
		return 1;
	}else{
		return 0;
	}
}

/*
リストの初めにノードを挿入
listheadがどの番地に入っているかを渡さなければならない
そのため**listheadを渡している

挿入前
0010 listhead
	（値：1234）
        |
        |_____>1234 nd1（1番目のノード）
        

挿入後
0010 listhead
	（値：AAAA）
		|
		|___________>AAAA newnode（新しいノード）
		

これを行うためには、関数に0010（listheadの番地）を渡さなければならない

つまり
9999 listhead_address
	（値:0010）
		|
		|_______>0010 listhead
					 （値：AAAA）
					 	|
					 	|____________>AAAA newnode

*/
int inserthead(Node_t **listhead, int var){
	Node_t *node;
	node = new_Node(var, NULL);
	if(node != NULL){
		node->next = *listhead;
		*listhead = node;
		return 1;
	}else{
		return 0;
	}
}

void delete(Node_t *previous){
	Node_t *q;
	q = previous->next;
	previous->next = q->next;
	free(q);
}

void deletehead(Node_t **listhead){
	Node_t *q;
	q = *listhead;
	*listhead = q->next;
	free(q);
}


/*
リストの中身を表示させる
あえて、値渡しをしている
関数内でnpの値が変化してしまうが、main関数の中ではもとに戻る
*/
void displaylist(Node_t *np){
	while(np!=NULL){
		printf("%d\n",np->var);
		np=np->next;
	}
	printf("**************\n");
}
	
int main(void){
	Node_t *nd1, *nd2, *nd3;
	Node_t *np;
	Node_t *listhead;
	
	nd3 = new_Node(3,NULL);		//ノードを作る順番を注意
	nd2 = new_Node(2,nd3);
	nd1 = new_Node(1,nd2);
	
	listhead = nd1;
	np = listhead;
	displaylist(np);
	
	if(insert(nd2,10) == 1){
		displaylist(np);
	}
	
	if(inserthead(&np,100) == 1){
		listhead = np;
		displaylist(np);
	}

	delete(nd1);
	displaylist(np);

	deletehead(&(listhead));
	np = listhead;	
	displaylist(np);	
	
	return 0;
}