How to pass parameters by reference in recursive algorithms in c? - c

algorithm that given an array delivers the largest number by recursion, but passing the result by reference.
tam: size of array
first I realized it by value and it worked for me but I need to pass it by reference the result, I really do not know what the error could be, if you can guide me please, since when compiling it, I did not return anything
#include <stdio.h>
#include <stdlib.h>
void search(int a[], int tam, int max,int *result);
int main()
{
int max,tam=5, result;
int array[5]={3,1,5,8,6};
max=array[0];
search(array, tam, max, &result);
printf("the biggest number is: %d",result);
return 0;
}
void search(int a[], int tam, int max, int *result )
{
if(tam==1)
*result=max;
if(max<a[tam-1])
max=a[tam-1];
search(a,tam-1,max,result);
}
Blockquote

When compiling with 'clang -Wall', you get the following warning:
warning: all paths through this function will call itself [-Winfinite-recursion]
Indeed, in you don't have an effective base case and inductive step in your function.
I would suggest converting to the following:
#define MAX(x, y) ((x) > (y)) ? x : y
int search(int a[], int tam )
{
// base case if last element
if (tam == 1) return a[0];
// inductive case (max of this and following elements)
return MAX(a[0], search(a + 1, tam - 1));
}

Since the OP's code attempts to be tail recursive, and #Gill Bates 's answer is head recursive, I am showing a tail recursive solution.
int find_max_helper(const int *a, int n, int max)
{
if (n==0) return max;
else return find_max_helper(a+1, n-1, MAX(max, a[0]));
}
//returns the maximum value in the array of size n elements
//or 0 if the array is empty
int find_max(const int *a, int n)
{
return n > 0 ? find_max_helper(a+1, n-1, a[0]) : 0;
}

Related

After a pointer Returns from a function i cant print it

I am relatively new to C. My program is supposed to fill in the array with random numbers and i have to find the max and min using 1 function. The program works fine up until the point i have to return the values my 2 pointers get from the function. When i go to print them the porgram stop working and exits with the return value of 3221225477. I have been trying to fix this for 3 hours and i am going INSANE. Please help in any way you can i would really apreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void MaxMin(int size, int *B, int *Max, int *Min);
int main(int argc, char *argv[])
{
int N, i,*A,*MAX,*MIN;
srand(time(NULL));
/*Making sure the user enters a proper value for the array*/
do
{
printf("Give the number of spaces in the Array\n");
scanf("%d",&N);
}
while(N<1);
A = (int *) malloc(N*(sizeof(N)));
/*Giving random numbers to the array and printing them so i can make sure my code is finding the max min*/
for(i=0;i<N;i++)
{
A[i]=rand()%100;
printf("\n%d\n",A[i]);
}
/*Calling my void function so that the pointers MAX and MIN have a value assigned to them */
MaxMin(N, A, MAX, MIN);
/*Printing them*/
printf("\nMax = %d\nMin = %d",*MAX,*MIN);
free(A);
return 0;
}
/*The function*/
void MaxMin(int size, int *B, int *Max, int *Min)
{
/*using 2 temporary ints to get max min cause pointers and arrays confuse me*/
int max=B[0],min=B[0],i;
for(i=1;i<size;i++)
{
if(max<B[i])
{
max = B[i];
}
if(min>B[i])
{
min = B[i];
}
}
/*These have the proper value last i chekced */
Max = &max;
Min = &min;
}
(edit) SOLUTION Ty so much for the help !
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void MaxMin(int size, int *B, int *Max, int *Min);
int main(int argc, char *argv[])
{
int N, i,*A,MAX ,MIN ;
srand(time(NULL));
/*Making sure the user enters a proper value for the array*/
do
{
printf("Give the number of spaces in the Array\n");
scanf("%d",&N);
}
while(N<1);
A = (int *) malloc(N*(sizeof(int)));
/*Giving random numbers to the array and printing them so i can make sure my code is finding the max min*/
for(i=0;i<N;i++)
{
A[i]=rand()%100;
printf("\n%d\n",A[i]);
}
/*Calling my void function so that the pointers MAX and MIN have a value assigned to them */
MaxMin(N, A, &MAX, &MIN);
/*Printing them*/
printf("\nMax = %d\nMin = %d",MAX,MIN);
free(A);
return 0;
}
/*The function*/
void MaxMin(int size, int *B, int *Max, int *Min)
{
*Max=B[0];
*Min=B[0];
int i;
for(i=1;i<size;i++)
{
if(*Max<B[i])
{
*Max = B[i];
}
if(*Min>B[i])
{
*Min = B[i];
}
}
}
You passed to the function MaxMin pointers MAX and MIN by value. That is the function deals with copies of (indeterminate) values of the passed pointers. Changing the copies does not influence on the original arguments.
Within main you should declare MIN and MAX as objects of the type int.
int N, i,*A, MAX, MIN;
and call the function ,like
MaxMin(N, A, &MAX, &MIN);
Within the function you should write
*Max = &max;
*Min = &min;
And at last in main you should call printf like
printf("\nMax = %d\nMin = %d", MAX, MIN);
Pay attention to that the expression sizeof( N ) used in this statement
A = (int *) malloc(N*(sizeof(N)));
is error prone. The type of the variable N can be changed for example from the type int to the type size_t. In this case the size of the allocated memory will be incorrect, You should write for example
A = (int *) malloc(N*(sizeof( *A )));
You have three bugs:
In main, you don't assign MAX or MIN any values. So you pass garbage to MaxMin.
In MaxMin, Max and Min are about to go out of scope. Changing their values before they go out of scope has no effect on anything.
In main, you don't create any place to hold the maximum and minimum values. So where are you expecting them to be stored?

