2017-05-30 8 views
0

乱数で配列を生成し、配列メンバーを最後から最初にキューに追加する必要があります。私は関数dodajURed()を使用してキューに個々の番号を追加し、poljeURed()を使用して配列メンバーをキューに追加します。アレイからキューへの再帰的な追加中にプログラムがクラッシュするのはなぜですか?

ラベルは英語ではないので、ここではクイックリファレンスガイドだ:

cvor =ノード

赤=キュー

ulaz =フロント

izlaz =リア

novi = new

メインプログラムでは、ランダムに生成された数値で配列を塗りつぶし、配列を印刷してpoljeURed()関数を呼び出します。

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

typedef struct cvor { 
    int element; 
    struct cvor *sljed; 
} cvor; 

typedef struct { 
    cvor *ulaz, *izlaz; 
} Red; 

void init_red(Red *red) { 
    red->ulaz = NULL; 
    red->izlaz = NULL; 
} 

int dodajURed(double broj, Red *red) { 
    cvor *novi; 
    if (!(novi=malloc(sizeof(cvor)))) return 0; 
    novi->element = broj; 
    if (!(red->izlaz)) red->izlaz = novi; 
    else (red->ulaz)->sljed = novi; 
    novi = red->ulaz; 
    return 1; 
} 

int poljeURed(int polje[], int n, Red *red) { 
    if (n<=0) return 1; 
    if (!(dodajURed(polje[n-1], red))) return 0; 
    else { 
     printf("Dodan u red: %d\n", polje[n-1]); 
     return poljeURed(polje, n-1, red); 
    } 
} 

int main(void) { 
    int i, polje[10]; 
    int broj; 
    Red red; 
    srand((unsigned)time(NULL)); 
    init_red(&red); 
    for(i=0; i<10; i++) { 
     broj = rand() % 11; 
     polje[i]=broj; 
    } 

    printf("Polje: "); 
    for(i=0; i<10; i++) { 
     printf("%d ", polje[i]); 
    } 
    printf("\n"); 

    if (poljeURed(polje, 10, &red)) printf("Dodavanje uspjesno"); 
    else printf("Dodavanje prekinuto"); 

    return 0; 
} 

さて、プログラムが正常に乱数で配列を埋め、poljeURed()を呼び出します。最初の呼び出しは成功し、配列の最後のメンバーがキューに追加されます。しかし、プログラムは2回目の呼び出し(再帰)でクラッシュします。私は何かが私の再帰で間違っていると思うが、私は正確に何が間違っているかに私の指を置くことはできません。このプログラムは、cmdのGCCとうまくコンパイルされます。

int poljeURed(int polje[], int n, Red *red) { 
    if (n<=0) return 1; 
    if (!(dodajURed(polje[n-1], red))) return 0; 
    else { 
     printf("Dodan u red: %d\n", polje[n-1]); 
     return poljeURed(polje, n-1, red); 
    } 
} 
+0

のようになります。その結果、それはコードに直接翻訳を置くように頼むには余りにも多くのだろうか?正確なコードを投稿する必要はありません。予期しない動作を最小限に抑えるだけです。 –

+0

私はちょっと急いでいますが、私が管理すれば挑戦します。私は文脈のためにすべてのコードを置く。私が言ったように、私は問題が私の反復的な機能にあると思う。 – scriptybusiness

答えて

1

問題は再帰関数にはありません。

else(red->ulaz)->sljed = novi; 

問題は、あなたの(init_redに)NULLで満たされている「ulaz」フィールドにアクセスしようとしている。いくつかの簡単なデバッグテスト(のprintfの)で、私はこの問題は、この行である判明しました。

if((red->ulaz)!=NULL) 
    (red->ulaz)->sljed = novi; 

それとも、「ulaz」の値を挿入不足している: は、だから、「ulazがNULLであるかどうかを確認するのいずれかが必要です。

他に必要な場合は、お尋ねください。

+0

ありがとう、これは働いた。私は元の形式の関数が別のプログラムで働いていた(キューを使って作業していましたが、入力はrandの代わりにキーボードを使用していました)ので、ちょっと困惑しています。私はそれをよく見ていきます。 – scriptybusiness

+1

この 'if((red-> ulaz)!= NULL)(red-> ulaz) - > sljed = novi;'はまったく読めません。これはコメントでは改行ができないので、 '' if((red-> ulaz)!= NULL)\ n(red-> ulaz) - > sljed = novi; '(\ nは改行を意味します。) –

+0

@ MichaelWalzすべてのコードは実際には読めません(変数名は見たことがありますか?)。とにかく、私はそれを読みやすくするために編集しました。 (編集依頼をしたこともあります)。 –

0

初心者の方は、英語の単語と、プログラムの識別子として使用される母国語の単語を混ぜてはいけません。これにより、コードが完全に不明瞭になります。英単語のみを識別子として使用します。

機能dodajURedが間違っています。

ポインタnoviが指す割り当てオブジェクトのデータメンバsljedはNULLに設定されていません。

だから、あなたはデータメンバーizlazulazに両者が新しく割り当てられたオブジェクトをポイントするように設定する必要があるキューが空の場合は、次のステートメント

int dodajURed(double broj, Red *red) { 
    cvor *novi; 
    if (!(novi=malloc(sizeof(cvor)))) return 0; 
    novi->element = broj; 
    novi->sljed = NULL; 
    //... 

を追加する必要があります。

また、この文

novi = red->ulaz; 

意味がありません。

データメンバーelementは、タイプがintであるが、タイプdoubleのキュー値を追加しようとしていることを考慮してください。

機能が

int dodajURed(int broj, Red *red) 
{ 
    cvor *novi; 

    if (!(novi=malloc(sizeof(cvor)))) return 0; 

    novi->element = broj; 
    novi->sljed = NULL; 

    if (!red->izlaz) 
    { 
     red->izlaz = red->ulaz = novi; 
    } 
    else 
    { 
     red->ulaz = red->ulaz->sljed = novi; 
    } 

    return 1; 
} 
関連する問題