2016-12-18 7 views
2

Я пробовал написать код, чтобы проверить, сбалансированы ли в парагенезе выражения, используя нижеследующую функцию. Может кто-то помочь мне понять, почему ниже функция возвращает 1 в случае сбалансированного выражения, когда это нигде не указано, для возврата 1.Возвращаемое значение функции в C

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

struct Stack 
{ 
    int top; 
    unsigned capacity; 
    char* array; 
}; 

struct Stack* createStack (unsigned capacity) 
{ 
    struct Stack* stack = (struct Stack*) malloc (sizeof(struct Stack)); 
    if(!stack) 
     return NULL; 

stack->top = -1; 
stack->capacity = capacity; 
stack->array = (char*) malloc(stack->capacity * sizeof(int)); 

if (!stack->array) 
    return NULL; 
return stack; 
} 

int isEmpty(struct Stack* stack) 
{ 
    return (stack->top == -1); 
} 
void push(struct Stack* stack, char op) 
{ 
    stack->top++; 
    stack->array[stack->top] = op; 

} 

int pop(struct Stack* stack) 
{ 

    if (!isEmpty(stack)) 
     return (stack->array[stack->top--]); 
    return '$'; 
} 

int isMatchingPair(char char1 , char char2) 
{ 
    if (char1 == '(' && char2 == ')') 
     return 1; 
    else if (char1 == '[' && char2 == ']') 
     return 1; 
    else if (char1 == '{' && char2 == '}') 
     return 1; 
    else 
     return 0; 
} 

int paranthesesMatch(char* exp) 
{ 
    int i; 
    struct Stack* stack = createStack(strlen(exp)); 
    for(i = 0; exp[i]; i++) 
    { 
     if (exp[i] == '(' || exp[i] == '[' || exp[i] == '{') 
     push(stack , exp[i]); 
     if (exp[i] == ')' || exp[i] == ']' || exp[i] == '}') 
     { 
     if (stack == NULL) 
      return 0; 
     else if (!isMatchingPair(pop(stack), exp[i])) 
      return 0; 

     } 
    } 
} 

int main() 
{ 
    char exp[100] = "{()}[)"; 
    printf(" %d\n", paranthesesMatch(exp)); 
    if (paranthesesMatch(exp) == 1) 
    printf("Balanced \n"); 
    else 
    printf("Not Balanced \n"); 
    return 0; 
} 

Edit: Добавлен полный код.

+0

С помощью сбалансированного выражения вы имели в виду, что все открытые фигурные скобки закрыты? – sjsam

+0

@sjsam: Да. Это то, что я имел в виду. – sank

+0

Это может вернуть 0, а не 1. Я в недоумении. – user902384

ответ

2

почему ниже функция возвращает 1 в случае сбалансированного выражения, когда это нигде не указано, для возврата 1.

Вашей функции имеет филиалы кода, которые не возвращают значение вообще. В частности, когда цикл достигает конца, ваша функция не указывает, что возвращать. В таких ситуациях, как использование возвращаемого значения функции - это неопределенное поведение: независимо от того, какая функция появляется для «возврата», это значение остаточного нежелательного содержимого, которое может отличаться на разных компьютерах или даже на том же компьютере, когда вы запускаете программу несколько раз.

Что касается самой функции, проверка на стек может быть ошибочной, если код не удаляет stack, когда он пуст (что было бы довольно плохим решением). Кроме того, код имеет утечку памяти, потому что stack никогда не освобождается. Кроме того, чрезмерно выделяет stack->array содержания на коэффициенте sizeof(int) (4 на многих компьютерах в эти дни):

stack->array = (char*) malloc(stack->capacity * sizeof(int)); 

должен быть

stack->array = malloc(stack->capacity); 

потому что вы делаете стек char с, а не стопкой int s.

И, наконец, нет необходимости выделять stack динамически. Выделите массив из char s и сделайте указатель стека или индекс стека, чтобы указать в начале вашего стека. Увеличивайте и уменьшайте указатель/индекс, когда вы нажимаете/поместите элементы в стек. Если вы используете массив переменной длины, вам не нужно будет очищать динамически выделенную память.

+0

.: Ooops..извините ... да точно. – coderredoc

+0

Привет, NULL проверяет наличие стека, чтобы проверить, есть ли какие-либо открывающие скобки, ранее введенные в стек. Должен быть открывающий кронштейн, вставляемый в стек для каждого закрывающего кронштейна в выражении. – sank

+0

@sank Затем это должен быть вызов 'isEmpty (stack)', а не 'stack == NULL'. – dasblinkenlight

5

Ваша функция, возвращающая 1, является результатом неопределенного поведения. Компилятор может делать все, что пожелает, потому что не все пути выполнения в вашей функции дают оператор return.

Причина в том, что может работать, так как вызывающий объект (который не знает, что функция завершена без оператора возврата) пытается получить доступ к возвращенному значению (которое может находиться в назначенном регистре). И ваша функция изменяет указанный регистр перед возвратом к вызывающему.

Набив ваши уровни предупреждения при строительстве, произведет диагностику (like so). Вы должны подумать об этом конкретном предупреждении об ошибке, так как отказ от оператора return может привести к зловещему и трудно найти ошибки.

0

А как ссылка на это помните это. Вытекание конца функции аналогично возврату без выражения. В любом из этих случаев возвращаемое значение не определено.

Смежные вопросы