我创建了一个找到除数之和的方法.使用while语句我可以在EOF之前输入最多10个整数.在while语句中,我得到sum = sum_divisor的输出并打印出sum.
如果我输入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;}解决方法 您应该在函数中将sum初始化为零.否则,它将被设置为某个任意值,而else块将具有任意结果.
换句话说,改变:
int sum;
成:
int sum = 0;
当然,一旦你完成了这个,就没有必要为x小于1的情况明确地做任何事情.另外,初始if是多余的,因为当x小于1时,for body将不会执行,所以你可以逃脱:
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 -> 1016 -> 26
这几乎可以肯定是因为对函数的每次调用都是为堆栈帧重用相同的内存,包括变量sum,所以sum只是每次添加(传入的参数大于1).
然而,这仅仅是实现的工件,它不是由标准保证的,它在C11中非常清楚地表明6.7.9初始化/ 10:
If an object that has automatic storage duration is not initialized explicitly,its value is indeterminate.
换句话说,不要依赖于此.
并且,除此之外,它是一个数学假设,如果数字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;}总结
以上是内存溢出为你收集整理的c – 除数之和(除了它本身)全部内容,希望文章能够帮你解决c – 除数之和(除了它本身)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)