10

こんにちは友達、
関数ポインタの配列を使用するにはどうすればよいですか?
上記のリンクが表示されている場合は、関数ポインタがどのように機能するかを示しています。
ここで問題は、なぜ関数ポインタを選択する必要があるのか​​ということです。
関数呼び出しを直接使用できないのはなぜですか?
関数ポインタで得られるメリットは何ですか?
例えば

enum{a, b, c};
void A();
void B();
void C();
void (*fun[3])() = {A, B, C};

Now when I need to call a function I am doing like,
fun[a](); // This calls function A
// And so on...

関数呼び出しでも同じことができます

関数A、B、またはCを直接呼び出す必要がある場合のように。

A();
B();
or 
C();

では、なぜfunction pointerですか?

4

7 に答える 7

14

関数ポインタを使用する理由はたくさんあります。特に、Cで一般的に行う場合はそうです。

それらが使用されているのを見る主な場所は、関数の引数としてです。たとえば、関数bsearchでは、関数ポインタとして渡される比較関数を使用して、アイテムを比較し、データを並べ替えます。

void *bsearch(const void *key, const void *base,
                     size_t nmemb, size_t size,
                     int (*compar)(const void *, const void *));

そのbsearch比較関数だけがデータのタイプを知る必要があるので、それは一般的であり、あらゆるタイプのデータをソートすることを可能にします。


もう1つは、複数のチェックを回避することと関係があります。すなわち。

void makePizza(void) { }

void bakeCake(void) { }

iWantPizza = 1;
...
if (iWantPizza)
   makePizza();
else
   bakeCake();
/* want to call the same function again... */
if (iWantPizza)
   makePizza();
else
   bakeCake();

..

/* alternative */
void (*makeFood)(void) = iWantPizza ? makePizza : bakeCake;

makeFood();
/* want to call the same function again... */
makeFood();
于 2012-06-04T06:41:41.110 に答える
8

ここで問題は、なぜ関数ポインタを選択する必要があるのか​​ということです。
関数ポインタで得られるメリットは何ですか?

非同期メカニズムを実装する必要がある場合は、関数ポインターを使用します。何か
が起こった ときに非同期的に呼び出される関数が必要です。どの関数を呼び出すかをどのようにして知ることができますか? すべての関数のアドレスは一意であるため、関数アドレスを使用して保存する必要があります。この関数アドレスをどこに保存しますか?関数ポインタ



于 2012-06-04T06:33:34.760 に答える
7

あなたが示した例では、もう1つ行うことができます。

いくつかのデバイス操作のために実行する必要がある機能の束があるとしましょう。簡単な方法で、すべての関数呼び出しを別のマスター関数に記述して、そのマスター関数を呼び出すことができます。

これを行う別の方法は、すべての関数名を中括弧で囲み、関数ポインターとループを使用してそれぞれを呼び出すことです。それは賢く見えます。それがどのように役立つかはわかりませんが、Linuxカーネルコードで見ました。


ここでのすべての答えに同意します。これとは別に、関数ポインタを使用するという私自身の判断がいくつかあります。

いくつかの複雑な数学計算の例を見てみましょう(フィボナッチの印刷、積分、フーリエXformなど)。

プログラムで何度も使用する関数FX(複雑な数学計算などを実行します)があります。この関数は、さまざまなジョブで使用されます。

プログラムを数か月使用した後、一部の作業では機能を改善でき、一部の作業では現在の機能が最適であることがわかります。あなたは何をしますか?新しい関数を作成し、すべての場所で関数名を変更します。

あなたがより良い何かを見つけるたびに、あなたは同じことをするつもりです。

代わりに、作業ごとに異なる関数ポインタを使用してください。初期段階では、すべてのポインターが1つの関数を指すことができます。いくつかの作業に適した関数を見つけたら、ポインターをそらすだけで完了です。


別のシナリオを考えてみましょう。ここに、携帯電話のOSのような本当の大きなコードがあります。(完全には開いていませんが、半分コンパイルされています)。特定のハードウェア用にBluetoothドライバーを追加する必要があります。

