trisimix
trisimix

Reputation: 101

How do you call a reference array in a recursive function?

So, my knowledge is lacking on both references and recursives.

Consider the following:

int sumelements(int arraylength, int &list){
  return list[arraylength] + sumelements(arraylength - 1, *list);
}
int main(){
  int arraylength = 10;
  int list[arraylength] = {1,2,3,4,5,6,7,8,9,10};
  sumelements(arraylength-1, *list);
}

Line 2 causes an error, assumingly because my syntax is wrong, though like I said I am new to both concepts.

Also, I know it's a loop, I'd just like it to compile.

Upvotes: 1

Views: 509

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 597051

sumelements is accessing a particular element of list, so you need to change your list parameter from int& to int* (or list[], which is identical to int* when used in a function parameter) so that operator[] will work correctly. Then change both main and sumelements to pass list without using operator* at all. When you refer to a fixed-length array by just its name, it decays into a pointer to the 1st element, so main can pass the array as just list by itself.

Also, you have endless recursion, as you don't have a stop condition in sumelements, so it will just keep calling itself endlessly, causing undefined behavior once arraylength becomes < 0.

Also, in main, you are declaring your list array using an arraylength value that is not known at compile-time, only at runtime. Declaring a fixed-length array in this manner is not allowed by the C++ standard, but some compilers (notably gcc) support it as a compiler extension. Do not rely on this behavior, as it is not portable. Declare arrayLength as const so it will be known at compile-time.

Try this:

#include <iostream>

int sumelements(int index, int *list)
{
  if (index < 0) return 0;
  return list[index] + sumelements(index - 1, list);
}

int main()
{
  const int arraylength = 10;
  int list[arraylength] = {1,2,3,4,5,6,7,8,9,10};
  std::cout << sumelements(arraylength - 1, list);
}

Live Demo

That being said, a more C++-ish way to handle this would be to use the standard std::accumulate() algorithm instead of a recursive function:

#include <iostream>
#include <numeric>

int main()
{
  const int arraylength = 10;
  int list[arraylength] = {1,2,3,4,5,6,7,8,9,10};
  std::cout << std::accumulate(list, list+arraylength, 0);
}

Live Demo

Upvotes: 3

Aconcagua
Aconcagua

Reputation: 25536

This is just playing around, possibly helping to understand references, however, not intended to actually be used in real code!!!

It can be done with references, too, if one does it right:

int sumelements(int arraylength, int& list)
{
    if(arraylength < 0) // stolen from Remy...
        return 0;

    return (&list)[arraylength] + sumelements(arraylength - 1, list);
    //     ^^^^^^^ 
}

Well, as list still references the first integer in your array, by taking the address of it you get back the pointer you need - which you then can use with an offset (index). In the recursive call, you pass on list just as is, and same again.

As mentioned already: This is just for understanding, don't do it this way, use pointers as Remy did!

Upvotes: 0

Related Questions