Error when compiling : incompatible types and similar warnings ( picture attached )

I'm writing a function that returns the inverse of an array using recursivity but I keep getting these warnings :
Here is my code
#include <stdio.h>
#include <stdlib.h>
int inv( float* t[],int n)
{ float u;
if (n==0) return 0;
else
{
u=*t;
*t=*(t+n);
*(t+n)=u;
return(inv(*(t+1),n-1));
}
}
int main()
{
float t[]={1,2,3,4,5,6,7,8,9};
int n=sizeof t /sizeof *t;
int i=0;
inv(t,n);
for(i=0;i<n;i++)printf("%f",t[i]);
return 0;
}
int inv( float* t[],int n)
Here, float* t[] declares an array of pointers. Please note that *t[i] = *(*(t+i))
For i = 0, *(*(t+i)) = *(*(t)) = *(*t).
Here, *t is of type float*, and u is of type float.
Using the expression u=*t; gives you that error (assigning float* value to float)
Solution : Change int inv( float* t[],int n) to int inv( float t[],int n)
I use a procedure to arrange the array elements in descending order
#include <stdio.h>
#include <stdlib.h>
void revs(int i, int n, float *arr)
{
if(i==n)
{
return ;
}
else
{
revs(i+1, n, arr);
printf("%.f ", arr[i]);
}
return 0;
}
int main()
{
float t[]={1,2,3,4,5,6,7,8,9};
int n=sizeof t /sizeof t[0];
int i=0;
revs(0,n,t);
}
It looks like the intended action of OP's function inv is to reverse the elements of an array of n float values in place, using recursion.
In the original inv code, the parameter declaration float* t[] will be adjusted to be equivalent to float** t by the compiler. This needs to be changed to float t[] or equivalently float* t.
In the original inv code, the return value is either 0 or the result of the recursive call to itself, which can only be 0. Therefore the return value is of no use. It would be better to change the return type of the function to void.
In the inv function, the parameter n is set to the length of the array in the initial call from main. The function swaps the values of elements at indices 0 and n before recursing, but there is no element at index n. The last element has index n-1. The function should swap the elements at indices 0 and n-1 before recursing. After swapping the first and last elements, the remaining n-2 elements with indices from 1 to n-2 can be swapped by a recursive call. The original inv code uses the value n-1 in the recursive call, but it should be n-2.
If n is less than 2, the inv function does not need to do anything.
A possible implementation of inv based on OP's original code follows:
void inv(float* t,int n)
{
float u;
if (n>=2)
{
u=*t;
*t=*(t+n-1);
*(t+n-1)=u;
inv(t+1,n-2));
}
}
The same function can be written using array subscripting operators as follows:
void inv(float t[],int n)
{
float u;
if (n>=2)
{
u=t[0];
t[0]=t[n-1];
t[n-1]=u;
inv(&t[1],n-2));
}
}

