2013-03-06 18 views
0

如何查找傳遞給函數的字符串數組的大小。大小應該在函數內計算。字符串數組的大小通過函數

#include<iostream> 

using namespace std; 


template <typename T,unsigned S> 
unsigned arraysize(const T (&v)[S]) { return S; } 

void func(string args[]) 
{ 
    unsigned m=arraysize(args); 
    cout<<m; 
} 

int main() 
{ 
    string str_arr[]={"hello","foo","bar"}; 

    func(str_arr); 
} 

什麼我不明白的是:

如果語句arraysize(str_arr)主使用,就不會造成問題。 str_arr是一個數組,因此str_arr充當指針,所以當我們使用arraysize(str_arr)時,意味着我們將地址發送到arraysize函數(糾正我,如果我錯了)。

但在函數func(),我不明白爲什麼有一個問題,即聲明arraysize(args)發送字符串數組ARGS(或指針參數的個數地址)的地址..或者是更復雜,因爲它變得一些雙指針?說明?

另外請糾正上述代碼..

+2

無法確定數組大小和指針大小。不是沒有專用的終止字節。這就是爲什麼我們有argc開始。 – Dmitry 2013-03-06 20:05:35

+0

另一個使用'std :: vector'的理由。 – 2013-03-06 20:07:00

+0

這是java數組超過C++指針的優點之一,數組的大小可以從數組本身獲得。德米特里是正確的,在C++中你所要求的是不可能的。 – 2013-03-06 20:07:01

回答

0

str_arr是一個字符串數組。當您執行sizeof(str_arr)時,您將獲得該數組的大小。但是,儘管args看起來像一串字符串,但事實並非如此。看起來像一個數組的參數實際上是指針類型。也就是說,編譯器將string args[]轉換爲string* args。當你做sizeof(args)你只是獲得指針的大小。

您可以通過數組的大小到函數或採取與模板參數大小的數組的引用(因爲你有arraysize所做的那樣):

template <size_t N> 
void func(string (&args)[N]) 
{ 
    // ... 
} 
+0

哈哈......這就是我以爲..它變成了字符串*。 – bkcpro 2013-03-06 20:18:09

0

沒有辦法來確定數組的大小時發送到一個函數。你還必須記住只有一個指向數組的指針纔會被髮送到函數中,這使得計算數組的大小在理論上甚至是不合理的。

0

數組大小的信息在您的函數中永遠不可見,因爲您在決定使用string args[]作爲參數時拋棄了它。從編譯器的角度來看,它與string* args相同。您可以將功能更改爲:

template<size_t M> 
void func(string (&args)[M]) 
{ 
    cout<<M; 
} 

但似乎你已經知道了,對吧?

+0

不:)但是謝謝:))還是需要掌握這種模板的用法! – bkcpro 2013-03-06 20:20:25

0

如果語句arraysize(str_arr)是主要使用,它不會構成 問題。 str_arr是一個數組,因此str_arr充當指針,所以 當我們使用arraysize(str_arr),這意味着我們發送的地址爲 arraysize函數(糾正我,如果我錯了)。

我得在這裏糾正你。你陳述了一個正確的前提,但是得出錯誤的結論。

關鍵點確實是str_arrmain中的一個數組。當數組衰減到許多(大部分)表達式上下文中的指針時,當對數組的引用進行初始化時,這不適用。這就是爲什麼array_size被聲明爲引用數組參數的原因 - 這是獲取數組類型參數的唯一方法,這意味着它具有定義的長度。

func的情況並非如此。當函數參數被聲明爲純數組類型時,指針衰減的數組被應用於該聲明。您的func聲明等同於void func(string * args)。因此args是一個指針,而不是一個數組。你可以稱之爲func作爲

string str_non_array; 
func(&str_non_array); 

正因爲如此,參考到陣列不能綁定到它。無論如何,args已經完全失去了它所指向的數組大小的所有信息。

你可以使用相同的參考到陣列的伎倆在arraysize使用:聲明func

template <std::size_t N> 
void func(string (&args)[N]); 

但這變得不切實際的確無處不在(可能導致代碼膨脹,如果應用天真到所有數組處理代碼)。在其他語言中可用的C++等效長度爲std::vector<string>(對於動態大小的數組)或std::array<string,N>(對於編譯時已知的固定大小)。請注意,後者可能導致與上述相同的代碼膨脹,因此在大多數情況下,std::vector<string>將是您需要傳遞給各種函數的陣列的首選類型。

+0

'std :: array '會導致與'template '的'func'版本一樣多的代碼擴展。 – 2013-03-06 20:33:10

+0

正如你所說的,對數組的引用被初始化,str_arr如何作爲引用被初始化,但不會轉換成指針?對不起,如果這不是一個有效的問題?基本上我問的是如何str_arr不被用作我的代碼上下文中的指針。 – bkcpro 2013-03-06 20:50:11

+0

@DanielFrey:好點 – JoergB 2013-03-07 09:06:56

0

德米特里是對的,我想進一步解釋一下。它發生的原因是因爲數組在C++中不是First Class citizen,並且當它作爲參數傳遞時,它會衰減到指針,並且在調用函數中得到的是指向其第一個元素的指針,並且大小會丟失。 您可以參考C++ arrays as function arguments來查看可用的替代選項。