一个无用的语句如何影响这个C程序?
我编写了下面的C程序,使用递归查找给定数组的最大数。该程序输出正确。但是有一行代码(intx=1;) 它在程序中没有作用,但是如果我删除它,这个程序启动时会给出错误的输出。我不明白为什么?请解释一下一个无用的语句如何影响这个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
#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
或介于两者之间的任何内容
当您声明一个额外的整数intx=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;
}