The sum in C with recursion

I'm trying to do a program that will do a sum for an array. If i put a printf in the function, it returns right, but at the final the result is incorrect. Why?
#include <stdio.h>
int summ(int a[100],int n)
{
static int sum=0;
static int i=0;
if(i<n)
{
sum+=a[i];
++i;
return (summ(a,n)+sum);
}
}
int main()
{
int b[100];
int n,i,suma;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
suma=summ(b,n);
printf("Suma=%d",suma);
return 0;
}
Compiling your code with warnings enabled should yield the following output:
program.c:13:1: warning: control may reach end of non-void function [-Wreturn-type]
This means that your summ function lacks a base case - i.e. it does not specify what should be returned once n is reached.
Once you fix this problem, your code starts returning the correct value. However, your function would still need some fixing, because you should not be using static variables in it. Any static variable in a function makes the function non-reentrant, which is very bad. In particular, your function can be run only once; second invocation would yield an error, because neither i nor sum could be reset.
Here is a simple recursive implementation of what you are looking to build:
int summ_impl(int a[], size_t i, size_t n) {
return i != n ? a[i] + summ_impl(a, i+1, n) : 0;
}
int sum(int a[], size_t n) {
return summ_impl(a, 0, n);
}
With recursion:
int summ(int *a, int n) {
if (n-- > 0)//the n is equal to n-1 after check condition
return (summ(a,n) + a[n]);//return the n-1 sum (recursion) + current value
return (0);
}
This way, the function will call itself while it not equal to zero (so between n and 0)
So we got:
a = [1,2,3]
the function will return
3 + sum before
-> 2 + sum before
-> 1 + sum before
-> 0
When the function go back in the stack
0 + 1 + 2 + 3 -> 6

hello this program for calculate min and max in the array

