我终于要从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
。