<分区>
谁能解释一下为什么 (numbers + 1) 在这段代码中被认为是一个数组?
int sum(const int numbers[], const int l) {
return l == 0 ? 0 : numbers[0] + sum(numbers + 1, l-1);
}
标签 c++
<分区>
谁能解释一下为什么 (numbers + 1) 在这段代码中被认为是一个数组?
int sum(const int numbers[], const int l) {
return l == 0 ? 0 : numbers[0] + sum(numbers + 1, l-1);
}
最佳答案
每当您将函数的参数声明为 f(const int numbers[])
,或者实际上是 f(const int numbers[N])
,它正在衰减为指针。在您的情况下,声明 f(const int numbers[])
实际上与 f(const int* numbers)
相同(语法糖)。
但是,数组与指针不同(记住这一点!!!!!!)。您可以通过引用传递数组,因此声明
f(int (&numbers)[N]) // numbers is a reference to the array that is passed as a parameter
与声明不一样
f(int* numbers) // even if numbers is an array, it decays to a pointer here
在第一种情况下,您可以通过例如推导数组的大小模板,而在最后一种情况下没有办法做到这一点(假设您将数组传递给 f(int*)
)。
数组大小推导的示例以及为什么数组在 C++ 中比指针“更多”:
#include <iostream>
#include <cstddef> // for std::size_t
template<typename T, std::size_t N>
std::size_t arr_size(T(&)[N]) // pass the array by reference, infer its size
// we don't care about the name, so can just use T(&)[N] instead of T(&numbers)[N]
{
return N;
}
int main()
{
int arr[10];
std::cout << "The size of the array is: " << arr_size(arr); // displays 10
}
归根结底,你必须记住,只要你有一个指针参数,你就可以将一个数组传递给它,它会衰减为一个指针。然而,数组更“进化”了,可以用它们做更多的事情,并且与指针不同。最后一点很重要,因为许多(糟糕的)书籍/老师告诉你数组与指针相同。 不,它们不一样。
因此,numbers+1
在您的例子中只是一个地址,例如指针,不是数组。 numbers
衰减为指向 &numbers[0]
的指针,递增 1 使其成为指向第二个元素的指针。
他们差异的另一个例子:
#include <iostream>
void g(int (&)[16]){} // reference to array of 16 ints, need EXACTLY the same type (i.e. same dimension also)
void h(int*){} // pointer, arrays will decay to it, regardless of their dimension
int main()
{
int arr[10];
// g(arr); // compile time error, arr is not of the same type of `int [16]`
// works if you declare int arr[16], now you have the same array type
h(arr); // OK, arr is being decayed to a pointer, dimension doesn't count anymore
}
可调用的策略
不要用另一个答案来污染这个,一些可能有用的事情......
#include <iostream>
#include <vector>
#include <iterator>
// generic sequence iterators
template<class Iter>
void do_something(Iter beg, Iter end)
{
for (;beg != end; ++beg)
std::cout << *beg << ' ';
std::cout << '\n';
}
// base+length specified overload
template<class T>
void do_something(const T* ar, std::size_t len)
{
// invoke iterator version
do_something(ar, std::next(ar,len));
}
// fixed array overload
template<class T, std::size_t N>
void do_something(T (&ar)[N])
{
// invoke iterator version
do_something(std::begin(ar), std::end(ar));
}
// sequence container overload
template<class T, template<class,class...> class S, class... Args>
void do_something(const S<T,Args...>& seq)
{
// invoke iterator version
do_something(std::begin(seq), std::end(seq));
}
int main()
{
int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };
do_something(std::begin(ar), std::end(ar)); // iterators
do_something(ar); // fixed array
do_something(ar+1, 9); // base+length specified
std::vector<long> v(std::begin(ar), std::end(ar));
do_something(v); // sequence container
}
输出
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
尽情享受吧!
关于c++ - 在 C++ 中递归使用数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27872533/