一个无用的语句如何影响这个C程序?

一个无用的语句如何影响这个C程序?,c,recursion,C,Recursion,我编写了下面的C程序,使用递归查找给定数组的最大数。该程序输出正确。但是有一行代码(intx=1;) 它在程序中没有作用,但是如果我删除它,这个程序启动时会给出错误的输出。我不明白为什么?请解释一下 #include<stdio.h> int largestElement(int ar[], int length,int i,int lar) { int largest, j; j=i; largest=lar; if(j

我编写了下面的C程序,使用递归查找给定数组的最大数。该程序输出正确。但是有一行代码(intx=1;) 它在程序中没有作用,但是如果我删除它,这个程序启动时会给出错误的输出。我不明白为什么?请解释一下

   #include<stdio.h>

  int largestElement(int ar[], int length,int i,int lar)
  {
      int largest, j;
      j=i;
      largest=lar;

    if(j<length)
    {


        if(ar[j]>ar[j+1])
        {

        ar[j+1]=ar[j];
        }

        largest=ar[j+1];
        largestElement(ar,length,i+1,largest);

        return largest;
    }

   printf("\nlargest number of array = %d ",largest);

    }

   int main()
  {
   int a[10]={2,22,87,1,9,99,11,90,1,0};// Given an array of 10 elements
   int x=1; //If I remove this statement the output is some random number
            //but if I keep this line I get correct output, despite the fact 
            // that x is of no use in this program.
   largestElement(a,10,0,0);
   return 0;
  }
#包括
int-largestedelement(int-ar[],int-length,int-i,int-lar)
{
int,j,;
j=i;
最大=lar;
if(jar[j+1])
{
ar[j+1]=ar[j];
}
最大值=ar[j+1];
最大元素(ar,长度,i+1,最大);
回报最大;
}
printf(“\n数组的最大数目=%d”,最大);
}
int main()
{
int a[10]={2,22,87,1,9,99,11,90,1,0};//给定一个由10个元素组成的数组
int x=1;//如果删除此语句,则输出为某个随机数
//但如果我保持这条线,我会得到正确的输出,尽管事实如此
//x在这个程序中没有用。
最大元素(a,10,0,0);
返回0;
}

如上所述,您的
最大元素
函数的问题是您在条件
if(ar[j]>ar[j+1])
中调用未定义的行为,然后在赋值中再次调用
ar[j+1]=ar[j]
j=9
时,因为您试图访问超出数组末尾的内存。这会在代码中调用未定义的行为,从而导致它提供所需的结果或
SEGFAULT
或介于两者之间的任何内容

当您声明一个额外的整数int
x=1时,它的行为是正确的跟随您的数组,只是实现定义行为的一个副作用,其中额外的整数
x
紧跟在数组之后,提供至少一个额外定义的整数存储位,使您免于立即出错。由于您是通过交换元素来分配最大值的,因此最大值很可能最终出现在
x
中,这就是为什么删除它会更改输出的原因但这些都不是定义的行为,因此无法保证

如果您想递归地找到最大的数字,那么根本不交换元素,只需返回最大的。简单地说:

#include <stdio.h>
#include <limits.h> /* for INT_MIN */

int largestElement (int *ar, int length, int idx, int largest)
{
    if (idx == length)      /* recursion exit condition */
        return largest;

    if (ar[idx] > largest)  /* largest test */
        largest = ar[idx];

    /* recursive call */
    return largestElement (ar, length, idx + 1, largest);
}

int main (void) {

    int a[10] = {2, 22, 87, 1, 9, 99, 11, 90, 1, 0},
    largest = largestElement (a, 10, 0, INT_MIN);

    printf("\nlargest number of array = %d\n", largest);

    return 0;
}
注意:一开始不需要使用递归方法,如果过程解决方案可用,则不鼓励使用递归。为什么?每个递归调用都是一个单独的函数调用,系统必须为每个递归调用创建一个完整的函数堆栈。现在对于一个10个元素的数组来说,这是无关紧要的,但是对于百万个元素或更多的数组来说,它加起来很快。一个简单的程序实现看起来像:

#include <stdio.h>
#include <limits.h>

int largestElement (int *ar, int length)
{
    int largest = INT_MIN;

    while (length--)
        if (ar[length] > largest)
            largest = ar[length];

    return largest;
}

int main()
{
    int a[10] = {2, 22, 87, 1, 9, 99, 11, 90, 1, 0},
    largest = largestElement (a, 10);

    printf("\nlargest number of array = %d\n", largest);

    return 0;
}
#包括
#包括
int最大元素(int*ar,int长度)
{
int最大=int_最小;
while(长度--)
如果(ar[长度]>最大值)
最大=ar[长度];
回报最大;
}
int main()
{
INTA[10]={2,22,87,1,9,99,11,90,1,0},
最大=最大元素(a,10);
printf(“\n最大数组数=%d\n”,最大);
返回0;
}

仔细检查一下,如果您还有任何问题,请告诉我。

j=9
什么是
ar[j+1]
?(提示:未定义的行为)当您尝试访问
ar[j+1]
时,看起来您正在超越数组,并且您的编译器正在将
x
值放在
a
的最后一个元素之后,该元素的行为类似于哨兵。您为什么要使用递归?这个问题有一个简单的程序解决方案,不需要创建多个函数堆栈。这个程序很棒,但是你能告诉我为什么在这个程序中使用INT_MIN吗?我试图通过printf(“%d”,INT_MIN)来查看它的值;我得到了一些随机值-21473637388。当然,当你在寻找一个最大值时。您总是从范围内的最小数字开始。否则,如果您的值都是,您将得到错误的答案,例如
-1891255,-21976282,-1956385
。换句话说,如果您需要查找最大值的所有数字都小于您初始化最大值的值(例如
max=0;
),则您的答案将保持
0
,并且永远不会反映
-1891255,
的真正最大值。最小值也是如此。如果您正在查找最小整数,请初始化
int min=int\u max;
#include <stdio.h>
#include <limits.h>

int largestElement (int *ar, int length)
{
    int largest = INT_MIN;

    while (length--)
        if (ar[length] > largest)
            largest = ar[length];

    return largest;
}

int main()
{
    int a[10] = {2, 22, 87, 1, 9, 99, 11, 90, 1, 0},
    largest = largestElement (a, 10);

    printf("\nlargest number of array = %d\n", largest);

    return 0;
}