2017-11-20 27 views
0

は私が定義するいくつかの時点までの特定の合計を与えるプログラムを作成しようとしています「...動作を停止しました」ここにある:再帰関数。 、

float sum(int n,float m); 

main(void) { 
    float a,m=1.0; 
    int n; 
    scanf_s("%ld", &n); 
    a = sum(n, m); 
    printf("%f", a); 
} 

float sum(int n, float m) { 
    if ((n/m) < 0.0005) { 
     return 0; 
    } 
    else { 
     return n/m + sum(n, m + 2); 
    } 
} 

(私は定義されたポイントは0.0005であることに注意してください) Iが大きい又は5に等しい値を与える場合、プログラムは、私は、このエラーを与える:

...has stopped working

Iが0.5を好きに定義されたポイントを増加させる場合も、値の数があまりにも増加を与えることができます。なぜこれが起こっていると思いますか?それをどうやって修正できますか?

+0

可能な重複https://stackoverflow.com/questions/26247345/segmentation-fault-using-scanf-:あなたは反復解法で行くことによってこれを回避することができます整数付き) – Alfabravo

+1

好奇心の高まりから、なぜint型に対して '%ld'(' long int'用)を使用していますか?あなたはそれについてコンパイラからの警告を見ましたか? – lurker

+1

@Alfabravoその質問は適用されません。 OPは、 'scanf_s'呼び出しに対して'&n'を正しく使用しています。 – lurker

答えて

1

scanf_sにフォーマット指定子は、long int *引数が必要です。あなたが渡しているのはint *です。これらのタイプは互換性がありません。間違った書式指定子を使用すると、undefined behaviorが呼び出されます。この場合、クラッシュとして現れます。

int *のための適切なフォーマット指定子が%dです:

scanf_s("%d", &n); 

EDIT:あなたが見ている

クラッシュは、おそらくスタックオーバーフローです。 sum関数は、再帰的に自身を1000 * n回呼び出します。 MSVCでは同様のエラーが表示されますが、別の制限があります。

float sum(int n, float m){ 
    float result = 0; 
    while ((n/m) >= 0.0005){ 
    result += n/m; 
    m+=2; 
    } 
    return result; 
} 
([整数でscanf関数を使用してセグメンテーションフォールト]の
+0

「n」の値が5より小さい場合、なぜOPで動作するのか説明できますか?それは未定義の振る舞いだからですか? OPは 'scanf_s()'を使用していたので、彼は '%ld'を持つためにコンパイル時にエラーが出るはずのMicrosoftを使用していなければなりません。 – PhotometricStereo

+0

@PhotometricStereo未定義の動作です。つまり、クラッシュする可能性があり、奇妙な結果をもたらす可能性があり、正しく動作するように見える可能性があります。 – dbush

+0

さて、ここでは、指定子を修正して修正しました。しかし、私はまだクラッシュしています。私は入力 "5"を与えるまで正しく動作します。私は "5"プログラムを与えると何も結果を与えずに1秒間停止し、同じエラーでクラッシュします。 –