编写一个从键盘读取整数的程序,并在输出中写入n的除数之和(除了它自身)。
我创建了一个查找除数之和的方法。使用while语句我可以在EOF之前输入最多10个整数。在while语句中,我得到sum = sum_divisor的输出并打印出总和。
如果输入0 0 0 4 5 6 12,则输出应为0 0 0 3 1 6 16。 我得到的输出是0 0 0 3 4 10 26.如何才能使它不会将sum_divisor添加到前一个总和?
#include <stdio.h>
int sum_divisor(int x);
int main()
{
int x;
int sum;
printf("Enter up to 10 positive integer ending with EOF:\n");
while((scanf("%d",&x)) != EOF){
sum = sum_divisor(x);
printf("%d ", sum);
}
return 0;
}
int sum_divisor(int x){
int i;
int sum;
if(x<= 0){
sum = 0;
}
else{
for(i=1;i<x;++i)
{
if(x%i==0)
sum += i;
}
}
return sum;
}
答案 0 :(得分:4)
您应该在函数中将sum
初始化为零。否则,它将被设置为某个任意值,else
块将具有任意结果。
换句话说,改变:
int sum;
成:
int sum = 0;
当然,一旦你完成了这个,就没有必要为x
小于1的情况明确做任何事情。此外,最初的if
是多余的,因为当for
小于1时,x
正文将无法执行,因此您可以使用以下内容:
int sumDivisors (int x) {
int i, sum = 0;
for (i = 1 ; i < x; i++) {
if ((x % i) == 0) {
sum += i;
}
}
return sum;
}
顺便说一句,你实际看到没有初始化的值正在积累:
0 -> 0
0 -> 0
0 -> 0
3 -> 3
1 -> 4
6 -> 10
16 -> 26
这几乎可以肯定,因为对函数的每次调用都会为堆栈帧重用相同的内存,包括变量sum
,因此每次都会添加sum
(通过 - in参数大于1)。
然而,这只是实现的工件,标准并不能保证,C11 6.7.9 Initialization /10
中明确说明了这一点:
如果没有明确初始化具有自动存储持续时间的对象,则其值为 不确定。
换句话说,不依赖于此。
而且,除了另一个之外,这是一个数学假设,如果一个数字n
均匀地划分为a
,它也会被n/a
均分。您可以利用此优势来使代码更有效(但是,与所有优化一样,您应该测量,而不是猜测)。
由于您将数字本身作为除数折扣,因此您必须将除数1
视为一种特殊情况。您还必须将完美正方形视为一种特殊情况,这样您就不会添加两次平方根。
以下代码将是一个很好的起点:
int sumDivisors (int x) {
int i, sum;
// Always return zero for -inf..1 inclusive.
if (x < 2)
return 0;
// Otherwise, 1 is factor, search for others
// up to but NOT including sqrt(x).
for (i = 2, sum = 1 ; i * i < x; i++) {
if ((x % i) == 0) {
sum += i;
sum += x / i;
}
}
// Add in sqrt(x) ONCE for a perfect square.
if (i * i == x)
sum += i;
return sum;
}
答案 1 :(得分:2)
当你在while语句中调用sum_divisor时,正在分配相同的堆栈块,因此sum变量在每次调用时都分配在相同的位置。在第一次调用时,该值为0,(但不一定),下次该值将是您在上一次调用中计算的值。
int sum = 0;
应该修复它。
答案 2 :(得分:1)
mice-own [is-special]
to step
ask mice
[
let num-surrounding-cats count neighbors4 with [count cats-here > 0]
ifelse is-special
[if num-surrounding-cats > 1 [*eaten logic*]
[ if num-surrounding-cats > 0 [*eaten logic*]]
]
end