typedef void (*afunc)();について

解決


くろのすけ  2006-11-08 08:13:06  No: 63531  IP: 192.*.*.*

くろのすけです。
typedefは、typedef A Bのようにして
A型にBという新しい名前を与えるものだと思っていますが、
下のプログラムの★の部分が、イマイチ合点がいきません。
  typedef void (*afunc)();
これでは、AとBがどれなのかわかりません。
『引数を受け取らず、返却型がvoidである関数へのポインタ』型として定義しているそうです。
分かる方、教えていただけますか?

******************************************************
#include <iostream>
using namespace std;

enum animal { Dog, Cat, Invalid };

//--- 犬 ---//
void dog()
{
  cout << "ワンワン!!\n";
}

//--- 猫 ---//
void cat()
{
  cout << "ニャ〜オ!!\n";
}

//--- メイン ---//
int main()
{
  typedef void (*afunc)();  ←★
  afunc fn[] = {dog, cat};
  int menu;

  do {
    do {
      cout << "0…犬  1…猫  3…終了:";
      cin >> menu;
    } while (menu < Dog  || menu > Invalid);
    if (menu != Invalid)
      fn[menu]();
  } while (menu != Invalid);

  return 0;
}

編集 削除
tetrapod  2006-11-08 08:32:37  No: 63532  IP: 192.*.*.*

int x; と書くと「int 型の変数 x」となりますよね
typedef int x; だと「int 型の別名 x」ができます。
型が複雑な場合も同様で
int* y; は「「int へのポインタ型」である 変数y」
typedef int* y; は「「int へのポインタ型」の別名 y」となります。
もっと読みやすい日本語にすれば y は int* 型の別名

void (*a)(); は何であるかわかりますか?これが読めなきゃ話にならない
あとは上の例と同じように「変数→別名」と置き換えるだけです。

編集 削除
くろのすけ  2006-11-08 09:10:56  No: 63533  IP: 192.*.*.*

くろのすけです。
ご回答感謝します。

>void (*a)(); は何であるかわかりますか?
これは、『引数を受け取らず、返却型がvoidである関数へのポインタ』aですね。

typedef int* int_type;
とすると、
  int* x;
を、
  int_type x;
とすることができますね?

typedef void (*afunc)();
とする場合は、
  void (*dog)();
を、
  afunc dog
とすることができる、ということでしょうか?

編集 削除
tetrapod  2006-11-08 09:40:00  No: 63534  IP: 192.*.*.*

はい。その通りです。その記述では dog は「ポインタ変数」ですから。

最初の例題にそぐうように書くなら
void dog() { ... } を指すポインタを afunc ptr_to_dog=dog; と書ける。
更に「ポインタの配列」を作るため afunc fn[]={ dog, cat }; としました。

typedef int x[3]; // だと 「int 3つの配列」の別名 x
x y; // と書くと y は配列 (int 3つ)
x z[2]; // だと z は配列の配列 「(int 3つ) が2個」

typedef を使う練習と、使わずにべた書きする練習とを繰り返すと理解が深まります。
afunc を使わずに先の fn を書ける様になれば初心者卒業でしょう

編集 削除
くろのすけ  2006-11-08 10:38:09  No: 63535  IP: 192.*.*.*

くろのすけです。
関数の例も↑に示していただいた例も、
抵抗がありますが、
よく理解出来ました。
丁寧な回答、ありがとうございました。

編集 削除