c++ - 在 C++ 中递归使用数组

标签 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/

相关文章:

c++ - LevelDB TEST_ 方法前缀

c++ - 如何在 C++ 中读取格式化数据?

修改参数和/或返回新实例的方法/函数的 C++ 命名约定?

c++ - 将 POD 结构转换为派生类型

c++ - 您将如何编写可能优化为一条 SSE 指令的无符号加法代码?

C++11 递归自旋锁实现

c++搜索数字的数字

c++ - 将 int 转换为字符串/字符 C++/Arduino

c++ - data_condition 等待无效参数错误

c++ - 寻求一种在 C++ 中设置 128 位或更高位的位集的方法