2017-07-30 7 views
1

私はsetjmp()longjmp()を使用してc言語で(つまり、pythonでyieldキーワードを使用して実装されている)fibonacci発電シーケンスのようなものを作るしようとしていた。エラーsetjmp関数を使用してフィボナッチジェネレータのシーケンスを作成する()とlongjmp()

#include <setjmp.h> 
#include <stdio.h> 

jmp_buf mainTask, childTask; 
void child(void); 
int main(void) { 
    long i = 1; 
    if (!setjmp(mainTask)) { 
     printf("%ldth Parent\n", i++); 
     child(); 
    } 
    for (int j = 0;j < 9;j++) { 
     printf("%ldth Parent\n", i++); 
     if (!setjmp(mainTask)) { 
      longjmp(childTask, 1); 
     } 
    } 
} 
void child (void) { 
    int c = 0; 
    long i = 1; 
    long j = 1; 
    long k = 0; 
    for (;;) { 
     printf("i is:%ld j is:%ld\n", i, j); 
     k = i + j; 
     if(i <= j) 
      i = k; 
     else 
      j = k; 
     c++; 
     printf("%dth fib number:%ld\n", c, k); 
     if (!setjmp(childTask)) longjmp(mainTask, 1); 
    } 
} 

最初の番号のみが正しく動作します。

*更新:私は、... 2,3,5,8,13期待が、それは2生成、及びnextsは

+0

質問を実際の出力と期待される出力で編集できますか? –

+2

そして、実験のためにこれをやっていることを本当に願っています。なぜなら、純粋なプログラマは、生産コードのためにこのようなスパゲッティコードを作成することはないからです。 –

+0

uは正しく考えています。私は自分自身に挑戦したいです – arianpress

答えて

2

残念ながら、あなたのプログラムの動作は未定義た:変数が宣言された関数呼び出しが終わったとき、正常または自動変数が破壊されます。 ISO 9899引用

:1999、7.13.2.1 longjmp機能、段落2:

longjmp機能は、同じ呼び出しで setjmpマクロの最も最近の呼び出しによって保存された環境を復元対応する jmp_buf引数のプログラム。 を含む関数はsetjmpマクロの呼び出しが実行208を終了した場合、中間に)そのような呼び出し、またはがなかった場合、又はsetjmpマクロの 呼び出しが有する識別子の範囲内であった場合可変的に 変更された型と実行はその範囲を中間に残しました動作は定義されていません

[...]

208)。例えば、別のlongjmp呼び出し関数でsetjmp呼び出しに 転送先にネストされた呼び出しのセットで生じたためreturnステートメントまたはを実行することによって。

(重点鉱山。)

childsetjmp呼び出しにコントロールを転送するmain試みであなたの

 longjmp(childTask, 1); 

声明が、childへの呼び出しは、すでに(longjmp(mainTask, 1)て)戻ってきました。

これは簡単に修正可能ではありません。 Cでは、2つのアクティブな機能を同時に実行することはできません。 (returnまたはlongjmpを使用して)関数から戻ると、その呼び出しを再入力することはできません。

+0

ありがとうございます。 :) –

0

はあなたが使用する必要があり、このerror解決するために(間違った番号15digits)間違っている static variableまたはglobal variable。プログラムが実行されている間に変数staticがメモリに残ります。

#include <setjmp.h> 
#include <stdio.h> 

jmp_buf mainTask, childTask; 
void child(void); 
int main(void) { 
    long i = 1; 
    if (!setjmp(mainTask)) { 
     printf("%ldth Parent\n", i++); 
     child(); 
    } 
    for (int j = 0;j < 9;j++) { 
     printf("%ldth Parent\n", i++); 
     if (!setjmp(mainTask)) { 
      longjmp(childTask, 1); 
     } 
    } 
} 
void child (void) { 
    static int c = 0; 
    static long i = 1; 
    static long j = 1; 

    long k = 0; 
    for (;;) { 
     printf("i is:%ld j is:%ld\n", i, j); 
     k = i + j; 
     if(i <= j){ 
      i = k; 
     } 
     else{ 
      j = k; 
     } 
     c++; 
     printf("%dth fib number:%ld\n", c, k); 
     if (!setjmp(childTask)) longjmp(mainTask, 1); 
    } 
} 
+0

それは動作しますが、グローバル変数は必要ない方法のために考えています – arianpress

+0

ok @arianpress。直した 。これで試してみることができます。 :) –

+1

あなたのコードはまだ未定義の動作をしています。私の答えを見てください。 – melpomene

関連する問題