2013-03-06 20 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来查看可用的替代选项。