Question

I'm finally moving from Python/PHP etc to C++. For the life of me, I can't sort out how this program, from Jumping into C++ works. It seems like, if you pass an array into a function, not as a reference, it still modified that array? To me, it seems like "array" should not have changed after sort() because it's not a reference.

#include <cstdlib>
#include <ctime>
#include <iostream>

using namespace std;

int findSmallestRemainingElement (int array[], int size, int index);
void swap (int array[], int first_index, int second_index);

void sort (int array[], int size)
{
    for ( int i = 0; i < size; i++ )
    {
        int index = findSmallestRemainingElement( array, size, i );
        swap( array, i, index );
    }
}

int findSmallestRemainingElement (int array[], int size, int index)
{
    int index_of_smallest_value = index;
    for (int i = index + 1; i < size; i++)
    {
        if ( array[ i ] < array[ index_of_smallest_value ]  )
        {
            index_of_smallest_value = i;
        }
    }
    return index_of_smallest_value;
}


void swap (int array[], int first_index, int second_index)
{
    int temp = array[ first_index ];
    array[ first_index ] = array[ second_index ];
    array[ second_index ] = temp;
}

// small helper method to display the before and after arrays
void displayArray (int array[], int size)
{
    cout << "{";
    for ( int i = 0; i < size; i++ )
    {
        // you'll see this pattern a lot for nicely formatting
        // lists--check if we're past the first element, and
        // if so, append a comma
        if ( i != 0 )
        {
            cout << ", ";
        }
        cout << array[ i ];
    }
    cout << "}";
}

int main ()
{
    int array[ 10 ];
    srand( time( NULL ) );
    for ( int i = 0; i < 10; i++ )
    {
        // keep the numbers small so they're easy to read
        array[ i ] = rand() % 100;
    }
    cout << "Original array: ";
    displayArray( array, 10 );
    cout << '\n';

    sort( array, 10 );

    cout << "Sorted array: ";
    displayArray( array, 10 );
    cout << '\n';
}
Was it helpful?

Solution

Your intuition is absolutely correct and, usually, you'd be right.

However, as a throwback to C, giving the name of an array as a function argument is a special and messy case — the name automatically transforms (or "decays") into a pointer to the array's first element.

So this:

void foo(int array[]);

actually means this:

void foo(int* array);

and so, even, does this:

void foo(int array[5]);

This cataclysmic design decision stemmed from the fact that arrays themselves cannot be automatically copied and somebody didn't want to keep writing out &myArray[0] in full.


One way around it is to use the wrapper std::array, which can be copied:

#include <array>

void foo(std::array<int, 5> name) // pass-by-value; copies!
{
   name[3] = 8;
}

int main()
{
   std::array<int, 5> array = { 1,2,3,4,5 };
   foo(array);
   // array is still 1,2,3,4,5 here
}

But, unless you are happy to delve into templates, you have to know the array dimension for that to work... and even if foo were a function template, the dimension would still have to be known at compile-time.

The container std::vector is a resizable array-like type with runtime dimensions; if your array won't always be 10 large, that may be what you need.

OTHER TIPS

Arrays are internally cast to pointers, so the function modifies the content. This behaviour probably happens because you don't want to pass a copy of an array (because of efficiency), so that's how originally C was designed (and C++ borrowed the convention).

see "arrays as parameters" subsection here. Essentially, the address to the start of the array is being passed in.

When passing a C-style array i.e. [] to a function it is really just a pointer.

void function(int array[]);
void function(int* array);

These two are exactly the same (such that it will fail to compile).

If you want a more self-contained array that will copy itself when passed by value, use std::vector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top