《C程序设计语言》练习 4-4

练习 4-4
在栈操作中添加几个命令,分别用于在不弹出元素的情况下打印栈顶元素;
复制栈顶元素;交换栈顶两个元素的值。另外增加一个命令用于清空栈。


/*打印栈顶元素*/
void printtop(void)
{
    if (op > 0)
        printf("%g\n", val[op - 1]);
    else 
        printf("error: stack empty\n");
}

/*复制栈顶元素 如果成功返回被复制元素的值*/
double copy(void)
{   
    double n;
    if (op > 0)
    {
        push(n = val[op - 1]);
        return n;
    }
    else
    {
        printf("error: stack empty\n");
        return 0.0;
    }
}

/*交换栈顶的两个元素的值 成功返回 1 ,否则返回 0 */
int swop()
{
    double t;
    if (op > 1)
    {
        t = val[op - 1];
        val[op - 1] = val[op - 2];
        val[op - 2] = t;
        return 1;
    }
    else
    {
        printf("The number of elements in the stack is insufficient\n");
        return 0;
    }
}

/*清空栈 返回被清空的元素数*/
int clear()
{
    int n;
    if (op > 0)
    {
        n = op;
        op = 0;
        return n;
    }
    else
    {
        printf("error: stack empty\n");
        return 0;
    }
}

我在 main 里面加了一些对应的字符指令
p : 打印栈顶元素
c : 复制栈顶的元素并压入栈
s : 交换栈顶的两个元素的值
e : 清空栈 打印被清空的元素数
b : 删除栈顶元素,实际上调用的是 pop 函数

        case 'c':
        case 'C':
            op2 = copy();
            if (op2 != 0)
                printf("%g to be copied\n", op2);
            break;
        case 'e':
        case 'E':
            op2 = clear();
            if (op2 != 0)
                printf("The %d elements were deleted\n", (int)op2);
            break;
        case 'p':
        case 'P':
            printtop();
            break;
        case 's':
        case 'S':
            swop();
            break;
        case 'b':
        case 'B':
            op2 = pop();
            printf("%g deleted\n", op2);
            break;

完整代码 :

/*练习 4-4 在栈操作中添加几个命令,分别用于在不弹出元素的情况下打印栈顶元素;
复制栈顶元素;交换栈顶两个元素的值。另外增加一个命令用于清空栈。*/

#include 

//--------------main------------------------------------------------


#define MAXOP 100 //操作数与操作符的最大值
#define NUMBER '0' //getop得到数字或小数点时返回的值
/*获取输入的字符*/
int getop(char[]);
/*将 d 压入栈顶*/
void push(double d);
/*弹出栈顶元素*/
double pop(void);
/*打印栈顶元素*/
void printtop(void);
/*复制栈顶元素 如果成功返回被复制元素的值*/
double copy(void);
/*获得栈顶元素的值*/
double peek(void);
/*交换栈顶的两个元素的值 成功返回 1 ,否则返回 0 */
int swop();
/*清空栈 返回被清空的元素数*/
int clear();

double atof(char s[]);
int isspace(int);
int isdigit(int);



main()
{
    int type;
    double op2, op3;
    char s[MAXOP];

    while ((type = getop(s)) != EOF)
        switch (type)
        {
        case NUMBER:
            push(atof(s));
            break;
        case '+':
            push(pop() + pop());
            break;
        case '*':
            push(pop() * pop());
            break;
        case '-':
            op2 = pop();
            push(pop() - op2);
            break;
        case '/':
            op2 = pop();
            if (op2 != 0.0)
                push(pop() / op2);
            else
                printf("error: zero divisor\n");
            break;
        case '%':
            op2 = pop();
            op3 = pop();
            if (op2 != (int)op2 || op3 != (int)op3) //要保证取模的两个数都是整数
                printf("error: Only integers can get the modulus\n");
            else if (op2 == 0)
                printf("error: zero divisor\n");
            else if (op2 < 0)
                push(0);
            else
                push((int)op3 % (int)op2);
            break;
        case '=': //等于号用来取出栈中最上面的值
            printf("\t%.8g\n", pop());
            break;
        case '.':
            printf("error: There's no number in front of the decimal point");
            break;
        case 'c':
        case 'C':
            op2 = copy();
            if (op2 != 0)
                printf("%g to be copied\n", op2);
            break;
        case 'e':
        case 'E':
            op2 = clear();
            if (op2 != 0)
                printf("The %d elements were deleted\n", (int)op2);
            break;
        case 'p':
        case 'P':
            printtop();
            break;
        case 's':
        case 'S':
            swop();
            break;
        case 'b':
        case 'B':
            op2 = pop();
            printf("%g deleted\n", op2);
            break;
        case ' ': //空白字符不处理
        case '\n':
        case '\t':
            break;
        default:
            printf("error: unknown command %s\n", s);
            break;
        }

}

