C++ 数组作用域

Che*_*eam 0 c++ arrays scope

我终于从 Python/PHP 等转向 C++。对于我的一生,我无法弄清楚这个程序是如何工作的,从 Jumping into C++ 开始。看起来,如果您将数组传递给函数而不是作为引用,它仍然会修改该数组吗?对我来说,似乎“array”在 sort() 之后不应该改变,因为它不是引用。

#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';
}
Run Code Online (Sandbox Code Playgroud)

Lig*_*ica 5

你的直觉是绝对正确的,而且通常情况下,你是对的。

然而,作为对 C 的回归,将数组的名称作为函数参数是一种特殊且混乱的情况 - 该名称自动转换(或“衰减”)为指向数组第一个元素的指针。

所以这:

void foo(int array[]);
Run Code Online (Sandbox Code Playgroud)

实际上的意思是这样的:

void foo(int* array);
Run Code Online (Sandbox Code Playgroud)

甚至,这样做:

void foo(int array[5]);
Run Code Online (Sandbox Code Playgroud)

这种灾难性的设计决策源于这样一个事实:数组本身无法自动复制,并且有人不想继续&myArray[0]完整写出。


解决这个问题的一种方法是使用包装器std::array,它可以被复制:

#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
}
Run Code Online (Sandbox Code Playgroud)

但是,除非您乐意深入研究模板,否则您必须知道其工作的数组维度...即使是foo函数模板,仍然必须在编译时知道该维度。

容器std::vector是一个可调整大小的类似数组的类型,具有运行时维度;如果您的数组并不总是 10 个大,那么这可能就是您所需要的。