これで、OSで使用できるオプションを追加することも、残すこともできます。

多くの場所からBluetoothをオン/オフにする必要があるかもしれません。

つまり、OSが行うことは、Bluetoothをオンにして、必要な場所で使用する関数ポインターを作成することです。このコードはすでにコンパイルされているため、コードを追加することはできません。しかし、できることは、関数を記述して、そのポインターが関数を指すようにすることです。

これは私がAndroidOSですでに見たものです。(正確ではありませんが、より近くにあります)

于 2012-06-04T09:14:27.733 に答える
5

私の経験では、関数ポインタは主に、関数をパラメータとして別の関数に渡すために使用されます。

コードを見ると、配列と同じように使用できるため、配列全体(数百の関数ポインターで構成される可能性があります)をループするだけで、すべてを実行できます。

于 2012-06-04T06:31:29.277 に答える
4

関数ポインターは、関数のアドレスを指すポインター(変数ポインターのような)です。関数呼び出しのように間接参照すると、実際に基になる関数を呼び出します。

関数ポインタの主な利点は、たとえば、パラメータとして別の関数に渡すことができることです...

于 2012-06-04T06:30:50.630 に答える
4

関数ポインタと関数呼び出しの違いは何ですか?

これは、「今すぐナショナルギャラリーに連れて行ってください」ではなく、「ナショナルギャラリーの住所を教えてください(後で行きたいので、準備をしたいのですが)」とコンパイラに依頼することの違いのようなものです。しかし、私はあなたが私をそこに連れて行く方法に注意を払わないので、後で私が知ることを期待しないでください)」。重要なのは、住所/ポインターを尋ねたら、「次の日曜日の午後の大旅行」のような場所に書き留めることができるということです...これから行くのはナショナルギャラリーであることを覚えておく必要はありません。そこに着くと嬉しい驚きかもしれませんが、日曜日のエンターテイメントがすべて整理されていることがすぐにわかります。

関数ポインタでどのような利点がありますか?

さて、上記のように、関数ポインタを設定するときに、後でどこを呼び出すかを決定する必要がありますが、その決定を行う理由をすべて忘れて、後で宛先がすべて使用できるようになったことを知ることができます。あなたが実際に何かをしているとき...「私の日曜日のルーチン:10時まで寝て、​​大きな朝食を食べ、ベッドに戻り、シャワーを浴びてください。十分なお金があれば、日曜日に行ってください。午後の大きな旅行、夕食のために友達に会う」...以前の決定はあなたをギャラリーに連れて行くためにちょうど始まります。重要なのは、おなじみの日曜日のスケジュールを使い続けて、「次の日曜日の午後の大旅行」のアドレス/ポインターが、一般的なスケジュールが作成されたときに存在していなかったとしても、新しい場所に目を向けるように「ポイント」を開始できることです。

AusCBlokeの言及でよく示されている古いルーチンのあるステップでディスパッチされた宛先を変更するこの事後の柔軟性がわかりbsearchます。 qsortもう1つの典型的な例です。任意のものの配列を効率的にソートする全体像のロジックを知っていますが、実際に使用している2つのものを比較するためにどこに行くかを指示する必要があります。

于 2012-06-09T06:51:59.897 に答える
1

これらは良い例であり、特に上記のUrvishの最初のものです。同じことを考えたのですが、答えは純粋にデザインだと思います。私の考えでは、これらは同じ結果です。関数をポイントしてa + bを取得することも、関数を定期的に呼び出してa + bを取得することもできます。SOの例では、通常、これらは小さくて些細なものです。説明のために。 しかし、10k行のCプログラムがあり、変更を加えたために何かを50回変更しなければならなかった場合、関数ポインターを使用する理由をすぐに理解できるでしょう。

また、OOP言語の設計とOODの背後にある哲学を理解することもできます。

于 2014-05-31T15:26:03.653 に答える