在函數中以數組作為形參的方法


本文介紹了三種在函數中以數組作為形參時的處理方法,重點介紹C++11標准是如何管理數組大小的。

數組的兩個特殊性質對我們定義和使用作用在數組上的函數有影響,這兩個性質分別是:
不允許拷貝數組以及使用數組時通常會將其轉換成指針。因為不能拷貝數組,所以我們無法以值傳遞的方式使用數組參數。因為數組會被轉換成指針,所以當我們為函數傳遞一個數組時,實際上傳遞的是指向數組首元素的指針。

盡管不能以值傳遞的形式傳遞數組,但是我們可以把形參寫成類似數組的形式:

//盡管形式不同,但這三個print函數是等價的
//每個函數都有一個const int*類型的形參
void print(const int*);
void print(const int[]);
void print(const int[10])//這里的維度表示我們期望數組含有多少元素,實際不一定

當編譯器處理對print函數的調用時,只檢查傳入的參數是否是const int*類型:

int i = 2;
int j[2] = {1,2};
print(&i);  //正確,&i的類型是int*
print(j);   //正確,j被轉換成int*並指向j[0]

如果我們傳給print函數的是一個數組,則實參自動地轉換成指向首元素的指針,數組的大小對函數的調用沒有影響。

由於數組實際上是以指針的形式傳遞給函數的,因此一開始函數並不知道數組的確切尺寸,調用者應該為此提供額外的一些信息。管理指針形參有三種常用的技術:

使用標記指定數組長度

這種方法要求數組本身包含一個結束標記,使用這種方法的典型示例是C風格字符串。C風格字符串存儲在字符數組中,並且在最后一個字符后面跟着一個空字符。函數在處理C風格字符串時遇到空字符就停止:

void print(const char *cp)
{
    if(cp){     //若cp不是空指針
        while(*cp){     //只要指針所指字符不是空字符
            cout<<*cp++;    //輸出當前字符並將指針前移
        }
    }
}

這個方法適用於那些有明顯結束標記且該標記不會與普通數據混淆的情況。

顯示傳遞一個表示數組大小的形參

這種方法是專門定義一個表示數組大小的形參,在C程序和過去的C++程序中常常使用這種方法。

//const int ia[]等價於const int *ia
//size表示數組的大小,將它顯示地傳給函數用於控制對ia元素的訪問
void print(const int ia[],size_t size)
{
    for(size_t i = 0; i != size; ++i){
        cout<<ia[i]<<" ";
    }
}

這種方法通過形參size的值確定要輸出多少個元素,調用print函數時必須傳入這個表示數組大小的值:

int j[] = {1,2,3};

print(j,3);

使用標准庫函數begin和end

C++11標准引入兩個名為begin和end的函數,begin函數返回指向數組首元素的指針,end函數返回指向數組尾元素下一位置的指針,這兩個函數定義在iterator頭文件中。
示例代碼如下:

#include<iostream>
using namespace std;
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,-1,5,3,4};

    int *pbeg = begin(arr);     //指向arr首元素的指針
    int *pend = end(arr);       //指向arr尾元素的指針

    //尋找第一個負值元素,如果已經檢查完全部元素則結束循環
    while(pbeg != pend && *pbeg >= 0){
        ++pbeg;
    }
    cout<<*pbeg<<endl;  //輸出第一個負數的值
}

對於本文的print函數,可以寫成如下形式:

void print(const int *beg, const int *end)
{
    //輸出beg到end之間(不含end)的所有元素
    while(beg != end)
        cout<<*beg++<<" ";
}

為了調用這兩個函數,我們需要傳入兩個指針:一個指向要輸出的首元素,另一個指向尾元素的下一個位置。使用方法如下:

int a[] = {1,2,3};

print(begin(j),end(j));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM