2017-07-01 15 views
-3

C再帰関数エラー不正確な出力

私はスティーブ・アウアラインによる「実践Cプログラミング、第3版」 を勉強していますし、それが次の要件を持つプログラムを作るために、この割り当てが含まれています。

練習9-3:numberarrayに現れる回数の 数をカウント機能count(number, array, length)を書きます。配列にはlength要素があります。 関数は再帰的でなければなりません。この機能を使用するためのテストプログラムを作成します。

私はプログラムを15分でコーディングしましたが、私の出力はまさに私が望むものではありません。ここでは、コードがあります:プログラムは(論理的なものを除く)エラーなしでokです

#include <stdio.h> 

int length; 
int count(int num2count, int array[length], int size); 

int main(void) 
{ 
    char check; 
    int i = 0; 
    long int num_to_be_counted; 
    int ans; 
    printf("Please enter the length of array:"); 
    scanf("%d",&length); 
    long int numbers[length]; 

    for(int i = 0; i != length; ++i) { 
    numbers[i] = 0; 
    } 

    printf("Enter the array:"); 

    while(check != '\n') { 
    scanf("%li",&numbers[i]); 
    ++i; 
    check = getchar(); 
    } 

    printf("Enter the number to be counted in the array:"); 

    scanf("%d",&num_to_be_counted); 

    for(int i = 0; i != length; ++i) { 
    numbers[i] = 0; 
    } 

    ans = count(num_to_be_counted,numbers,length); 

    printf("The number appears %d times in the array.",ans); 

    return 0; 
} 


int count(int num2count, int array[length], int size) 
{ 
    static int times = 0; 
    static int i = 0; 

    if (array[i] == num2count) { 
    ++times; 
    } 

    if(i == size) { 
    return times; 
    } 

    while(i != length) { 
    ++i; 
    count(num2count,array,length); 
    } 
} 

、ここではサンプル入力と出力

length = 4 
numbers = 1 2 2 4 
number_to_count = 2 
Output: 4 

は機能もカウントされる数をカウントしていないのです。例えばこの場合は4の配列のサイズを返すだけです。

何か助けをいただければ幸いです。

+0

ヒント:グローバル変数または 'static'変数を使用しないでください。 – melpomene

+0

@メルポメン精緻化してください? – Muneeb

+1

なぜあなたはそれらをユーザーから受け入れた後、配列のすべての値を '0'に再割り当てしますか? – GoodDeeds

答えて

0

ここには多くの問題があります。

まず第一に、これははるかに複雑である必要があります。すべてが必要ではないstaticを使用しました。

複数回計算したため、答えが間違っています。

このようにする必要があります。このコードを理解しようとすることができます。

int count(int num2count, int array[], int size) 
{ 
    if(size<= 0) return 0; 
    return (array[size-1]==num2count)+count(num2count,array,size-1); 
} 

または

int count(int num2count, int array[], int size) 
{ 
    if(size<= 0) return 0; 
    return (array[0]==num2count)+count(num2count,array+1,size-1); 
} 

なぜ私は再帰でstaticを使うべきではないのですか?それは何も間違っていませんが、何千ものコード行と多くの機能を持っているときに問題になるため、悪い設計です。どの変数が問題を引き起こしたのかを追跡したり、デバッグするのは面倒です。

あなたの問題

int count(int num2count, int array[length], int size) 
{ 
    static int times = 0; // bad design and unnecessary. 
    static int i = 0; 

    if (array[i] == num2count) 
    { 
    ++times; 
    } 



    if(i == size) 
    { 
    return times; 
    } 
    while(i < length) <----check 
    { 
    ++i; 
    count(num2count,array,length); 
    } 

} 

はまたcount()は、任意の値を返さないので、変数に格納していない使用。

私はちょうどいくつかの問題とその問題のきれいな解決策を述べました。詳細な説明についてはメルポメンヌの答えを参照してください。

+0

@melpomene .:申し訳ありませんでした。指してくれてありがとう。 – coderredoc

+0

@coderredocなぜ静的変数を使用していないのですか?静的変数が使用されていない場合に関数が再帰的に呼び出されると、変数は次の段階でどのように値を保持しますか? – Muneeb

+0

@melpomene:ご確認ください。 – coderredoc

0
  1. 配列の値を関数に渡す前にリセットしないでください。
  2. whileループのカウントは意味をなさないが、動作の仕方を再考したり、再帰呼び出しを出力したりすることができます。また、何も返されない場合もあります。
  3. コメントで既に述べたように、配列要素にアクセスする前に範囲外であることを確認してください。あなたのコード内
+0

ありがとうございます。 :) – Muneeb

2

問題:

  • あなたのコードはそれで何かを行う前に0に入力配列をリセットします。

  • countarray[i]にアクセスします。つまり、範囲外のアクセス権があります。

  • countへの再帰呼び出しは、ループでラップされます。 countのネストされた呼び出しがループするので、意味がありません(そして、各繰り返しで再びループします... count)。

  • countのすべてのローカル変数は、staticです。つまり、この関数は役に立たなくなります。どのプログラムでも2回以上呼び出すことはできません。

    • int i;があなたのmain()機能が未使用である:

      for (int i = 0; i < length; i++) { 
          printf("%d appears %d times in the array\n", numbers[i], count(numbers[i], numbers, length)); 
      } 
      

    その他の問題:これを実証するためのより良いテストプログラムは、何かのようになります。

  • checkは、初めて確認するときに初期化されません。
  • getchar()の結果をcharに割り当てることは一般的には悪い考えです。 getchar()は、理由のためにintを返します。
  • プログラムに型エラーがあります:numberslong intの配列として宣言されていますが、配列はintの配列に渡しています。
  • system()の場合は#include <stdlib.h>が見つかりません。
+1

私はそれを使わずにシステムにアクセスできるときにstdlibをインクルードする必要があるのはなぜですか? – Muneeb

+0

@Muneeb ' 'を含むことは' system'の宣言を提供します。これは、間違った引数でコンパイラを呼び出すと警告を出すことができます。スコープ内に宣言がなければ、 'system(" ... ")'は動作します( 'system'は' int'を返すため)。しかし、コンパイラは 'system(1,2,3)'引数の数、間違った型)。そのようなことは、通常は実行時にクラッシュする(またはゴミの結果)。 – melpomene

+1

なぜ、私はコーディング中に多くのことを見なければならないのですか?私はもしあなたが1つのことを尋ねたかったのですが? – Muneeb

関連する問題