#include <stdio.h>
void sum( int a, int b ){
printf( "%d\n", a+b );
}
int main(void){
int a = 10;
int b = 20;
//char name[10] = "sum";
sum( a, b );
return 0;
}
関数名をchar型変数で代替したい
関数名をchar型変数で代替したい
下記のコードは、main関数内のint型変数a(=10),b(=20)を、合計値を出力する関数sumに渡すプログラムです。
このプログラムで、
の"sum"の代わりに、
の"name"を利用できたら便利だなと思ったのですが、可能でしょうか?
Re: 関数名をchar型変数で代替したい
>"name"を利用できたら便利だなと思ったのですが、可能でしょうか?
「"name"を利用できたら便利」というのは、具体的には、どのようなことでしょうか ?
strcpy( name, "sum" );
name( a, b ); // 30
strcpy( name, "sub" );
name( a, b ); // -10
みたいなことでしょうか ?
「"name"を利用できたら便利」というのは、具体的には、どのようなことでしょうか ?
strcpy( name, "sum" );
name( a, b ); // 30
strcpy( name, "sub" );
name( a, b ); // -10
みたいなことでしょうか ?
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: 関数名をchar型変数で代替したい
#include <stdio.h>
void sum1( int a, int b ){
printf( "%d\n", a+b );
}
void sum2( int a, int b ){
printf( "%d\n", a+a+b );
}
void sum3( int a, int b ){
printf( "%d\n", a+b+b );
}
int main(void){
int a = 10;
int b = 20;
char name[10];
/*1*/
sum2( a, b ); //関数sum2に値を渡す
/*2*/
scanf("%s",name); //例)"sum2"と入力
name( a, b ); //関数sum2に値を渡す
return 0;
}
例えになりますが上のような流れのプログラムが作成できればと思いました。もちろん上のプログラムは実行してもエラーになるのですが、/*1*/のように"sum1"や"sum2"という文字を直接記載しなくても、/*2*/のようにnameに格納された"sum1"や"sum2"が関数名としての役割をできないかなと思っています。
あたっしゅ様の書かれた に変えて試したのですがうまく動きませんでした…。string.hもちゃんと書いたのですが、すみません。
Re: 関数名をchar型変数で代替したい
こんなのはいかがですか?
#include <stdio.h> // printf, puts, scanf
#include <string.h> // strcmp
void sum1(int a, int b) { printf("%d\n", a + b); }
void sum2(int a, int b) { printf("%d\n", a + a + b); }
void sum3(int a, int b) { printf("%d\n", a + b + b); }
void error(int a, int b) { puts("error"); }
void (*func(const char *f))(int, int)
{
if (!strcmp(f, "sum1")) return sum1;
if (!strcmp(f, "sum2")) return sum2;
if (!strcmp(f, "sum3")) return sum3;
return error;
}
int main(void)
{
int a = 10, b = 20;
char name[10];
while (scanf("%s", name) == 1)
func(name)(a, b);
}
Re: 関数名をchar型変数で代替したい
ご回答ありがとうございます。返信が遅れて失礼しました。
早速試したところ、こちらでもうまく動きました。
文字列を戻り値で渡すというのは思いつかなかったのですごく勉強になりました。本当にありがとうございました。
〇解決したコード
早速試したところ、こちらでもうまく動きました。
文字列を戻り値で渡すというのは思いつかなかったのですごく勉強になりました。本当にありがとうございました。
〇解決したコード
#include <stdio.h> // printf, puts, scanf
#include <string.h> // strcmp
void sum1(int a, int b) { printf("%d\n", a + b); }
void sum2(int a, int b) { printf("%d\n", a + a + b); }
void sum3(int a, int b) { printf("%d\n", a + b + b); }
void error(int a, int b) { puts("error"); }
void (*func(const char *f))(int, int)
{
if (!strcmp(f, "sum1")) return sum1;
if (!strcmp(f, "sum2")) return sum2;
if (!strcmp(f, "sum3")) return sum3;
return error;
}
int main(void)
{
int a = 10, b = 20;
char name[10];
while (scanf("%s", name) == 1)
func(name)(a, b);
}
Re: 関数名をchar型変数で代替したい
関数 func は、文字列 name を引数として渡すと、
「関数へのポインタ」を戻り値で返してくる
ということが本当に分かっていますか?
私の提示したコードと何も変わっていませんね。
自分の書き方に変えましょう。
たとえば、
・f というのは分かりにくい。name にしよう。
・! よりも == 0 のほうが違和感がない。
・if文の中の文には { } を付ける主義だ。
など
Re: 関数名をchar型変数で代替したい
フォーラム(掲示板)ルールにソースコードや解決した方法を明記しろ、と書いてあったので記載しました。不快に思われたのでしたら申し訳ないです。
かずま様の回答を見た際に「なんでfunc関数の前に*がついているんだろう…?」「そもそもvoid型なのにreturnを使ってる…?」とかいろいろ思いましたが、おかげで関数ポインタを知るきっかけになりました。手元の教科書には関数ポインタが載ってなかったのでネットでなんとなく理解した程度ですが、かなり便利です。
せっかくなので私なりに書いてみました。こんなのでも正しい実行結果が出るので驚きです。
かずま様の回答を見た際に「なんでfunc関数の前に*がついているんだろう…?」「そもそもvoid型なのにreturnを使ってる…?」とかいろいろ思いましたが、おかげで関数ポインタを知るきっかけになりました。手元の教科書には関数ポインタが載ってなかったのでネットでなんとなく理解した程度ですが、かなり便利です。
せっかくなので私なりに書いてみました。こんなのでも正しい実行結果が出るので驚きです。
#include <stdio.h>
void sum1( int a, int b ) { printf( "%d\n", a+b ); }
void sum2( int a, int b ) { printf( "%d\n", a+a+b ); }
void sum3( int a, int b ) { printf( "%d\n", a+b+b ); }
void error( void ) { printf( "error" ); }
int main( void )
{
int a = 10, b = 20, i;
void (*p[])( int ,int ) = { sum1, sum2, sum3 };
scanf( "%d" ,&i );
if( i<1 || 3<i ){
error();
}else{
(*p[i-1])( a, b );
}
return 0;
}
Re: 関数名をchar型変数で代替したい
関数へのポインタの配列とは、もう型はバッチリですね。
sum1 が関数なら、&sum1 が「関数へのポインタ」ですから、
sum1 の代わりに &sum1 と書くこともできます
sum1 と書いてもいいのは、関数は一部の例外を除いて
常に「関数へのポインタ」に変換されるからです。
関数呼出し演算子「(実引数式の並び)」はオペランドに
「関数へのポインタ」を要求するので、
(*p[i-1])(a, b); は、p[i-1](a, b); と書くこともできます。
これらについてはちょっと前に、関数へのポインタに書きました。
ということで、次のプログラムもちゃんと動きます。
#include <stdio.h>
int main(void)
{
(&printf)("&printf\n");
(printf)("printf\n");
(*printf)("*printf\n");
(**printf)("**printf\n");
(***printf)("***printf\n");
}
これは、 と同じで、配列変数 p の初期化が実行時に行われます。
static void (*p[])(int, int) = { sum1, sum2, sum3 };
と静的に変数を確保することによって、関数が何十個あっても
実行時の初期化は無くなります。
Re: 関数名をchar型変数で代替したい
#include <stdio.h>
void sum1( int a, int b ) { (&printf)( "%d\n", a+b ); }
void sum2( int a, int b ) { (*printf)( "%d\n", a+a+b ); }
void sum3( int a, int b ) { (**printf)( "%d\n", a+b+b ); }
void error( void ) { (***printf)( "error\n" ); }
int main( void )
{
int a = 10, b = 20, i;
static void (*p[])( int, int ) = { &sum1, &sum2, &sum3 };
scanf( "%d" ,&i );
if( i<1 || 3<i ){
error();
}else{
p[i-1]( a, b );
}
return 0;
}
&sum1という書き方は見た目が分かりやすくていいですね。いかにもな「これは住所です」感が初心者の私にはピッタリみたいです。