(1.1)不限制数组长度的陷阱。
// parameter treated as const int*, size of array is ignored
void printValues(const int ia[5])
尽管上述代码假定所传递的数组至少含有 5 个元素,但 C++ 语言没有任何机制强制实现这个假设。虽然编译没有问题,但是以下两个调用都是错误的,可能导致运行失败。在这两个调用中, 由于函数 printValues 假设传递进来的数组至少含有 5个元素,因此造成数组内在的越界访问。
(1.2)可以限制传递的数组长度,但应用不够灵活。
// ok: parameter is a reference to an array; size of array is fixed
void printValues(int (&arr)[10]) { /* ... */ }
&arr 两边的圆括号是必需的,因为下标操作符具有更高的优先级。
测试代码如下:
#include <iostream>
#include <vector>
using namespace std;
// ok: parameter is a reference to an array; size of array is fixed
// 这个版本的 printValues 函数只严格地接受含有 5 个 int 型数值的数组
//void printValues(int (&arr)[5]) { /* ... */ }
void printValues(const int ia[5]);
int main()
{
int i = 0, j[3] = {0, 1, 2};
cout<<"i:"<<endl;
printValues(&i); // ok: &i is int*; probable run-time error
cout<<endl;
cout<<"j:"<<endl;
printValues(j); // ok: j is converted to pointer to 0th324
// element; argument has type int*;
// probable run-time error
return 0;
}
// parameter treated as const int*, size of array is ignored
void printValues(const int ia[5])
{
// this code assumes array has 10 elements;
// disaster if argument has fewer than 10 elements!
for (size_t i = 0; i != 5; ++i)
{
cout << ia[i] << endl;
}
}
输出结果:
tekken@tekken:~/C++WS$ ./a.out
i:
0
0
1
2
-1535276800
j:
0
1
2
-1535276800
1919115986
(2)优化一:用户给定数组长度,当长度不对,容易发生溢出。
调用这个版本的函数需要传递两个指针:一个指向要输出的第一个元素,另一个则指向最后一个元素的下一个位置。只要正确计算指针,使它们标记一段有效的元素范围,程序就会安全。
测试代码如下:
#include <iostream>
#include <vector>
using namespace std;
void printValues(const int *beg,const int *end);
int main()
{
int j[2] = {3,4};
printValues(j,j+2);
return 0;
}
void printValues(const int *beg,const int *end)
{
while(beg!=end)
{
cout<<*beg++<<endl;
}
}
输出结果:
tekken@tekken:~/C++WS$ ./a.out
3
4
(3)优化二:显式传递表示数组大小的形参
这个版本使用了形参 size 来确定要输出的元素的个数。调用 printValues时,要额外传递一个形参。只要传递给函数的 size 值不超过数组的实际大小,程序就能安全运行。
测试代码如下:
#include <iostream>
#include <vector>
using namespace std;
void printValues(const int ia[], size_t size);
int main()
{
int j[2] = {5,6};
printValues(j, sizeof(j)/sizeof(*j));
return 0;
}
// const int ia[] is equivalent to const int* ia
// size is passed explicitly and used to control access to elements of ia
void printValues(const int ia[], size_t size)
{
for (size_t i = 0; i != size; ++i)
{
cout << ia[i] << endl;
}
}
输出结果:
tekken@tekken:~/C++WS$ ./a.out
5
6








网友评论