4

我正在尝试用 C 编写一个代码,该代码允许在数组中最多输入 10 个元素(自然数),识别数组中的所有完美数字,并对所有非完美数字进行乘积。

Euclid 证明了 2^{p−1}(2^p−1) 是一个偶数,只要 2^p−1 是素数(Euclid,Prop. IX.36)。例如,前四个完美数由公式 2^{p−1}(2^p−1) 生成,具有 pa 素数,如下: 对于 p = 2: 2^1(2^2−1 ) = 6 对于 p = 3:2^2(2^3−1) = 28 对于 p = 5:2^4(2^5−1) = 496 对于 p = 7:2^6(2^7− 1) = 8128。(来源:维基百科)

当我编译程序时,我得到了三次或多次重复的完美数声明。

例如:

... t[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 6}

“6”是一个完美的数字。“6”是一个完美的数字。“6”是一个完美的数字。...

我也得到了一个奇怪的产品。

例如:

... 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();
}
4

2 回答 2

2

“奇怪的产品”(例如负数)是由整数溢出引起的。例如,您的产品是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;
}
于 2012-12-02T14:21:44.720 回答
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];

应该在用于确定除数和的循环之后移动。在循环内部,你乘以productt[i]时间t[i] - 1(或者t[i] - 2如果中间和之一等于t[i]) ift[i]不完美,并且t[i]/2-1乘以 ift[i]是完美的。此外,您打印t[i]/2完美数的时间,如果中间和之一等于,则打印一次丰富的数字t[i](我忽略了奇数完美数的理论可能性,如果有的话,它们对于 来说太大了int)。

这样做会在此处产生正确的输出。

于 2012-12-02T14:50:12.257 回答