在C ++中向数组添加整数?

时间:2016-03-28 15:09:38

标签: c++ arrays recursion arguments arrayaccess

考虑:

int sum(const int numbers[], const int size){
    if (size == 0)
        return 0;
    else
        return numbers[0] + sum(numbers+1, size-1);
}

这是一个简单的递归函数,来自MIT 6.096,用于添加任意数量的整数,并且它可以工作。

我无法理解的是最后一行:

如果numbers+1是一个numbers[]数组,int如何工作,你不应该能够将一个整数添加到int[]常量?

5 个答案:

答案 0 :(得分:19)

  

"数字+ 1" work,给定的数字[]是一个int数组,你不应该能够将一个整数添加到int []常量?

没有 int[]常数numbers被衰减为指针,numbers+1是应用于传递给递归调用的参数的简单指针算法。

答案 1 :(得分:10)

作为@πάνταῥεῖ答案的附注,这里有一些关于术语的澄清:

以下是描述数组表示法的另一种方法:

短语numbers[1]也可以表示为*(numbers + 1) *运算符被称为取消引用 指针地址 numbers + 1的位置。 在这种情况下, dereference 可以被认为是读取指向的值。

因此,您示例中的代码使用的是 pointer arithmetic 。短语numbers + 1是指针表示法,指向指针numbers的第二个int位置。 size - 1是从numbers开始到数组末尾的内存位置的字节数。

关于腐朽的含义
通常,在 C数组参数的上下文中, decay 表达了数组参数经历类型和维度信息丢失的想法。您的const int numbers[]被认为(可以说)衰变int *,因此无法再提供数组大小信息。 (例如,使用sizeof()宏不提供数组的长度,而是提供指针的大小。)这也是提供第二个参数以传达大小信息的原因。

然而,在这个问题的上下文中,衰变的含义是学术性的,正如@Ben Voigt所指出的:令牌序列const int数字[],当它出现在形式参数列表中时,声明一个指针而不是一个数组。(它永远不会腐烂成指针,因为它是一个开头的指针。)

答案 2 :(得分:4)

πάντα ῥεῖ says int[]衰为int*

但是这个sum函数是穷人的解决方案,你应该更喜欢accumulate

cout << accumulate(numbers, next(numbers, size), decay_t<decltype(numbers[0])>{});

Live Example

如果你有C ++ 17和静态分配的数组,例如int numbers[size],你可以利用cbegincend

cout << accumulate(cbegin(numbers), cend(numbers), decay_t<decltype(numbers[0])>{});

我尝试将递归sumaccumulate进行基准测试,但是sum用完了堆栈空间才能达到vector大小且有意义差异,使accumulate成为明显的赢家。

我将accumulate的{​​{1}}文章的类型与init'元素的类型相关联:numbers。这样做的原因是,如果有人要回来更改decay_t<decltype(numbers[0])>{}的类型,而不更改numbers的{​​{1}}参数的类型,则会将累积分配给错误的类型

例如,如果我们使用累积行:accumulate,则init就可以了。如果我们切换到定义:cout << accumulate(cbegin(numbers), cend(numbers), 0),则会出现问题,但我们未能将int numbers[]参数更改为double numbers[] = {1.3, 2.3, 3.3, 4.3};init。这将导致10而不是11.2:http://ideone.com/A12xin

答案 3 :(得分:2)

int sum(int *num,int size)
{
int total=0;
                                   /* function to sum integer array */
if (size <= 0) return(ERROR);
while(size--) total+= *num++;
return total;
}

更快,更紧凑,更容错。

答案 4 :(得分:1)

数字是一个指针;在每次迭代中,函数sum()在数组中前进(这是数字+ 1 的作用),同时将大小减小1( - size 将起作用同样)。

当大小达到0时,这是退出条件,递归结束。