C++数组作用域



我终于要从Python/PHP等转移到C++了。就我的一生而言,我无法理清这个程序是如何工作的,从跳到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';
}

你的直觉是绝对正确的,通常你是对的。

然而,作为对C的回归,将数组的名称作为函数参数是一种特殊而混乱的情况—名称会自动转换(或"decays")为指向数组第一个元素的指针。

所以这个:

void foo(int array[]);

实际意思是:

void foo(int* array);

因此,甚至这样做:

void foo(int array[5]);

这个灾难性的设计决定源于这样一个事实,即数组本身无法自动复制,而且有人不想一直完整地写出&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
}

但是,除非你很乐意深入研究模板,否则你必须知道数组维度才能工作。。。即使foo是一个函数模板,在编译时也必须知道维度。

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

数组内部强制转换为指针,因此函数会修改内容。发生这种行为可能是因为您不想传递数组的副本(因为效率),所以最初C就是这样设计的(C++借用了约定)。

请参阅此处的"数组作为参数"小节。从本质上讲,数组开头的地址是传入的。

当将C样式数组(即[])传递给函数时,它实际上只是一个指针。

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

这两者完全相同(因此它将无法编译)。

如果您想要一个更自包含的数组,该数组在传递值时会复制自身,请使用std::vector

最新更新