18 cout << setw( 4 ) << a[ i ]; 19
20 bubbleSort( a, arraySize ); // sort the array 21 cout << \22
23 for ( i = 0; i < arraySize; i++ ) 24 cout << setw( 4 ) << a[ i ]; 25
26 cout << endl; 27 return 0; 28 } 29
30 void bubbleSort( int *array, const int size ) 31 {
32 void swap( int *, iht * ); 33
34 for (int pass = 0; pass < size - 1; pass++ ) 35
36 for (int j = 0; j < size - 1; j++ ) 37
38 if ( array[ j ] > array[ j + 1 ] ) 39 swap( &array[ j ], &arra[ j + 1 ] ); 4O } 41
42 void swap( int *element1Ptr, int *element2Ptr ) 43 {
44 int hold = *elementlPtr; 45 *element1Ptr = *element2Ptr; 46 *element2Ptr = hold;
47 }
输出结果:
Data item: in Original Order
2 6 4 8 10 12 89 68 45 37 Data items in ascendinq Order
2 4 6 8 lO 12 37 45 68 89
图5.15 按引用调用的冒泡排序
注意函数bubbleSort中的几个特性。函数首部中将array声明为int* array而不是int array[],表示bubbleSort接收单下标数组作为参数(这些符号是可以互换的)。参数size声明为const以保证最低权限原则。尽管参数size接收main中数值的副本,且修改该副本并不改变main中的值,但是bubbleSort不必改变size即可完成任务。bubbleSort执行期间数组的长度保持不变,因此,size声明为const以保证不被修改。如果排序过程中修改数组长度,则排序算法无法正确执行。
bubbleSort函数体中包括了函数swap的原型,因为它是调用swap的惟一函数。将原型放在bubbleSort中,使得只能从bubbleSort正确地调用swap。其他函数要调用swap时无法访问正确的函数原型,这通常会造成语法错误,因为C++需要函数原型。
软件工程视点5.4
将函数原型放在其他函数中能保证最低权限原则,只能从该原型所在函数中正确地调用。
注意函数bubbleSort接收数组长度参数。函数必须知道数组长度才能排序数组。数组传递到函数时,函数接收数组第一个元素的内存地址。数组长度要单独传递给函数。
通过将函数bubbleSort定义成接收数组长度作为参数,可以让函数在排序
任何长度单下标整型数组的程序中使用。
软件工程视点5.5
向函数传递数组时,同时传递数组长度(而不是在函数中建立数组长度信息),这样能使函数更加一般化,以便在许多程序中复用。
数组长度可以直接编程到函数内,这样会把函数的使用限制在特定长度的数组并减少其复用性。程序中只有处理特定长度的单下标整型数组时才能使用这个函数。
C++提供一元运算符sizeof,确定程序执行期间的数组长度或其他数据类型长度(字节数)。采用数组名时(如图5.16所示),sizeof算符返回数组中的总字节数为size_t类型的值,通常是unsigned int类型。这里使用的计算机将float类型的变量存放在4字节内存中,array声明为20个元素,因此array使用80字节内存空间。在接收数组参数的函数中采用指针参数时,sizeof运算符返回指针长度的字节数(4)而不是数组长度。
常见编程错误5. 7
在函数中用sizeof运算符寻找数组参数长度的字节数时返回指针长度的字节数而不是数组长度的字节数。
1 // Fig. 5.16: fig05_16.cpp
2 // Sizeof operator when used on an array name 3 // returns the number of bytes in the array. 4 #include
6 size_t getSize( float * ); 7
8 int main() 9 {
10 float array[ 20 ]; 11
12 cout << \13 << sizeof( array )
14 << \15 << getSize( array ) << endl; 16
17 return 0; 18 } 19
20 size_t getSize( float *ptr ) 21 {
22 return sizeof( ptr ); 23 }
输出结果:
The number of bytes in the array is 80 The number of bytes returned by getSize is 4
图5.16 采用数组名时,sizeof运算符返回数组中的总字节数
数组中的元素个数也可以用两个sizeof操作的结果来确定。例如,考虑下列数组声明:
double realArray[ 22 ];
如果double数据类型的变量存放在8个字节的内存中,则数组realArray总共包含176个字节。要确定数组中的元素个数,可以用下列表达式: sizeof realArray/sizeof(double)
这个表达式确定realArray数组中的字节数.并将这个值除以内存中存放—个
double值的字节数,图5.17的程序用size运算符计算我们所用的个人计算机上存放每种标准数据类型时使用的字节数。 可移植性提示 5.3
存放特定数据类型时使用的字节数随系统的不同而不同。编写的程序依赖于数据类型长度而且要在几个计算机系统上运行时,用sizeof确定存放这种数椐类型时使用的宇节数。
1 // Fig. 5.17:fig05 17.cpp
2 // Demonstrating the sizeof operator 3 ~include
76 ~nt main(} 8 char c; 9 short s; 10 iht i; 11 long 1; 12 float f; 13 double d; 14 long double ld;
15 int arras 20 ], *ptr = array; 16
17 cout << \
18 << \19 << \
20 << \2I \22 << \23 \