pass by reference recursive function without initialising the reference

Ophitect Source

This is a recursive function to find the amount of 2 appearing in a number.

Example Input:

221122

Example Output:

countTwo(): 4

#include <stdio.h>
void countTwo2(int num, int *result);

int main()
{
    int number, result;
    printf("Enter the number: \n");
    scanf("%d", &number);
    countTwo2(number, &result);
    printf("countTwo2(): %d\n", result);
    return 0;
}

void countTwo2(int num, int *result)
{
    if(num > 0) {
       if((num % 10)/2 == 1) {
           *result += 1;
       }
       countTwo2(num/10, result);
    }

}

I can't increment result since it has not been initialised but I also can't initialise result in the recursive function as this will reset the result.

Edit: This is a question given, with all the template written as above except for the code within countTwo. We are supposed to write the code in countTwo such that main() will be able to run.

Edit2: Thanks for the help! This problem has been solved by using static int. I understand that this is not very efficient. I will also ask my teacher pertaining to this question. Once again, Thanks!

crecursion

Answers

answered 5 days ago squeamish ossifrage #1

I can't see any good reason for declaring this as a void function with the result passed back via pointer parameter.

The following would be a lot cleaner, surely?

int countTwo(int num) {
    return (num == 0) ? 0 : (num % 10 == 2) + countTwo(num / 10);
}

answered 5 days ago Lundin #2

For reference, the proper way to write such a function is to not use recursion. It isn't obvious that the compiler will be able to unroll the recursion in this case, as the recursive call would be in the middle of the function, and also conditional.

Thus the only thing gained from recursion is slow execution and higher stack peak use. Why would we want slow execution when we can have fast execution? You should ask your teacher this question, so they can tell you why they are teaching it. I would be most curious to hear their rationale.

For a professional, non-academic programmer, the proper way to write the function would be to use a loop:

int count_n (int input, int n)
{
  int result = 0;

  for(; input>0; input/=10)
  {
    if(input%10 == n)
    {
      result++;
    }
  }

  return result;
}

(This version doesn't work with negative numbers.)

answered 5 days ago Lasse Vågsæther Karlsen #3

The way to keep all the oddities of this code:

  • it has to be recursive
  • you cannot change main, so the initial result value will be undefined

is to, as you stated you cannot do, actually reset result inside countTwo2. However, you need to it in the right place, before you start incrementing.

The way to do that is to reorder your function and add the part that resets the value at the right place:

void countTwo2(int num, int* result)
{
    if (num > 0)
    {
        countTwo2(num / 10, result);
        if ((num % 10) / 2 == 1)
        {
            *result += 1;
        }
    }
    else
        *result = 0;
}

Notice that I moved the recursive call up above the if-then block that increments the result, and that when num is 0, we reset. This will call recursively down digits of the input until we're at the end, then reset the result, then return back up one digit at a time and optionally increment the value.

This requires no other changes to your code.

As many have stated, in comments and answers, this is obviously not a good implementation or design but if you have a confined context to work in, this is probably as good as it gets.

answered 5 days ago manoliar #4

As I mentioned before you may use static variables. You do not need two arguments. Here is a solution: @Lasse Vågsæther Karlsen

#include <stdio.h>
int countTwo2(long int num)
{
    static int m=0;  //static variable is initialized only once.
    if (num==0)
        return m;
    else if (num % 10 ==2)
        m=m+1;
    num=num /10;
    countTwo2(num);
}

int main()
{
    int result; long int number;
    printf("Enter the number: \n");
    scanf("%ld", &number);
    result=countTwo2(number);
    printf("countTwo2(): %d\n", result);
    return 0;
}

comments powered by Disqus