I wrote the code with functions and it give me the address of the variable not the value in which the solution is in the same way of coding.
this is the output
and this is my code
#include <stdio.h>
int maxi(int feld[],int size);
int mini(int feld[],int size);
int main(void){
int feld[]={33,36,31,38,45,42,11,29,56,54};
int len;
int min,max;
len=sizeof(feld)/sizeof(int);
printf("Lange des Datenfeldes=%i\n",len);
max=maxi(feld,len);
min=mini(feld,len);
printf("Minimum = %i\tMaximum = %i\n",min,max);
return 0;
}
int maxi(int feld[],int len){
int i,max;
for(i=0;i<len;i++){
if(feld[i]<max){
feld[i]=max;
}
}
return max;
}
int mini(int feld[],int len){
int i,min;
for(i=0;i<len;i++){
if(feld[i]>min){
feld[i]=min;
}
}
return min;
}
You need to give a starting value to max and min in the functions.
A good choice would be max = INT_MIN; and min = INT_MAX;. Also, add #include <limits.h> in your includes since the INT_MAX and INT_MIN are defined in it.
int maxi(int feld[],int len){
int i;
int max = INT_MIN;
for(i=0;i<len;i++){
if(feld[i]<max){
max=feld[i];
}
}
return max;
}
EDIT: Your code also has the assignment of max and feld[i] reversed. I've fixed it in my function above.
You have to initislize max in maxi() and min in mini() first to some value in the array, say feld[0].
Don't use immediate value such as 0 to initialize because using such a value will cause trouble when all values in the array are greater or smaller rhan the value.
Including limits.h, using INT_MIN for max and INT_MAX for min is OK.
UPDATE:
You are trying to calculate minimum value in maxi() and maximum value in mini(). You have to reverse the direction of comparision operator of feld[i]<max and feld[i]>min.
Using INT_MIN and INT_MAX is good because it will also somewhat work when size <= 0.
UPDATE 2:
feld[i]=max; and feld[i]=min; are also wrong. They should be max=feld[i]; and min=feld[i];.
Code is backwards. int maxi(int feld[],int len){... if(feld[i]<max){ should be if(feld[i] > max){.
Assignment also in wrong order.
Initialize max. #munircontractor #MikeCAT
Similar problems with mini().
int maxi(int feld[], int len){
// int max;
int max = INT_MIN;
int i;
for(i=0;i<len;i++){
// if(feld[i]<max){
if(feld[i] > max){
// feld[i] = max;
max = feld[i];
}
}
return max;
}

removing duplicate values from an array in C

I am trying to create a program in C that removes duplicate values in an integer array. My strategy is to first sort the array via a selectionsort function, and then call a function removedup that removes any consecutive, duplicate values in the array.
My code:
#include <stdio.h>
#include "simpio.h"
#define n 10
void GetArray(int a[]);
void SelectionSort(int a[]);
int FindMax(int a[], int high);
void swap(int a[], int p1, int p2);
int removedup(int a[]);
void printArray(int a[]);
main()
{
int a[n];
GetArray(a);
SelectionSort(a);
printf("The original, sorted array is\n");
printArray(a);
printf("The array with removed duplicates \n");
printArray(removedup(a));
getchar();
}
void GetArray(int a[])
{
int i;
for(i=0;i<n;i++)
{
printf("Enter integer# %d", i+1);
a[i]=GetInteger();
}
}
void SelectionSort(int a[])
{
int i, max;
for(i=0;i<n;i++)
{
max=FindMax(a,n-i-1);
swap(a,max,n-i-1);
}
}
int FindMax(int a[], int high)
{
int i, index;
index=high;
for(i=0;i<high;i++)
{
if(a[i]>a[index])
index=i;
}
return index;
}
void swap(int a[], int p1, int p2)
{
int temp;
temp=a[p2];
a[p2]=a[p1];
a[p1]=temp;
}
int removedup(int a[])
{
int i, count, OutArray[count], j;
count=0;
for(i=0;i<n-1;i++)
{
if(a[i]==a[i+1])
{
a[i+1]=a[i+2];
count++;
}
}
count++;
for(j=0;j<count;j++)
{
OutArray[i]=a[i];
}
return OutArray;
}
I have two questions:
1) How do I fix the error the compiler in giving me in the main body when calling removedup inside the printarray function, saying "invalid conversion from int to int*"? (line 22)
2) How do I accurately define the size of OutArray[] in the removedup function? Currently I have it defined as the size variable, but the value of this variable isn't accurately defined until after the declaration of OutArray.
Notice your prototypes ...
int removedup(int a[]);
void printArray(int a[]);
And also notice you're calling printArray() with the result of removedup().
printArray(removedup(a));
The result of removedup() is an int; printarray() requires a int[].
int and int[] are not compatible.
I suggest you remove duplicates and print array in two distinct statements.
You should be able to fix the compiling problems after reading comp.lang-c FAQ on arrays and pointers.
After you get your array sorted, you can use the following function to remove the duplicates:
int dedup(int arr[], int size) {
int curr = 0, next = 0;
while (next < size) {
while (next < size && arr[next] == arr[curr])
next++;
if (next < size)
arr[++curr] = arr[next++];
}
return size ? curr+1 : 0;
}
It takes two arguments, the array and its size. The duplicates are removed in-place, which means that the array is modified, without allocating a new array to store the unique elements.
Remember that the dedup function expects the elements to be sorted! I've noticed you are using your own implementation of selection sort, which makes me think this is homework. In that case, I feel a little reluctant on giving you a complete solution, although understanding it should be a good exercise anyway.
EDIT: I should've explained the last line of code.
return size ? curr+1 : 0; is equivalent to:
if (size)
return curr+1;
else
return 0;
Just a shorter way of saying the same thing.

Resources