3

I am new to c++ and have a couple questions regarding passing arrays by reference to functions (so that the arrays are modified by the function). I realize there are similar questions that have been asked already, but there are a few points that I think were not covered in those previous questions (at least from what I saw). From what I have gathered so far, one can pass an array by reference by doing the following:

#include<iostream>
using namespace std;

void modify_array(int* a);

int main()
{
  int array[10];

  modify_array(&array[0]);

  for(int i=0;i<10;i++)
  {
    cout<<array[i]<<endl;
  }
}

void modify_array(int* a)
{
  int i;
  for(i=0;i<10;i++)
  {
    *(a+i)=i;
  }
}

This makes sense to me but if I change the function to:

void modify_array(int* a)
{
  int i;
  for(i=0;i<10;i++)
  {
    a[i]=i;  //line changed
  }
}

This also works. Is there a difference? Or is the second just a short cut? Also in the case of passing 2d arrays I would have guessed that the following code would work:

#include<iostream>
using namespace std;

void modify_array(int* a);

int main()
{
  int array[10][10];

  modify_array(&array[0][0]);

}

void modify_array(int* a)
{
  int i,j;
  for(i=0;i<10;i++)
  {
    for(j=0;j<10;j++)
    {
      a[i][j]=i*j;
    }
  }
}

But this doesn't. From what I have seen in other related questions, you would do something like:

void modify_array(int (*a)[10])
{ 
  int i,j;
  //a[i][j]= blah blah blah;
}

or,

void modify_array(int (&a)[10][10])
{ 
  int i,j;
  //a[i][j]= blah blah blah;
}

What is the difference between these latter two function definitions? What do experienced c++ programmers recommend using: the (*a)[10][10] notation or the (&a)[10][10] notation?

niklasfi
  • 15,245
  • 7
  • 40
  • 54
James
  • 398
  • 1
  • 6
  • 19
  • `void modify_array(int* a);` Takes a pointer to a block of integers or a pointer to a single int. Can be stack or dynamically allocated. `modify_array(int (&a)[10])` Takes an array of 10 integers by reference. Must be stack allocated, size is not lost. sizeof operator can be used. – Brandon Apr 12 '14 at 20:13
  • @CantChooseUsernames ok so is the use of `a[i]=i` a short-cut for `*(a+i)=i`? In both cases in the main program we call the function by `modify_array(&array[0])` so we are passing the memory reference to the first element of the array, so it seems like `a[i]=i` would be changing the memory location and not the actual value. Thanks. – James Apr 12 '14 at 20:26
  • possible duplicate of [How do I use arrays in C++?](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) – fredoverflow Apr 12 '14 at 20:49
  • @FredOverflow Thanks I actually didn't see this one (was looking at some other questions). Not sure if it answers all the questions I have, but ill take a look. – James Apr 12 '14 at 21:02

1 Answers1

3

Writing *(a+i)=i; or a[i]=i; are equivalent. The first is seen as an offset applied to the pointer to the array and assigning the value to the pointee, while the second is assigning the value to the element of the array.

However, when passing a pointer to a function modify_array(int* a), it cannot deduce that the pointee is a 2D array, and does not know what size to offset to address the other lines of the array, with a[i][j]=i*j;. For the compiler, it can only access the first dimension of the array.

The proper way to do what you need is this

#include<iostream>
using namespace std;

void modify_array(int (&a)[10][10]);

int main()
{
  int array[10][10];

  modify_array(array);

  for(int i=0;i<10;i++)
  {
    for(int j=0;j<10;j++)
    {
      cout<<array[i][j]<<endl;
    }
  }
}

void modify_array(int (&a)[10][10])
{
  int i;
  for(i=0;i<10;i++)
  {
    for(int j=0;j<10;j++)
    {
      a[i][j]=i*j;
    }
  }
}

Live example

The function is expecting an int array of 10x10, passed by reference.

Vince
  • 3,497
  • 2
  • 19
  • 15
  • ok, so when we invoke the function in the main part of the program by `modify_array(array)` we are sending this 10-by-10 array by reference. So does the program only actually send the memory address of the first element &array[0] still? Or is it sending the memory address of all the elements in the array (i.e. 100 addresses)? If we added the line `cout<<&a< – James Apr 12 '14 at 20:59
  • A reference is different than a pointer in many ways, but understand that passing by reference will NOT copy the whole array in your example. How it is compiled is up to the compiler, and will most certainly involve pointers. And yes, `cout<<&a< – Vince Apr 12 '14 at 21:51
  • 1
    Not entirely true: "reference to an array" is just a sugared pointer. http://www.cplusplus.com/doc/tutorial/pointers/ – Ashalynd Apr 12 '14 at 22:53
  • See also here for more info about pointers vs references: http://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html – Ashalynd Apr 12 '14 at 23:04
  • Nice answer, however, while `*(a + b)` is equivalent to `a[b]` in C, that is not the case in C++: In C++, the `operator[]` may be overloaded in a user defined type, which can make it behave differently than the combination of the user defined `operator+` and `operator*`. – cmaster - reinstate monica Apr 13 '14 at 10:22