0

再帰を使用して配列の要素を見つけたいです。関数は配列とターゲット値を取ります。再帰関数は、指定された配列の要素であるかどうかをチェックします。しかし残念ながら、このコードを設定することはできません。関数は常に '1' を返します。どこで間違えますか?

#include <stdio.h>

int isElement(int *a, int target) ;

int main()
{

  int a[] = {3,5,6,4,2,32,15} ;
  int target = 12 ,res  ;


  res = isElement( a, target) ;

  if(res==1)
    printf("its an element of the array\n");

  if(res==0) 
    printf("its not an element of the array\n");

  return 0 ;
}


int isElement(int *a, int target)
{
  int son=0  ;


  printf("array = %d\n",a[0] );

  if(a[1] == '\0')
      son = 0 ;

  else if(target == a[0])
    son = 1 ; 

  else
    son = isElement(&a[1] ,target);

  return son ;

}
4

4 に答える 4

3

a は文字列ではないため、ヌル ターミネータ ('\0') はありません。配列の長さを渡す必要があります。そうしないと、この関数は (それが見つかるまで) メモリ内で永久に継続します。

于 2012-08-07T12:42:54.407 に答える
0

あなたの終了条件はいつa[1] == '\0'です。ただし、配列は 0 で終了しません。したがって、スタックの残りの部分でtarget 、配列の境界の外を検索しています。これは未定義の動作であるため、何かが起こる可能性があります (文句を言うことはできません)。ただし、特定のケースでは、 がスタックのtarget後に配置されるため、 を終了すると、探していたのと同じ値が表示されるため、常に 1 が返されます。aa

あなたがすべきことは、の定義を次のように変更することですa:

int a[] = {3,5,6,4,2,32,15, 0} ;
                           ^^^

また、条件:

if(a[1] == '\0')
      son = 0 ;

このような例では、間違った結果が得られます。

int a[] = {12, 0};
int target = 12;

をチェックする前にa[0] == target、このケースを不合格としてマークするためです。したがって、条件を次のように変更する必要があります。

     vvv
if (a[0] == 0)
    son = 0;
于 2012-08-07T12:43:37.983 に答える
0

「a」はヌルで終了する文字列ではないため、このテストは次のとおりです。

if(a[1] == '\0')
  son = 0 ;

間違っている。

関数は、未定義の動作を呼び出す配列の末尾を超えて読み取り続けるため、1 を返します。別のコンピューターでコンパイルして実行すると、関数は0を返します。私のマシンでは、プログラムは12を見つけません。しかし、あなたのマシンでは動作が異なります。これは未定義の動作の結果です。

于 2012-08-07T12:43:53.610 に答える
0

間違った行:

  if(a[1] == '\0')
      son = 0 ;

int a[] はシンボル '\0' で終わっていないため、コードは不正なメモリにアクセスします。

int a[] の場合、関数の場合は次のように定義する必要があります。

int isElement(int *a, int arraylength, int target) ;

すべての再帰ループで、arraylength -1。

終了した比較は次のようになります。

if(arraylength == 1 && a[0] != target)
son = 0;
于 2012-08-07T12:50:47.620 に答える