maruさん、bunさん、Blue さん、tetrapodさん、仲澤@失業者さん、hirocco さん、レ
スありとうございます。
maruさん
>std::map<std::string, ddfunc_type*> func_table;
なるほど、いい手ですね。検討してみます。
bunさん、
>double (*myclass::myfunc(char const *))(double) { ... }
ありがとうございます。理解できたような気がします。
double (*p)(double)myclass::myfunc(char const *) {...}
ってこんなことしてました。
tetrapodさん、
>C/C++ のポインタ関連の記述方法は不必要に複雑/煩雑な上に、この例は
>typedef を使って1段階簡単にしてやるととても読みやすくなる典型なわけで
>あえてプレーンな書き方をせずに typedef したものにしておく・・・
同意させていただきます。
>typedef double ddfunc_type(double);
>ddfunc_type* myclass::myfunc(const char* p) { ... }
で動作しましたが、ついでに変数もこのtypedef で
ddfunc_type * func ;
とやってみましたが、コンパイルエラーがでます。関数の宣言のみに使える?というの
は、なんともわたしの今までもっていた'typedef'のイメージと全然ちがいます。
でも現実的にはこの表現にすることを選択すると思います。
仲澤@失業者さん、
>「よくわからないときは無視してよい」という考え方は多くの場合、誤りです(vv;)。
おっしゃるとおりですね。すいません。すぐわからないとほっといてしまいます。
hirocco さん、
>私は基本的にできるだけ複雑にしない派ですねぇ
>後で自分でも読めなくなっちゃうんで。。。
わたしも、’簡単にする派’です。そのときは、集中しているので、いろいろ考え付き
ますが、あとで見たとき、わからなくなるのは、つらいですから・・・
PS)tetrapodさん、この課題ちょっとまってくださいませ。
(わたしも、うら若き?なので、食事の支度をしなければ・・)
>ぢゃあここで課題
>・関数ポインタのテーブル functable (bun 氏の Func[]) を記述して味噌
>・POSIX の signal 関数は void (*signal(int, void (*func)(int)))(int); という
プロトタイプ宣言される。解読して味噌。 typedef を使って簡単にして味噌。
tetrapodさん、課題への解答。これでいいですか?
static double (*functable) (double)[FV_Last] ;
functable[FV_SIN] = sin ;
functable[FV_SIN] = cos ;
functable[FV_SIN] = tan ;
void (*signal(int, void (*func)(int)))(int); ということは、
第一引数がint型で
第二引数が「int型の引数ひとつ、返り値なしの関数」のポインタ
で
返り値が「int型の引数ひとつ、返り値なしの関数」のポインタ
の名前がsingalという関数なので、
typedef void vifunc_type (int) ;
vifunc_type *signal(int,vi_func_type *) ;
ちょっと訂正します。
enum TFunc {
FV_SIN=0,
FV_COS,
FV_TAN
} ;
static double (*functable) (double)[FV_Last] ;
functable[TFunc::FV_SIN] = sin ;
functable[TFunc::FV_COS] = cos ;
functable[TFunc::FV_TAN] = tan ;
signal の方は正解。
functable のほうは不正解。自分でコンパイラに食わせてみた?エラーになるはず。
もう少し考え方のヒントを
C / C++ の変数宣言を typename variablename; と考えちゃダメ。
typename arrayname[elementcount]; と考えちゃダメ。
型は変数名の前後にわたって書かれることがある。
identifier( のように名前+開き丸カッコがあると、その名前は関数名
identifier[ のように名前+開き角カッコがあると、その名前は配列名
今、「関数へのポインタ」の配列を作ろうとしているわけだ。
なので、この配列変数の宣言の際には functable[要素数] という記述が必ず現れる。
ここで気をつける点は
・名前と角カッコは場所が分離しない。
・カッコ(丸、角)の後ろに何か文字が来ることは、ごく当たり前。
double (*functable[3])(double); // が正解。
> ddfunc_type * func ;
はできるはずだが。ウチではコンパイルエラーにならないし。
ddfunc_type f; はダメだけど。
tetrapod さんレスありがとうございます。
ここのところは、違和感があったところなので、ご説明いただいて、
たいへんうれしく思います。
>C / C++ の変数宣言を typename variablename; と考えちゃダメ。
>typename arrayname[elementcount]; と考えちゃダメ。
>型は変数名の前後にわたって書かれることがある。
>identifier( のように名前+開き丸カッコがあると、その名前は関数名
>identifier[ のように名前+開き角カッコがあると、その名前は配列名
>今、「関数へのポインタ」の配列を作ろうとしているわけだ。
>なので、この配列変数の宣言の際には functable[要素数] という記述が必ず現れる。
>ここで気をつける点は
>・名前と角カッコは場所が分離しない。
>・カッコ(丸、角)の後ろに何か文字が来ることは、ごく当たり前。
理解する上で、たいへん大きなコメントとなりました。
ありがとうございました。
ひとまず、解決とさせていただきます。
PS’現在、hirococoさんのご指摘のあったとおり、関数名を文字列にせず、enumでの
宣言コンスタントに変えているところです。
PS’他のみなさんもありがとうございました。
結局、switchにしちゃいました。maruさん、が書いてくださった、C標準ライブラリーの
mapを使うのもいいんですが、ユーザ定義関数も視野にいれると、この書き方がいちば
ん、あとで広げやすそうなので、そうしました。みなさん、ご意見、ご指導、ありがと
うございました。
switch(Sc2){
case CSToken::SSyntacticCategory2::SC2_SIN:
AnsData = sin(dData[0]) ;
break ;
case CSToken::SSyntacticCategory2::SC2_COS:
AnsData = cos(dData[0]) ;
break ;
case CSToken::SSyntacticCategory2::SC2_TAN:
AnsData = atan(dData[0]) ;
break ;
:
: