如何查找传递给函数的字符串数组的大小。大小应该在函数内部计算。
#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);
}
我不明白的是:
如果在main中使用语句arraysize(str_arr)
,则不会造成问题。 str_arr是一个数组,因此str_arr充当指针,因此当我们使用arraysize(str_arr)时,这意味着我们将地址发送到arraysize函数。(如果我错了,请纠正我)。
但是在函数func()中,我不明白为什么会出现问题,即语句arraysize(args)
发送字符串数组的地址args(或指针args的地址)..还是更复杂既然它变成了一些双指针?解释
另请注意以上代码..
答案 0 :(得分:0)
发送到函数时无法确定数组的大小。你还必须记住,只有一个指向数组的指针被发送到函数,这使得计算数组的大小在理论上甚至是不可信的。
答案 1 :(得分:0)
在您的函数中永远不会看到数组大小的信息,因为当您决定使用string args[]
作为参数时,它会将其丢弃。从编译器的角度来看,它与string* args
相同。您可以将功能更改为:
template<size_t M>
void func(string (&args)[M])
{
cout<<M;
}
但似乎你已经知道了,对吧?
答案 2 :(得分:0)
str_arr
是一个字符串数组。执行sizeof(str_arr)
时,您将获得该数组的大小。然而,尽管args
看起来像一个字符串数组,但事实并非如此。看起来像数组的参数实际上是指针类型。也就是说,编译器将string args[]
转换为string* args
。当你执行sizeof(args)
时,你只需要获得指针的大小。
您可以将数组的大小传递给函数,也可以使用模板参数大小引用数组(与arraysize
一样):
template <size_t N>
void func(string (&args)[N])
{
// ...
}
答案 3 :(得分:0)
如果在main中使用了语句
arraysize(str_arr)
,则不会构成声明 问题。str_arr
是一个数组,因此str_arr
充当指针,所以 当我们使用arraysize(str_arr)
时,这意味着我们正在发送地址arraysize
功能。(如果我错了,请纠正我。)
我必须在这里纠正你。你陈述了一个正确的前提,但得出了错误的结论。
关键点确实str_arr
是main
中的数组。当数组在许多(大多数)表达式上下文中衰减为指针时,这在初始化对数组的引用时不适用。这就是为什么声明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>
将是您需要传递给各种函数的数组的首选类型。
答案 4 :(得分:0)