0

I am trying to understand how to find the maximum number using a recursive function, but I do not really understand how. Having this code:

#include <stdio.h>
#include <stdlib.h>
int main()
{

    int ar[100],n,i;
    int *ptr;
    printf("Enter size of the list:");
    scanf("%d", &n);
    printf("Printing the list:\n");
    for (i = 0; i < n ; i++)
    {
        scanf("%d", &ar[i]);
    }
    ptr=&ar;
    int max=maximum(ptr,n);
    printf("ma %d",max);
    return 0;
}
int maximum(int ar[], int n)
{

    int max;
    if(n+1==1)
    {
        return ar[n];
    }
    max =maximum(ar,n-1);
    return ar[n]>max?ar[n]:max;
}

What is it actually doing and how? Is it correctly using pointers to point the array of integers? I hope you can help me understand it!

6
  • 4
    a[n] is undefined behavior. You are reading uninitialized values. Commented Feb 4, 2019 at 7:14
  • Recursion has it's place, but be very wary of the number of times it may recurse. You are creating a separate function stack and local variables each time a recursive call is made. Think about an in-order sequence from INT_MIN to INT_MAX and the number of separate function stacks that would be created. (yes, in reality the number will "probably" be much less, but be mindful of what could happen) Commented Feb 4, 2019 at 7:42
  • Why if (n+1==1) though? Apart from being harder to read, n+1 can (theoretically) lead to overflow. Commented Feb 4, 2019 at 8:35
  • @Groo It looks like some coding puzzle for a beginner, and they are supposed to realize that if (n + 1 == 1) is just the same as if (n == 0). There are a lot of other silly things in this code. Anyways, depth first recursion is very confusing the first time you see it. I went through the motions of a thorough explanation. I hope that helps. Commented Feb 4, 2019 at 8:39
  • @okovko: it's a weird coding puzzle since calling maximum(ptr, n) from main will lead to UB, as Ajay mentioned. Commented Feb 4, 2019 at 8:49

5 Answers 5

1

You set aside memory for an array of 100 integers with int ar[100], and you enter n which is set using scanf("%d", &n). If you enter a number greater than 100 at this stage, your program will seg fault because your loop for (i = 0; i < n ; i++) will try to access ar[100] which is a memory access error (the highest array index available is ar[100 - 1], notice that 100 - 1 < 100). Anyways, you fill n indices of ar in the loop. ptr = &ar just assigns the starting address of ar to ptr. By the way ptr = ar will work too, the & is not necessary. Now you can use ptr the same way you were using ar.

The easiest way to understand the recursion is to go straight to the last call of maximum. But first, understand that you passed ptr to the function which is the same as passing ar (remember, they are the same thing in main since ptr = ar.).

So in the last call to maximum, When n + 1 == 1 (same as n == 0), it returns ar[n] which is ar[0], which is first the number you entered for 'Printing the list' (it was stored in ar[0]).

Now in the second last call to maximum, n + 1 == 1 is false because n = 1 so we go to max = maximum(ar, n - 1). That's the result of the last call to maximum that I just explained, so max has the value of ar[0]. Now you have return ar[n] > max ? ar[n] : max, which is the same as return ar[1] > ar[0] ? ar[1] : ar[0]. That is the same as

if (ar[1] > ar[0]) {
  return ar[1];
} else {
  return ar[0];
}

And you can see that this returns whichever is bigger, ar[0] or ar[1]. Now for the third last call to maximum, max is the result of the second last call to maximum. And you can see the pattern emerge. You will return whichever is greater: max or ar[n] for all the rest of the calls to maximum, and by the time you get to the first call to maximum, you will have compared all the values in ar to find its maximum and return it.

Also, what Ajay said is right, ar[n] is accessing a value that you never initialized in your loop. You should write int max = maximum(ptr, n - 1) in main to fix that.

Sign up to request clarification or add additional context in comments.

Comments

1

My solution with tail recursion:

int maximum(int a[], int n)
{
    if (n == 1)
        return a[0];
    --n;
    return maximum(a + (a[0] < a[n]), n);
}

Demo on compiler explorer

2 Comments

that doesn't work , for instance maximum({1, 2}, 2) returns 1
It is a very interesting way to do
0

To understand how maximum works, just try and find some invariants in the maximum function

int maximum(int ar[], int n)
{
    int max;
    if(n==0)
    {
        return ar[n];
    }
    max =maximum(ar,n-1);
    /* at this point MAX keeps the maximum of the subarray [0..N-1] and using this 
       we try to get by induction the maximum of [1..N]. */
    return ar[n]>max?ar[n]:max;
}

Comments

0

Consider that definition :

#include <stdio.h>
#include <stdlib.h>

void maximum(int nums[], int size, int index, int * max)
{
  if (index != size) {
    if (nums[index] > *max)
      *max = nums[index];
    maximum(nums, size, ++index, max);
  }
}

int main()
{
  int * nums;
  int size, i, max;

  fprintf(stderr, "Enter size of the list: "); /* stderr to flush without \n */
  if ((scanf("%d", &size) != 1) || (size <= 0)) {
    puts("wrong size");
    return 0;
  }

  if ((nums = malloc(size * sizeof(int))) == 0) {
    puts("cannot allocate nums");
    return 0;
  }

  for (i = 0; i != size; ++i) {
    if (scanf("%d", &nums[i]) != 1) {
      puts("invalid number");
      return 0;
    }
  }

  max = nums[0];
  maximum(nums, size, 1, &max);
  free(nums);
  printf("max = %d\n", max);

  return 0;
}

Execution:

% gcc -O2 -pedantic -Wall m.c
% ./a.out
Enter size of the list: 3
3
1
2
max = 3

maximum is recursive, but this is a terminal recursion, so the compiler can remove it to generate a loop. So maximum seems to be recursive as you request but the stack will not explode even with a large number :

% ( echo 100000000 ; yes 1 ) | ./a.out
Enter size of the list: max = 1

If I remove the option -O2 the generate code uses the recursion and the stack explode :

% gcc -pedantic -Wall m.c
% ( echo 100000000 ; yes 1 ) | ./a.out
Enter size of the list: Segmentation fault

Comments

0
int maxRecursively( arr array, int index){

    int max = array.ptr[index];

    if ( index == array.length-2 ){
        return max= array.ptr[index]> array.ptr[index+1] ? array.ptr[index]:array.ptr[index+1];
    }

    return  max = max > maxRecursively(array,index+1) ? max: maxRecursively(array,index+1);
}

1 Comment

Is this supposed to be C language? Question is for C, and said nothing about a type "arr"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.