#if ! defined(_STACK_H_)			/* 避免重複 include */
#define _STACK_H_

#define MAX_STACK_SIZE 8192

typedef struct {				/* 堆疊型別 */
    int n_elem;					/* 目前堆疊中有多少個元素 */
    int data[MAX_STACK_SIZE];
} stack;

void stack_init(stack * s);
void stack_push(stack * s, int n);
int stack_pop(stack * s);
int stack_is_empty(stack const * s);

#endif

/*
名稱: stack.c
作者: 洪朝貴 http://www.cyut.edu.tw/~ckhung/
功能: 堆疊模組
*/
/* #include "stack.h" */
#include <assert.h>

void stack_init(stack * s)			
/* 設定起始值. 宣告/定義每個 stack 變數之後, 使用之前, 一定要呼叫 */
{
    s->n_elem = 0;
}

void stack_push(stack * s, int n)
/* 將 n 放入堆疊 s 中, 放在最上面 */
{
    assert(s->n_elem < MAX_STACK_SIZE);
    s->data[s->n_elem] = n;
    ++ s->n_elem;
}

int stack_pop(stack * s)
/* 將堆疊 s 中的最上面那個元素取出來 */
{
    assert(0 < s->n_elem);
    -- s->n_elem;
    return s->data[s->n_elem];
}

int stack_is_empty(stack const * s)
/* 堆疊 s 空了嗎? */
{
    return 0 >= s->n_elem;
}

#if defined(TEST)

/*  測試程式: 簡單的 post-fix 計算機. 以 "gcc -Wall -DTEST stack.c" 編譯,
    以 "a.out 3 5 + 7 \* 5 %" 測試. */

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

int main(int argc, char *argv[])
{
    stack numbers;
    int i;
    int x, y, z;

    stack_init(& numbers);
    for (i=1; i<argc; ++i) {
	if (isdigit(argv[i][0])) {
	    z = atoi(argv[i]);
	} else if (strchr("+-*/%", argv[i][0])) {
	    y = stack_pop(& numbers);
	    x = stack_pop(& numbers);
	    switch (argv[i][0]) {
	    case '+' : z = x + y; break;
	    case '-' : z = x - y; break;
	    case '*' : z = x * y; break;
	    case '/' : z = x / y; break;
	    case '%' : z = x % y; break;
	    default: assert(0);
	    }
	} else {
	    fprintf(stderr, "strange char in argv[%d]: '%c'\n", i, argv[i][0]);
	    fprintf(stderr, "(Did you remember to quote '*' ?)\n");
	    exit(1);
	}
	stack_push(& numbers, z);
    }
    printf("%d\n", stack_pop(& numbers));
    if (! stack_is_empty(& numbers))
	fprintf(stderr, "Warning: stack ends up being non-empty!\n");
    return 0;
}

#endif

