2016-11-18 4 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

入れ子関数とは何ですか? 'push()'関数は 'main()'の外で定義しなければなりません。あなたがCを学んでいるならば(そしておそらくCを学んだ後であってもおそらく使用していないかもしれないが)、弛緩モードのGCCだけが入れ子関数を許可します。 –

答えて

1

ある方法を知って、あなたがやったすべては、そのポインタを作成しています何かを指すが、おそらくstack_tではない。を指すように何かを割り当てる必要があります。 mallocを参照してください。次に、stack_t::topを-1などの値に初期化する必要があります。そのインデックスはスタックの最初のアイテムになる可能性が高いので、ゼロはおそらくここでは機能しません。

+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を宣言する、あなたのコードをJonathan Lefflerによってコメントとして、

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

ところで:(call stack上)、明示的に初期化し、それへのポインタを渡します標準Cではnested functionsが許可されていないため、標準C99またはC11ではありません。GCC extensionを(おそらく間違って)使用しています。 mainの外に(そして前に)push関数を定義する必要があります。効率を気にしている場合は、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ポインターを使用すると、topsizeの両方をstack_tのフィールドとして保持し、data[]を(最後の)flexible array memberと考えることができます。その場合、pushはおそらく(おそらくは更新された)ポインタを返すでしょう。 GCCを使用している場合は、いくつかの を持っている場合は、読み(

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

ところで、できるだけ早くあなたがmallocのようないくつかのヒープ割り当てを使用しているとして、あなたは常には非常に少なくともとして、失敗を処理する必要がありますそのcommand options(その順序は重要です)。gcc -std=c99 -Wall -Wextra -g(元のコードでは、いくつかの有用な診断が必要です)でコンパイルし、警告が出なくなるまでコードを改善してから、gdbデバッガを使用することをお勧めします。

関連する問題