2016-11-18 7 views
0

Я пытаюсь создать стек, где я могу вставить в него целые числа. До сих пор у меня есть следующее:Как создать пустой стек?

#include <stdio.h> 
#define N 20 

typedef struct { 
    int data[N]; // array of at most size N 
    // N should be a constant declared globally 
    int top; 
} stack_t; 

void push(stack_t *stack, int element); 


int main(){ 

void push(stack_t *stack, int n) { 
    if (stack->top == N - 1) { 
     printf("Warning: Stack is full, You can't add'\n"); 
     return; 
    } else { 
     stack->data[++stack->top] = n; 
    } 
    } 


    stack_t * e_stack; // Empty stack created 
    push(e_stack, 2); 


} 

Однако этот код дает ошибку времени выполнения. Я предполагаю, что это потому, что эта часть неверна: stack_t * e_stack; // Пустой стек создан

(Это, вероятно, не создать пустой стек)

Но я знаю, как это неправильно

+2

Что с вложенной функцией thingy? У вас должна быть функция 'push()', определенная вне 'main()'. Только GCC в вялом режиме допускает вложенные функции - они не переносятся и вообще злобны, и вы не должны их использовать, если вы изучаете C (и, вероятно, не используете даже после того, как вы научились C). –

ответ

1

Вы правы, все, что вы сделали, создали указатель, точки на ... что-то, но, вероятно, не stack_t. Вам нужно выделить что-то, на что нужно указать. См. malloc. Затем вам нужно будет инициализировать stack_t::top до -1 или какое-либо другое значение. Zero, вероятно, не будет работать здесь, поскольку этот индекс, вероятно, будет первым элементом в стеке.

+1

Указатель стека должен быть следующей записью для использования; он должен располагаться над значениями 0 (пустой) до N (без пробела). Он также показывает, сколько записей находится в стеке. –

0

Вот пример, который я написал некоторое время назад. Он в основном подталкивает целые числа в стек и выдает последний добавленный элемент в стек. Обратите внимание, что появление предметов, вероятно, не самый лучший способ сделать это, есть, конечно, лучшие способы.

Пример кода:

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

#define N 20 

typedef struct { 
    int data[N]; //better to use a dynamic array instead here 
    int top; 
} stack_t; 

stack_t *create_empty_stack(void); 
void push(stack_t *stack, int value); 
int pop(stack_t *stack); 

int 
main(void) { 
    stack_t *stack; 
    stack = create_empty_stack(); 

    push(stack, 10); 
    push(stack, 20); 
    push(stack, 30); 

    printf("Popped: %d\n", pop(stack)); 
    printf("Popped: %d\n", pop(stack)); 
    printf("Popped: %d\n", pop(stack)); 
    printf("Popped: %d\n", pop(stack)); 

    free(stack); 

    return 0; 
} 

void 
push(stack_t *stack, int value) { 
    if (stack->top == N - 1) { 
     printf("Warning: Stack is full, You can't add'\n"); 
     return; 
    } else { 
     stack->data[stack->top] = value; 
     (stack->top)++; 
    } 
} 

int 
pop(stack_t *stack) { 
    if (stack->top > 0) { 
     (stack->top)--; 
     return stack->data[stack->top]; 
    } else { 
     //definetly better way to do this. I will let you decided how you want to implement this. 
     printf("Tried to pop empty stack!\n"); 
     exit(EXIT_FAILURE); 
    } 
} 

// Since you are using a fixed sized array, creating an empty stack in this case is easy. 
stack_t 
*create_empty_stack(void) { 
    stack_t *stack = malloc(sizeof(*stack)); 
    if (stack == NULL) { 
     printf("Cannot allocate stack\n"); 
     exit(EXIT_FAILURE); 
    } 
    stack->top = 0; 
    return stack; 
} 
0

Либо (как другие ответы предполагают) выделить зону памяти и получить указатель на stack_t в куче и инициализировать ее правильно (возможно, через в create_empty_stack функции) или объявить stack_tlocal variable (на call stack), инициализировать его в явном виде, и передать указатель на него:

stack_t locstack = {.data={}, .top=0}; 
push(&locstack, 2); 

BTW, так как прокомментировал Jonathan Leffler, код не является стандартом C99 или C11, потому что nested functions не разрешены в стандартном C. Вы (возможно, неправильно) используете GCC extension. Вы должны определить функцию push вне (и до) main. Если вы заботитесь об эффективности, определите его как static inline void push(stack_t *stack, int n) .... чтобы получить его inlined.

Обратите внимание, что если вы хотите принять сколь угодно размера стека, следует использовать некоторые flexible array member и вырастить их (раз в то время) по мере необходимости (думать о какой-то int newsize = 4*stack->size/3+2; когда стек становится полным, то
stack_t*newstack = malloc(sizeof(stack_t)+newsize*sizeof(int)); и т.д ....) и только использование heap allocated указатели, вы можете рассмотреть как top, так и size в качестве полей stack_t и имеют data[] в качестве своего последнего (последнего) flexible array member. В этом случае push, вероятно, вернет (возможно, обновленный) указатель.

BTW, как только вы используете некоторые выделения динамической памяти, как malloc, вы всегда должны справляться с неудачами, по крайней мере, как:

stack_t* pstack = malloc(sizeof(stack_t)); 
if (pstack==NULL) { perror("malloc"); exit(EXIT_FAILURE); }; 

(если у вас есть какое-то При использовании GCC, прочитайте подробнее о его command options (их порядок важен). Я рекомендую компиляцию с gcc -std=c99 -Wall -Wextra -g (на ваш исходный код, который должен дать некоторые полезные диагностические данные), улучшите свой код, пока не получите никаких предупреждений, а затем используйте отладчик gdb.

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