如何在纯C中仅使用 一个指针 来计算 递归 数组的总和。函数原型如下:
int sum(int *arr);
这是我的代码:
int sum(int *arr) {
int *p, *q;
p = &arr[0];
q = p + sizeof(*arr) - 1;
int total = 0;
if(p < q) {
return total + sum(++p);
}
else
return total;
}
答案 0 :(得分:2)
两个问题:
在C中,数组只是内存块,没有长度属性。可以从存储器的其他部分读取阵列末尾的不可预测数字。
在发布的代码中,显然sizeof(*arr)
用于获取指针算术q = p + sizeof(*arr) - 1
但sizeof
确定数组长度吗?让我们找出......
#include <stdio.h>
void main(){
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int * p = a;
int l = sizeof(*p);
printf("%d\n",l);
}
这会在编译时打印4
并使用gcc
而不是10
运行。
为什么4
?因为4
是int
的大小。
这表明sizeof
不会提供数组长度。
因此,函数int sum(int *arr)
将不知道何时停止读取,除非给定终止的标记值或总和的显式长度。在字符串中,终端值为0
,但这里使用0的问题在于它是一个完全有效的数字,可以添加到总和中。
大多数递归求和函数基本上是fold operations,因此需要一个累加器来存储部分结果。
现在累加器可能放在static variable中,但它通常不会这样做,因为它不是线程安全的,导致更复杂的代码,包括复制最终结果和重置累加器。
这表明包含一个accumulator
参数来保存总和。
如果我们还为长度添加参数,我们可以写:
int sum(int *arr, int len, int accumulator){
if (len==0) return accumulator;
else return sum(arr+1,len-1,accumulator+*arr);
}
或者,您可以使用函数堆栈来存储累加量并删除累加器参数,如下所示:
int sum(int *arr, int len){
if (len==0) return 0;
else return sum(arr+1,len-1)+*arr
}
但单个参数int sum(int *arr)
是不可能的,因为它缺少一个终止求和过程的参数。
答案 1 :(得分:2)
你可以使用这样的函数:
int sum(int *array, int offset, int length)
{
if (offset < length - 1)
return (array[offset] + sum(array, offset + 1, length));
else
return (array[offset]);
}
数组表示您的数组/偏移数组中的位置,因此当您使用该函数时,使用0和length将是数组的长度。
问候。