在C中排列代码以分离函数

在C中排列代码以分离函数,c,stack,parentheses,brackets,C,Stack,Parentheses,Brackets,我在大学里做的练习是:“输入等式,检查是否有括号。如果是打开的,则推入堆栈。如果是关闭的,则检查堆栈的头元素是否是打开的括号/括号。如果堆栈是空的,则等式是正确的”。我编写了在main()函数中检查它的代码。但需要检查方程的元素是否为第一个函数中的括号,并与下一个括号进行比较 如果你能帮助我,非常感谢)。代码如下: #include <stdio.h> <stdlib.h> <string.h> #define STACK_SIZE 20 #define O

我在大学里做的练习是:“输入等式,检查是否有括号。如果是打开的,则推入堆栈。如果是关闭的,则检查堆栈的头元素是否是打开的括号/括号。如果堆栈是空的,则等式是正确的”。我编写了在main()函数中检查它的代码。但需要检查方程的元素是否为第一个函数中的括号,并与下一个括号进行比较

如果你能帮助我,非常感谢)。代码如下:

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

#define STACK_SIZE 20
#define OVERFLOW -100
#define UNDERFLOW -101

///BEGIN DEFINING
typedef char C;
typedef struct Stack_tag {
    C data[STACK_SIZE];
    size_t size;
} Stack;
///END DEFINING

///BEGIN STACK FUNCTIONS
void Push(Stack* stack, const C value) {
    if (stack->size >= STACK_SIZE) exit(OVERFLOW);

    stack->data[stack->size] = value;
    stack->size++;
}

C Pop(Stack* stack) {
    if (stack->size == 0) exit(UNDERFLOW);

    stack->size--;
    return stack->data[stack->size];
}

C Peek(const Stack* stack) {
    if (stack->size <= 0) exit(UNDERFLOW);
    return stack->data[stack->size - 1];
}

void PrintStackValue(const C value) {
    printf("%c", value);
}

void PrintStack(const Stack* stack, void(*PrintStackValue)(const C)) {
    int i, len = stack->size - 1;
    printf("\nStack %d", stack->size);
    for (i = 0; i < len; i++) {
        PrintStackValue(stack->data[i]);
        printf(" | ");
    }
    if (stack->size != 0) {
        PrintStackValue(stack->data[i]);
    }
    printf("\n");
}
///END STACK FUNCTIONS

///BEGIN OTHER FUNCTIONS
char isBr(char item) {
    switch (item) {
    case '(': return '(';
    case ')': return ')';
    case '[': return '[';
    case ']': return ']';
    case '{': return '{';
    case '}': return '}';
    default: return NULL;
    }
}
void Check(char item, Stack stack) {
    switch (item) {
    case '(': Push(&stack, item);
    case '[': Push(&stack, item);
    case '{': Push(&stack, item);
    case ')': if (Peek(&stack) == '(') Pop(&stack);
    case ']': if (Peek(&stack) == ']') Pop(&stack);
    case '}': if (Peek(&stack) == '}') Pop(&stack);
    }
}
///END OTHER FUNCTIONS
int main()
{
    Stack stack;
    stack.size = 0;
    ///EQUATION
    char* equation;
    int i;
    equation = (char*)malloc(100 * sizeof(char));
    printf("Enter the Equation: \n");
    gets(equation);
    ///CHECKING PROCESS
    ///TODO:
    ///1) SEPARATE FUNCTIONS
    for (i = 0; i < strlen(equation); i++) {
        /*
        if (equation[i] == '(' || equation[i] == '{' || equation[i] == '[') {
            Push(&stack, equation[i]);
        }
        if (equation[i] == ')') {
            if (Peek(&stack) == '(') Pop(&stack);
        }
        if (equation[i] == '}') {
            if (Peek(&stack) == '{') Pop(&stack);
        }
        if (equation[i] == ']') {
            if (Peek(&stack) == '[') Pop(&stack);
        }
        */
        char p = isBr(equation[i]);
        Check(p, stack);

    }



    ///PRINT THE RESULT
    puts(stack.size == 0 ? "FINE" : "NOOPE!!!");
    //PrintStack(&stack, PrintStackValue);

    return 0;
}

