문제

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';
}
도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top