【问题标题】:C++ array scopeC++ 数组范围
【发布时间】:2014-04-26 23:07:18
【问题描述】:

我终于从 Python/PHP 等转向 C++。对于我的生活,我无法从 Jumping into C++ 中弄清楚这个程序是如何工作的。看起来,如果你将一个数组传递给一个函数,而不是作为参考,它仍然修改了那个数组?对我来说,似乎“数组”在 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++ arrays scope


    【解决方案1】:

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

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

    所以这个:

    void foo(int array[]);
    

    其实是这个意思:

    void foo(int* array);
    

    所以,甚至,这样做:

    void foo(int array[5]);
    

    这个灾难性的设计决定源于数组本身无法自动复制,并且有人不想继续完整地写出&amp;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 大,那可能就是您需要的。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        参见“数组作为参数”小节here。本质上是传入数组开头的地址。

        【讨论】:

          【解决方案4】:

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

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

          这两个完全一样(这样会编译失败)。

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

          【讨论】:

          • C-style arrays are really just pointers 不,绝对是废话。这个函数参数规则有时看起来像它们,但它们不是。另外,最好推荐std::array,因为那是真正的模拟。
          猜你喜欢
          • 2012-04-27
          • 1970-01-01
          • 1970-01-01
          • 2021-06-20
          • 2013-08-12
          • 1970-01-01
          • 2012-01-30
          • 1970-01-01
          • 2010-10-25
          相关资源
          最近更新 更多