2016-06-27 27 views
0

私は現在(主にC言語でも他の言語でも)コードを学習していますが、現在いくつかのプロジェクトでは同じ種類の「問題」に直面しています。 :C言語の任意のデータセットを扱う方法

多くの場合、データの任意のセットを扱わなければなりません。例えば、私は標準的な形式でかなりの数のコマンドを取るようなプログラムを書く必要があるかもしれませんが(例のために11としましょう)、柔軟なコードを作っています。このプロジェクトの後半に戻って、他のコマンドを追加したいのであれば、私はそう簡単にやりたいと思っています。

私のコードのどこかでこれらのコマンドの名前を手動で入力する必要があります。私が現在気に入っている方法は、構造体の配列を使用することです。各要素には、コマンド名のchar *とコマンドの機能を担当する関数ポインタが含まれています。

まだ、私は完全に私を満足させる方法でこの配列を実装していません。

私はそれから得た最も近いものがシングルトンを介したものでしたが、配列が必要なときには私はシングルトンを呼び出しましたが、それ以来、シングルトンは本質的にグローバル変数と同じ問題を抱えていることを学びました。私は依存性注入について少し学んだことがありますが、これはオブジェクト指向言語にのみ適用されるような原則です。

シングルトンを私がCでやりたいことに使用しない方法はありますか?

TL; DR: コード内に任意のデータセットを構築する必要がありますが、これをどのようにエレガントで簡単に保守可能な方法で実装できますか?

お返事いただける方に感謝します。

例:

私は、標準入力でコマンドをして、これらのコマンドを実行するために聞くのプログラムを持っています。 入力を読み込むたびに、文字列形式のコマンドの所定のリストと比較し、コマンドが一致する場合は適切なコードを実行します。

どのように文字列のセットを作成しますか?各文字列に対応する一連の関数をどのように作成しますか?どのように2つのセットを結びつけますか?あなたはどのようにこの組み合わせセットをどこにでも簡単にアクセスできるようにしますか?

これまでのところ、これに対する私の答えはされています:私は追加したい場合は

struct s_cmds { 
    char *cmd; 
    void (*func_cmd)(...); 
}; 

この方法では、関係なく、私は私のコードを作成する方法の進化:構造と

s_cmds *singleton(void) 
{ 
    static s_cmds ret[] = {{"cmd1", &func_cmd1}, {"cmd2", &func_cmd2}, ...}; 
    return (ret); 
} 

コマンドを使用すると、シングルトンに要素を追加するだけで済みます。コード内でこの配列にアクセスしたい場合は、シングルトンを呼び出すだけです。しかし、これは本質的にグローバル変数を使用するようなものですか?

「クリーナー」の方法はありますか?

+1

これを具体的な例で書き直せますか?それは現在書かれているように一般的な方法です。 –

+0

@Let_Me_Be私が現在取り組んでいる例を追加しました。私はそれが十分明確であることを望む。 – Arjofocolovi

答えて

0

あなたの質問は完全にはわかりませんが、そのサウンドからは、linked listのようなデータ構造を探していると思います。要素を追加することができます。すなわち、通常の配列で行うよりもはるかに簡単に新しいコマンドを追加できます。明らかに利点や欠点がありますが、あなたの問題について他の知識がなくても、正確に何が使えるかは言うまでもありません。

+0

例を追加しました。もう少し正確であることを願っています。リンクされたリストは、実際に私の11のコマンドを手動で作成し、このためのメモリを割り当てる必要はありません。私は、プログラムが実行されると、このコンテンツは決して変更されないことを意味します。私は動的メモリを使用する理由はないと思います。 – Arjofocolovi

+0

@Arjofocolovi Ok、この例でははるかに明確になりました。あなたの場合、はいリンクリストと動的メモリは必要ありません。今すぐあなたの解決策は、そのまま素敵です。普通の古いグローバル変数を使うことには何も問題はないことを覚えておいてください。あなたの場合、シングルトンは過度の攻撃にもなります。何かを全体的に見えるようにするには、それをぎこちなく見えるようにしてください。デザインパターンを過度に複雑にすることは役に立ちません。あるいは、コードにグローバルを持たないでください。おそらく、パラメータとしてコマンドを受け取り、正しいコマンドへの関数ポインタを返すメソッドでリファクタリングします。 – echoeida

+0

私は理解しています。しかし、私はこのプロジェクトにグローバル変数を使用することは許されていません(それは一般に私の学校では勧められていません)。その議論は、グローバルスコープのために複雑さを正確に生み出すことができ、コードのどの部分がこれらの変数を読み取って編集できるのかを知らないということです。したがって、この例ではグローバル変数を使用したと個人的に考えるでしょうか? – Arjofocolovi

1

あなたの説明は非常にあいまいですが、私はあなたがX-マクロを探していると思います:

https://en.wikipedia.org/wiki/X_Macro

それは、異なる種類の一緒に関連するコードをバインドするために使用されるコードの構文です。一般的な使用例は、エラーコードとそのテキスト表現の処理です。

+0

これはかなり面白いですし、リンクのおかげで本当に助けになるかもしれません。 – Arjofocolovi

関連する問題