#包括
#定义堆栈大小20
#定义溢出-100
#定义下溢-101
///开始定义
typedef-charc;
typedef结构堆栈标记{
C数据[堆栈大小];
大小;
}堆叠;
///端部定义
///开始堆栈函数
无效推送(堆栈*堆栈,常量C值){
如果(堆栈->大小>=堆栈大小)退出(溢出);
堆栈->数据[堆栈->大小]=值;
堆栈->大小++;
}
C Pop(堆栈*堆栈){
如果(堆栈->大小==0)退出(下溢);
堆栈->大小--;
返回堆栈->数据[堆栈->大小];
}
C Peek(常数堆栈*堆栈){
如果(堆栈->大小数据[堆栈->大小-1];
}
无效打印堆栈值(常量C值){
printf(“%c”,值);
}
void打印堆栈(常量堆栈*堆栈,void(*PrintStackValue)(常量C)){
int i,len=stack->size-1;
printf(“\n堆栈%d”,堆栈->大小);
对于(i=0;i数据[i]);
printf(“|”);
}
如果(堆栈->大小!=0){
PrintStackValue(堆栈->数据[i]);
}
printf(“\n”);
}
///端堆栈函数
///开始其他功能
字符isBr(字符项){
开关(项目){
格“(”:返回“(”;
case'):return');
大小写“[”:返回“[”;
案例']':返回']';
大小写“{”:返回“{”;
大小写“}”:返回“}”;
默认值:返回NULL;
}
}
无效检查(字符项、堆栈){
开关(项目){
案例“(”:推送(&堆栈,项);
案例“[”:推送(&堆栈,项);
案例“{”:推送(&堆栈,项);
case'):如果(Peek(&stack)='(')Pop(&stack);
案例']':如果(Peek(&stack)=']')Pop(&stack);
案例“}”:if(Peek(&stack)=='}')Pop(&stack);
}
}
///结束其他职能
int main()
{
堆叠;
stack.size=0;
///方程式
char*方程;
int i;
方程=(char*)malloc(100*sizeof(char));
printf(“输入公式:\n”);
获取(方程);
///检查过程
///待办事项:
///1) 独立功能
对于(i=0;i
这里有两个问题:

  • 当您将堆栈结构传递给
    Check
    时,函数会看到堆栈的副本。因此,您所做的更改将丢失在
    main
    中–它们只对副本进行了更改。传递指向结构的指针,就像您对堆栈操作的函数所做的那样。(由于变量
    堆栈
    将成为
    检查
    中的指针,因此应将
    堆栈
    而不是
    堆栈
    传递给堆栈函数。)

  • C中
    switch
    语句中的情况不是孤立的。如果不以
    break
    return
    结束代码,执行将“失败”到下一个情况

您的检查函数可以如下所示:

void Check(char item, Stack *stack) {
    switch (item) {
    case '(': Push(stack, item); break;
    case '[': Push(stack, item); break;
    case '{': Push(stack, item); break;
    case ')': if (Peek(stack) == '(') Pop(stack); break;
    case ']': if (Peek(stack) == ']') Pop(stack); break;
    case '}': if (Peek(stack) == '}') Pop(stack); break;
    }
}
Check(p, &stack);
你从main这样称呼它:

void Check(char item, Stack *stack) {
    switch (item) {
    case '(': Push(stack, item); break;
    case '[': Push(stack, item); break;
    case '{': Push(stack, item); break;
    case ')': if (Peek(stack) == '(') Pop(stack); break;
    case ']': if (Peek(stack) == ']') Pop(stack); break;
    case '}': if (Peek(stack) == '}') Pop(stack); break;
    }
}
Check(p, &stack);
进一步的意见:

  • 堆栈下溢不应导致程序立即退出。相反,它应导致一条消息,表明等式格式不正确
  • 如注释中所述,不要使用不安全且不推荐使用的函数
    gets
    。请改用
    fgets
  • 使用
    malloc
    ,确实不需要在堆上分配100个字符的缓冲区。只需使用一个自动数组:
    char等式[100];
    。如果使用
    malloc
    ,在从
    main
    返回之前,还必须使用
    free

[切线]不要使用<代码>获取< /C>。它被弃用,并且从此被从C和C++移除。如果OP使用<代码>,在程序退出之前释放内存真的有好处吗?当然,系统应该清理资源,但在我看来,这是一种不好的做法。我认为学习者应该养成释放分配内存、
关闭打开的文件等的习惯。在C中,你必须自己管理资源,所以最好习惯它。