2012-12-02 51 views
4

我想在C中編寫一個代碼,它允許在數組中最多輸入10個元素(自然數),標識數組中的所有完美數字,並執行該產品所有非完美數字。完美的數字,數組,驗證和操作

歐幾里得證明,2^{-1 P}(2^P-1)爲偶數完全數每當2^P-1 爲素數(歐幾里得,螺旋槳。IX.36)。例如,前四個完美的 數字由公式2^{p-1}(2^p-1)生成,其中pa素數爲 ,如下所示:對於p = 2:2^1(2^2 -1)= 6:對於p = 5:2^4(2^5-1)= 496對於p = 7:2^2(2^3-1)= 28^7-1)= 8128. (來源:Wikipedia)

當我編譯該程序,得到了一個一式三份或完美數聲明的更高的重複。

例如:

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

回答

2

在你的陣列的聲明,你有不確定的行爲,因爲你使用了錯誤的大小:

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])如果t[i]是不完美的,並且t[i]/2-1時候,如果t[i]是完美的。此外,您打印t[i]/2次完美的數字,如果其中一箇中間總和等於t[i](我忽略奇數完美數字的理論可能性,如果有的話,它們對於int來說太大了)打印一次。

這樣做會產生正確的輸出。

+0

所以我的錯誤是我的循環集成。謝謝你,你是對的! –

3

「奇怪的產品」(例如負值)是由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; 
} 
+0

對於**和**不是**,而**等效循環如果我重新初始化** i **並添加一個計數器(例如** i ++ **)。 –

+0

長時間沒有解決問題...我想問題的核心是我的操作(他們看起來沒問題)和我的循環(更可能)。 –

+2

'For','while','do-while'在邏輯上是相等的(當實現的時候是正確的),但是當你從具體值迭代到具體值時,常用的方法是用'for'。這只是一條線,而不是3. –