2016-11-11 6 views
1
#include <stdio.h> 
int lcm(int ,int); 
int main() 
{ 
    int a,b,f; 
    printf("Enter the numbers:"); 
    scanf("%d %d",&a,&b); 
    f=lcm(a,b); 
    printf("LCM of %d and %d : %d",a,b,f); 
    return 0; 
} 

int lcm(int a,int b) 
{ 
    static int x=1; 
    if(x%a==0 && x%b==0) 
     return x; 
    x++; 
    lcm(a,b); 
} 

このコードではエラーが発生していません。正解を返しますが、lcm関数の戻りキーボードなしで値がメイン関数に返される方法を教えてください。 "lcm(a、b);" !!説明してください !!リターンが再帰リターン関数で使用されないとどうなりますか?

+7

未定義の動作が発生します。 –

+0

残念ながら戻り値はmainで使用されています。この動作は、aとbの両方が1の場合にのみ定義されます。 – 2501

+2

"このコードではエラーが発生していません" - いいえ、Cの警告も同様に深刻なものになります! – Olaf

答えて

1

ここでは、このコードは何のエラーも与えていません。正しい答えを与えていますが、lcm関数lcm(a、b)の戻りキーボードなしで値がメイン関数に戻っているのはどうですか?

C言語ではコードが正しくないため、足で自分を撃つことができます。これはundefined behaviourと呼ばれます。あなたのコードは、(1,1)を除くすべての引数に対して未完成の動作を示します。あなたが(1,1)を渡すと、最初のリターンが最初にトリガされます。

具体例については、What Every C Programmer Should Know About Undefined Behaviorをお読みください。

これは言いましたが、戻り値そのものを無視するのは未定義の動作ではありません。 のみ未定義呼び出し元は関数の戻り値を使用します。 たとえば、戻り値がコード内のscanf()およびprintf()関数をすでに無視していても有効です。しかし、になりますが、戻り値scanf()がスキャンに成功したかどうかを確認してください。関連するノートでは、エラーが発生しやすいので、scanf() use is discouraged in C

しかし、あなたのコードでは、戻り値(f=lcm(a,b);)を使用します。したがって、未定義の振る舞いがあります(前述の例外があります)。

しかし、あなたのようにメインlcm()への呼び出しを記述した場合:

scanf("%d %d",&a,&b); 
lcm(a,b); 
... 

(それはあなたのプログラムには有用ではないだろうが)その後、任意の未定義の動作ができなくなります。

+0

"呼び出し元が関数の戻り値を使用するのは未定義です。" - 戻り値を無視するかどうかにかかわらず、値を返さないでvoid以外の関数を呼び出すのは* UBだけです。私はリファレンスを探してみましょう.. –

+0

だからええ。値が無視されても問題ありません。 [標準](http://port70.net/~nsz/c/c11/n1570.html#6.9.1p12)にはぼんやりとした段落があります。*関数を終了する}が到達し、値関数呼び出しの呼び出しが呼び出し側によって使用されている場合、その動作は未定義です。* Blurryは、 'return'ステートメントの存在によって条件付けされていないためです。 –

+0

@EugeneSh。私はそこに何がぼやけているのか分かりません。 6.9.1,12はかなり明確です。 * "}は、関数を終了する関数に到達する" *(C++は "関数の終わりから流れ出す"という用語を使用します)*)は、それが返される関数にreturn文がないことを意味します* return文があればそれを返す)。 –

関連する問題