//--------------------------------------------------------------

//-------------获取字符-------------------------------------------------

int getch(void);
void ungetch(int);
int getop(char s[])
{
    int i, c, c2;
    while ((c = getch()) == ' ' || c == '\n' || c == '\t') //去除多余的空白字符
        ;


    if (c == '-' || c == '+')   // '-' 和 '+' 有可能作为符号位
        if (isdigit(c2 = getch()))//所以读取下一位,若是数字,则当做符号位
        {
            s[i++] = c;
            c = c2;
        }
        else
        {
            ungetch(c2);
            return c;
        }

    if (isdigit(c))
    {
        s[0] = c;
        i = 1;
        //数字的格式为 "xxx.xxx" 
        // x 是数字
        while (isdigit(c = getch()))
            s[i++] = c;
        if (c == '.')
        {
            s[i++] = c;
            while (isdigit(c = getch()))
                s[i++] = c;
        }

        //数字结束
        s[i] = '\0';
        if (c != '\n' && c != ' ' && c != '\t')
            ungetch(c);

        return NUMBER;
    }
    else
        return c;
}


#define BUFSIZE 100

char buf[BUFSIZE]; //缓存的字符数组
int bufp = 0; //缓存数组指针

int getch(void)
{
    if (bufp > 0)
        return buf[--bufp];
    else
        return getchar();
}
void ungetch(int c)
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

//--------------------------------------------------------------



//----------------栈操作----------------------------------------------


#define MAXVAL 100 //栈的最大长度

int op = 0;
double val[MAXVAL];

/*将 d 压入栈顶*/
void push(double d)
{
    if (op < MAXVAL)
        val[op++] = d;
    else
        printf("error: stack full, can't push %g\n", d);
}

/*弹出栈顶元素*/
double pop(void)
{
    if (op > 0)
        return val[--op];
    else
        printf("error: stack empty\n");
    return 0.0;
}

/*打印栈顶元素*/
void printtop(void)
{
    if (op > 0)
        printf("%g\n", val[op - 1]);
    else 
        printf("error: stack empty\n");
}

/*复制栈顶元素 如果成功返回被复制元素的值*/
double copy(void)
{   
    double n;
    if (op > 0)
    {
        push(n = val[op - 1]);
        return n;
    }
    else
    {
        printf("error: stack empty\n");
        return 0.0;
    }
}

/*获得栈顶元素的值*/
double peek(void)
{
    if (op > 0)
        return val[op - 1];
    else
        printf("error: stack empty\n");
    return 0.0;
}

/*交换栈顶的两个元素的值 成功返回 1 ,否则返回 0 */
int swop()
{
    double t;
    if (op > 1)
    {
        t = val[op - 1];
        val[op - 1] = val[op - 2];
        val[op - 2] = t;
        return 1;
    }
    else
    {
        printf("The number of elements in the stack is insufficient\n");
        return 0;
    }
}

/*清空栈 返回被清空的元素数*/
int clear()
{
    int n;
    if (op > 0)
    {
        n = op;
        op = 0;
        return n;
    }
    else
    {
        printf("error: stack empty\n");
        return 0;
    }
}
//--------------------------------------------------------------





//---------------转换成数字-----------------------------------------------

double atof(char s[])
{
    double power, val;
    int sign, i, sign2, j, n;
    for (i = 0; isspace(s[i]); i++)
        ;

    sign = (s[i] == '-') ? -1 : 1;

    if (s[i] == '-' || s[i] == '+')
        i++;
    for (val = 0.0; isdigit(s[i]); i++)
        val = val * 10 + (s[i] - '0');
    if (s[i] == '.')
        i++;
    for (power = 1.0; isdigit(s[i]); i++)
    {
        val = val * 10 + (s[i] - '0');
        power *= 10;
    }

    if (s[i] == 'e' || s[i] == 'E')
    {
        i++;
        sign2 = (s[i] == '-') ? 1 : 0;
        if (s[i] == '-' || s[i] == '+')
            i++;

        for (n = 0; isdigit(s[i]); i++)
            n = n * 10 + (s[i] - '0');

        for (j = 0; j < n; j++)
            power = (sign2) ? (power * 10) : (power / 10);

    }
    return val * sign / power;
}
int isspace(int x)
{
    return (x == ' ' || x == '\t' || x == '\n') ? 1 : 0;
}
int isdigit(int x)
{
    return (x >= '0' && x <= '9') ? 1 : 0;
}

//--------------------------------------------------------------

发现 getop函数在处理 ‘+’ 和 ‘-’ 时写的代码有问题,
已修改
by 2018-1-4

你可能感兴趣的:(C,c语言,c程序设计语言)