1

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.

3
  • You use list like it was an array or pointer. You cannot use it this way. Simplifying - use a reference the same way you use normal variable, but have in mind, that reference references to some other variable. Commented Mar 22, 2018 at 22:16
  • I have added two lines in main and one in sum elements to clarify the issue Commented Mar 22, 2018 at 22:16
  • int sumelements(int arraylength, int* list){...} and sumelements(arraylength-1, list); Commented Mar 22, 2018 at 22:18

2 Answers 2

3

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

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

12 Comments

Its worth to notice, that you've added const in arraylength. Creating automatic arrays with not compile-time known size is forbidden in C++. It works only in GCC as an extension.
I would even say: std::accumulate(std::begin(list), std::end(list), 0) to get rid of arraylength.
So, is the first code example not passing the array by pointer instead of reference?
@trisimix: yes, my first example is passing the array by pointer. Your original code doesn't pass the array by pointer OR reference, it passes a single int by reference instead, which is why list[arraylength] and *list cause errors.
@Jarod42: std:begin() and std::end() were added in C++11, which not everyone uses, so I didn't mention them. But, to really get rid of arrayLength completely, you would have to also declare list as int list[] = {...}; so the compiler can deduce the array size
|
0

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!

3 Comments

Ahhh thanks for clarifying. I was sitting in a lab and wondering how to do this and my TA couldn't figure out how, I get why not to do it now.
"my TA couldn't figure out how" - then your teacher needs to find a better TA who knows what they are doing.
Yeah but then I'd have to pay more for school

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.