我正在尝试在C中编写一个代码,它允许在数组中最多输入10个元素(自然数),识别数组中的所有完美数字,并执行所有非完美数字的乘积。 / p>
Euclid证明2 ^ {p-1}(2 ^ p-1)是一个偶数完美的数,每当2 ^ p-1 是素数(Euclid,Prop.IX.36)。例如,前四个完美 数字由公式2 ^ {p-1}(2 ^ p-1)生成,其中p为素数 数量,如下:对于p = 2:2 ^ 1(2 ^ 2-1)= 6对于p = 3:2 ^ 2(2 ^ 3-1)= 对于p = 5:28 ^ 2(2 ^ 5-1)= 496,对于p = 7:2 ^ 6(2 ^ 7-1)= 8128。 (来源:维基百科)
当我编译程序时,我会重复三次或更高次数的完整数字声明。
e.g:
... t [10] = {1,1,1,1,1,1,1,1,1,6}
'6'是一个完美的数字。 '6'是一个完美的数字。 '6'是一个完美的数字。 ...
我也得到了一些奇怪的产品。
e.g:
... t [10] = {1,1,1,1,1,1,1,1,1,28}
'28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 '28'是一个完美的数字。 ... 非完美数字的乘积是-1677721600
我真的很新c,我似乎无法弄清楚我做错了什么,但我也不会给出一份讲义。我们非常感谢一些指导。
#include <stdio.h>
#define MAX_BOUND 9 /*Array's bound*/
main() {
int i, /*array index*/
t[i],
d, /*divider*/
sum, /*result for perfect number validation*/
product; /*product of all non-perfect number in array*/
i = 0;
printf("Enter your natural numbers. \n");
for (i = 0; i <= MAX_BOUND; i++) {
printf("Number %d : ", i + 1);
scanf( "%d", &t[i]);
}
i = 0;
product = 1;
for (i = 0; i <= MAX_BOUND; i++) {
d = 1;
sum = 0;
while(d < t[i]) {
if(t[i]%d == 0)
sum = sum + d;
d++;
if(sum == t[i])
printf("%d is a perfect number. \n", t[i]);
else
product = product * t[i];
}
}
printf("The product of the non-perfect numbers is %d \n", product);
getch();
}
答案 0 :(得分:2)
“奇怪的产品”(例如负面)是由integer overflow引起的。您的产品为int
,使其更大,例如long long
。
您应该for
使用i
,而不是while
。检查数字是否完美的代码应放在单独的函数bool isPerfect(int number)
中。
您的意思是sum = 0
,而不是somme = 0
。声明t[i]
也是错误的。
更正版本(使用gcc -std=c99 file.c
编译):
#include <stdio.h>
#include <stdbool.h>
#define MAX 10
int t[MAX];
bool isPerfect(int number)
{
int sum = 0;
for (int d = 1; d < number; ++d) // optimization: you can iterate until sqrt(number)
{
if (number % d == 0)
{
sum += d;
}
}
return sum == number;
}
int main()
{
printf("Enter your natural numbers. \n");
for (int i = 0; i < MAX; ++i)
{
printf("Number %d: ", i + 1);
scanf("%d", &t[i]);
}
long long product = 1;
for (int i = 0; i < MAX; ++i)
{
if (isPerfect(t[i]))
{
printf("%d is a perfect number. \n", t[i]);
}
else
{
product = product * t[i];
}
}
printf("The product of the non-perfect numbers is %lld \n", product);
return 0;
}
答案 1 :(得分:1)
在您对数组的声明中,您有未定义的行为,因为您使用了错误的大小:
main() {
int i,
t[i],
d, /*divider*/
sum,
product;
i = 0;
printf("Enter your natural numbers. \n");
while (i <= 9) {
printf("Number %d : ", i + 1);
scanf( "%d", &t[i]);
i++;
}
你可能想宣布
t[MAX_BOUND+1];
(MAX_BOUND
会出错,因为您使用了元素t[MAX_BOUND]
)。
在声明t
时,i
具有不确定的值(不一定是0)。
对于不确定的数组大小,访问t[i]
会产生更多不确定的值(如果i >= sizeof t / sizeof t[0]
,则会再次出现未定义的行为。)
印刷部分,
if(sum == t[i])
printf("%d is a perfect number. \n", t[i]);
else
product = product * t[i];
在用于确定除数和的循环之后应该移动。在循环内部,您将product
与t[i]
乘以t[i] - 1
次(如果其中一个中间总和等于t[i] - 2
,则为t[i]
){ {1}}并不完美,如果t[i]
完美,则为t[i]/2-1
次。此外,您打印t[i]
次以获得完美数字,如果其中一个中间总和等于t[i]/2
,则打印一次(我忽略了奇数完全数的理论可能性,如果有的话) ,它们对于t[i]
来说太大了。
这样做会产生正确的输出。