3

関数の現在の状態をC/C ++の別の関数に渡す方法はありますか?私は現在の状態によってすべてのパラメータとローカル変数を意味します。例えば:

void funcA (int a, int b)
{
    char c;
    int d, e;
    // Do something with the variables.
    // ...
    funcB();
    // Do something more.
}

void funcB()
{
    // funcB() should be able to access variables a,b,c,d & e
    // and any change in these variables reflect into funcA().
}

funcB()ある種の関数が必要な場合、コードの状態は良くありません。しかし、それは達成できますか?

これは、誰かが複数のパラメーターを使用して長いメソッドをリファクタリングし始めている場合に役立ちます。

4

9 に答える 9

7

一般的な構造体を導入します。

struct State {
    char c;
    int d,e;
};

void funcA(int a, int b){
    State s;
    s.d = 1234; // ...
    // ...
    funcB(s);
}

void funcB(State& s)
{
    //...
}
于 2010-02-04T13:36:36.547 に答える
5

gccは、CのPascalのような拡張、つまりネストされた関数をサポートします。

#include <stdio.h>

int main(void)
{
    int a = 1, b = 2;

    void foo(void)
    {
        printf("%s: a = %d, b = %d\n", __FUNCTION__, a, b);
    }

    printf("%s: a = %d, b = %d\n", __FUNCTION__, a, b);

    foo();

    return 0;
}

これを--nested-functionsでコンパイルします。

$ gcc -Wall --nested-functions nested.c -o nested

そしてそれを実行します:

$./nested
main: a = 1, b = 2
foo: a = 1, b = 2

もちろん、これは移植性がありませんが、gccのみを使用していて、レガシーコードが多すぎて書き直せない場合は、これが適切な解決策になる可能性があります。

于 2010-02-04T14:13:05.217 に答える
3

最初のものよりもエレガントかもしれない別のもの。静的メンバーを持つ構造体を使用します。

struct SomeAlgo {
    SomeAlgo()
    : c(0), d(0), e(0) // Initialize common variables
    { }
    void funcA(int a,int b)
    {
        c = 1234; //...
        // ...
        funcB();

    }
    void funcB() // You may put it in the private section.
    {
        // Simply use c,d,e here.
    }
private:
    char c;
    int d,e;
};

使用法

SomeAlgo alg;
alg.funcA(3,4);

編集:メンバーを静的ではないようにしました。その方がいい。

于 2010-02-04T14:14:34.807 に答える
2

気になるすべての状態を保持する構造体を作成します。

構造体の観点から両方の関数を記述します。つまり、それらは唯一のパラメータとして構造体のインスタンスを取り、すべての状態が構造体に保存されます。

struct foo {  int d; int e; char c ; } fooinstance;

void afunc( struct foo fi);
void bfunc( struct foo fi);

void afunc( struct foo fi ) {
  // do stuff with fi
  f1.d += fi.e ;
  fi.c++;
  // call b
  b(fi);
}

次に、structインスタンスをaからbに渡します。より効率的なのは、構造体へのポインターを渡すことですが、構造体を渡すことは機能します。

于 2010-02-04T13:35:53.133 に答える
1

いいえ、原則としてデータはすべて利用可能であり、すべてスタック上にありますが、インラインアセンブリやポインターなどをいじり始めない限り、Cはそれらにアクセスするメカニズムを提供しません。やりたいことではありません。必要なものだけを渡す方がよいでしょう。

于 2010-02-04T13:35:08.753 に答える
1

これは、誰かが複数のパラメーターを使用して長いメソッドをリファクタリングし始めている場合に役立ちます。

この特定の問題を克服するには、オブジェクトを使用して、一般的に使用されるパラメーターのいくつかをコンストラクターでオブジェクトのメンバーにバインドするだけです。そして、(これらの長いパラメーターのリストを受け入れる)関数をメンバー関数にするよりも。

于 2010-02-04T13:37:44.737 に答える
1

最善の解決策は、変数を構造体に配置し、他の関数を参照してこの構造体を渡すことです。ただし、マクロを使用できる別の解決策があります。マクロは同じスコープ内の任意の変数にアクセスできますが、このアプローチはお勧めしません。

于 2010-02-04T13:48:12.070 に答える
0

このようなことを行うと、モジュール性と関数作成の目的全体が損なわれます。funcB他の特定の関数、特に依存する変数を定義する関数によってのみ呼び出すことができます。これは、を呼び出す新しいコードを書いている人にはまったくわかりませんfuncB

他の人が示唆しているように、私はこの目的のためだけに構造体を作成するか、参照によって必要なすべての変数を渡して、何がfuncB依存しているのかを明確にします。

于 2010-02-04T13:40:18.117 に答える
-3

おそらくやりたいことは、関数をクラスにカプセル化し、そのシングルトンインスタンスを作成することです。これらの関数間で共有したい状態は、オブジェクトをインスタンス化し、それらのメソッドを呼び出すことによってOOPで技術的に発生することです。

したがって、C ++がオプションである場合(CにはOOPがないため)、そのソリューションを使用することをお勧めします。

別のアプローチはラムダ/クロージャを使用することですが、これらの言語構造をサポートしていないため、C /C++ではオプションではありません。

編集:コード全体でこれらを正しく処理する方法を知っている場合にのみ、シングルトンを使用してください...

于 2010-02-04T14:20:43.330 に答える