(七)C++篇-数组形参传递

2022-06-17  本文已影响0人  GoodTekken

(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
上一篇 下一篇

猜你喜欢

热点阅读