/* Calculating minimum and maximum element out of a list of elements using Recursion
Input: A list of numbers
Output: Minimum and Maximum number
*/
#include<stdio.h>
int a[8]={6,2,3,9,1,0,11,8},size=8;
int * minmax(int beg,int end)
{
int res[2],*x,*y,mid;
printf("%d %d %p:",beg,end,res);
if(beg==end)
{
res[0]=a[beg];
res[1]=a[beg];
return res;
}
if(end-beg==1)
{
if(a[beg]<=a[end])
{
res[0]=a[beg];
res[1]=a[end];
}
else
{
res[0]=a[end];
res[1]=a[beg];
}
printf("%d %d",res[0],res[1]);
printf("\n");
return res;
}
printf("\n");
mid=(beg+end)/2;
x=minmax(beg,mid);
y=minmax(mid+1,end);
if(x[0]<=y[0])
res[0]=x[0];
else if(x[0]>y[0])
res[0]=y[0];
if(x[1]<=y[1])
res[1]=y[1];
else if(x[1]>y[1])
res[1]=x[1];
printf("OUT: %d %d %d %d WIN: %d %d\n",x[0],y[0],x[1],y[1],res[0],res[1]);
return res;
}
int main()
{
int i,j,min,max,*ans;
ans=minmax(0,size-1);
printf("Ans=%d %d",ans[0],ans[1]);
return 0;
}
在上面的代码中,使用递归获取最小和最大元素,数组res
在连续的递归调用中得到相同的地址,如下所示:
0 7 0xbfa9cb08:
0 3 0xbfa9cac8:
0 1 0xbfa9ca88:2 6
2 3 0xbfa9ca88:3 9
OUT: 3 3 9 9 WIN: 3 9
4 7 0xbfa9cac8:
4 5 0xbfa9ca88:0 1
6 7 0xbfa9ca88:8 11
OUT: 8 8 11 11 WIN: 8 11
OUT: 8 8 11 11 WIN: 8 11
Ans=8 11
在函数调用minmax(0,1)
和minmax(2,3)
res
获取相同的地址,这就是它产生问题的原因。在minmax(4,5)
和minmax(6,7)
为什么会发生这种情况,如何修改程序以获得最低和最高
答案 0 :(得分:3)
您无法返回自动变量的地址。正如WhozCraig所述,它是undefined behavior。顺便说一句,如果您启用所有警告和调试信息(例如,如果使用GCC,则使用gcc -Wall -Wextra -g
进行编译),您会收到警告。
您应该返回struct
两个数字,例如声明为
struct myminmax_st {
int mymin;
int mymax;
};
struct myminmax_st minmax(int *arr, int beg, int end);
struct myminmax_st
minmax(int *arr, int beg, int end)
{
struct myminmax_st res = { INT_MIN, INT_MAX };
if(beg==end) {
res.mymin = arr[beg];
res.mymax = arr[end];
return res;
}
我留给你完成那个例程。您需要#include <limits.h>
才能获得INT_MIN
&amp; INT_MAX
请注意,在Linux / x86-64上,ABI指定返回带有两个整数的struct
非常快:它们在两个寄存器中返回。 (这特定于具有两个标量字段的struct
。
您可以将生成的min和max的地址作为正式参数传递,如MiteshMS answer中所述(但在Linux / x86-64上可能会慢一点,因为这样你就可以通过内存)。 / p>
同样在C数组中衰减为指针,因此您无法返回数组(除非您将其打包在某些struct
中);你可以返回一个指向某个数组的指针(通常是heap-allocated和malloc
)。在这种情况下 - 作为指针返回的堆分配数组 - 您需要一些记录的约定关于谁负责free
-
答案 1 :(得分:1)
这是实现MaxMin算法的另一种方法,这里每次递归调用都会更新max和min变量。
这种方式使用数组或结构,类似于您最初编码的方式。
#include<stdio.h>
#include<stdlib.h>
void maxmin(int a[],int low,int high,int *min,int *max);
int a[8]={6,2,3,9,1,0,11,8}, n=8;
void main()
{
int i,low,high,max,min;
low=0;
high=n-1;
maxmin(a,low,high,&min,&max);
printf("Minimum value is %d\n",min);
printf("Maximum value is %d\n",max);
}
void maxmin(int a[],int low,int high,int *min,int *max)
{
int mid,min1,max1,min2,max2;
if(low==high)//For 1 element min and max will be same
{
*min=a[low];
*max=a[high];
}
else if(low==high-1)//For two elements
{
if(a[low]>a[high])
{
*max=a[low];
*min=a[high];
}
else
{
*max=a[high];
*min=a[low];
}
}
else//for more than 2 elements
{
mid=(low+high)/2;
maxmin(a,low,mid,&min1,&max1);//Dividing
maxmin(a,mid+1,high,&min2,&max2);
if(min1<min2)//Combining
*min=min1;
else
*min=min2;
if(max1>max2)
*max=max1;
else
*max=max2;
}
}
我尝试以不同方式声明res []来搞乱你的代码。将它声明为一个结构将像Basile在另一个答案中指出的那样工作,但你可以使用上面的代码来坚持直观的基本指针。
答案 2 :(得分:-2)
C不允许返回指向自动数组的指针,因为它在函数末尾超出范围并在使用之前被释放。
在这种情况下(递归),你也不能使用静态变量,因为所有堆叠的调用都会使用相同的变量。
所以,你只剩2路了:
让调用者分配数组并将其传递给被调用者:
void minmax(int beg,int end, int *res)
{
int x[2], y[2],mid;
...
mid=(beg+end)/2;
minmax(beg,mid, x);
minmax(mid+1,end, y);
...
printf("OUT: %d %d %d %d WIN: %d %d\n",x[0],y[0],x[1],y[1],res[0],res[1]);
}
int main()
{
int i,j,min,max;
int ans[2];
minmax(0,size-1, ans);
...
在callee中使用动态分配并传递动态分配数组的地址,但是必须在调用者中释放它
int* minmax(int beg,int end)
{
int *res, *x, *y,mid;
*res = calloc(2, sizeof(int));
...
mid=(beg+end)/2;
x = minmax(beg,mid);
y = minmax(mid+1,end);
...
printf("OUT: %d %d %d %d WIN: %d %d\n",x[0],y[0],x[1],y[1],res[0],res[1]);
free(x);
free(y);
return res;
}
int main()
{
int i,j,min,max;
int *ans;
ans=minmax(0,size-1, ans);
printf("Ans=%d %d",ans[0],ans[1]);
free(ans);
return 0;
}
但是我忘记了Basile Starynkevitch给出的第三种方法:使用结构,因为你可以返回一个自动结构。