• ベストアンサー

関数へのポインタ

超初心者です。 C言語を使ってsin波を生成して音を鳴らそうとしているのですが・・ネットで調べてもよくワカリマセン・・ 超初心者な私でも理解できるようなサイトを教えて下さい. また、関数へのポインタも勉強しているのですが, char *(*func)(void); といったchar 型へのポインタを返す関数へのポインタというのがあったとして,関数へのポインタは理解できたのですがさらにchar 型へのポインタとなると一体これが何を指しているのかさっぱりで・・・・ ご協力お願いします.

noname#45110
noname#45110

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★関数へのポインタについて ・『char』型ポインタを返す『関数へのポインタ』が『char *(*func)(void);』という関数で、  さらにこの関数へのポインタを返す関数はどう記述するのか?って事か? ・そらならば、typedef などで新たな型を定義してから記述すると簡単になりますよ。 サンプル: typedef char* (*RetFuncType)(void); ←char型ポインタを返す『関数へのポインタ』のタイプ typedef RetFuncType (*NewFuncType)(void); ←RetFuncType型を返す『関数へのポインタ』のタイプ //『char型へのポインタ』を返す関数 char *Func1(void) {  return( "string" ); } //『Func1の関数へのポインタ』を返す関数 RetFuncType Func2(void) ←『char* (*Func2(void))(void)』でも同じ(複雑だ!) {  return( Func1 ); } //『Func2の関数へのポインタ』を返す関数 NewFuncType Func3(void) ←『RetFuncType (*Func33(void))(void)』でも同じ(やっぱ複雑だ!) {  return( Func2 ); } 最後に: ・関数へのポインタを返す関数定義は『typedef』を利用した方がわかりやすく簡単です。 ・『typedef』を使わないと関数定義が複雑すぎて自分でも理解できず、他人にも理解されない  暗号のような定義になってしまいます。 ・なお、関数へのポインタが理解できるのならば『初心者』ではなく『中級者』と思いますよ。 ・以上。おわり。

noname#45110
質問者

お礼

返答ありがとうございます。 中級者ですか・・・ 頑張ります。

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

sin波を生成して音を出すって昔懐かしいFM音源とかPSG音源でもいじるのですか? 関数のポインタのほうですが、関数自体へのポインタと その関数がポインタを返すので混乱しちゃったんですかね。 #include <stdio.h> int f(int x) { return x*x; } char* g(void) { return "hello"; } int main() { typedef int funci(int); typedef char * funcp(void); funci *p = f; funcp *q = g; printf("%d\n", (*p)(13)); printf("%s\n", (*g)()); return 0; } こんなんでイメージできますか?

noname#23436
noname#23436
回答No.1

【関数へのポインタについて】 以下のサンプルコードの内容を説明できますか? #include <stdio.h> typedef char *(*func)(void); char *a(void); char *b(void); char *c(void); int main(void) {   func f[] = { a, b, c };   char n;      while (1) {     printf("どの関数を実行しますか?(a~c, 終了:q)->");     scanf(" %c", &n);     switch (n) {     case 'a': case 'b': case 'c':       printf("%s\n", f[n - 'a']());       break;     case 'q':       return 0;     default:       puts("実行する関数名が正しくありません");       break;     }   } } char *a(void) {   return "おはよう"; } char *b(void) {   return "こんにちは"; } char *c(void) {   return "こんばんは"; } (注)インデントのため、全角空白を使っています。

関連するQ&A

  • 関数ポインタについて

    C言語によるUNIXシステムにプログラミング入門という本を読みながらC言語を勉強しています。 しかし、サンプルとして提示された下記の内容の意味がわかりません。 分からない箇所が「関数ポインタ」と呼ばれるものがついているということが分かった程度で、どういう意図で記述されているのかがわかりません。 分からないプログラムの処理内容は、ファイル内のデータを16進数で表示するというものです。 分からない箇所を記します。 #include <stdio.h> #define BUFF 17 /*buffer*/ #define ERR -1 /*system call error*/ void usage(void); /*put usage message*/ char *command_name /*command name*/ FILE *fpin; /*file pointer*/ main(int argc,char *argv[ ]){ char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); ... ... } void hexdump(void){ ... ... } void usage(){ ... ... } 不明なのは、main関数の中の char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); です。 Cについて、不明なところが多いので、利用する関数は使う前に宣言しなければいけない程度の理解ですが、そうだとしてもusageメソッドはmain関数の外であるのに、rindexとhexdumpは何故main関数の中で宣言されているのでしょうか。 上記の不明点とは別で、rindexの前にポインタが付いていると思うのですが、hexdumpやusageにはついていません。 知人からは、関数までのポインタを返すとのことでしたが、用途もいまいち理解できません。 全てではなくてもいいので、ヒントをいただけるとうれしいです。 よろしくお願いします。

  • 関数ポインタについて

    C言語の関数ポインタの問題で以下のような問題で、実際に解いて、プログラムを動かしてみてみました。 正常に動作したのですが、この回答では満点はもらえませんでした。 このほかに良い解答例などありましたら、教えていただけないでしょうか。 どうかよろしくお願い致します。 [問題]次の※1・※2を埋めなさい(「func1」,「func2」は解答に含まれないように書くこと)。 #include <stdio.h> void func1() { printf("func1\n"); } void func2() { printf("func2\n"); } void func(int no) { void (*func[2])(void) = {func1, func2}; /* ※1 (*func[no])() */; } int main() { /* ※2 func(1) */; return 0; } 実行結果:func2

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • 関数ポインタの利点

    こんにちは。 C言語初心者ですが今勉強中です。 その中でポインタについては理解できたのですが、 関数ポインタの利点、使うべき所などが理解できません。 ポインタの基本は理解しています。 値渡し、アドレス渡しも理解しています。 関数ポインタを使うと何がいい、またはどんなとき使わなければならないのか 教本を読んでいてもさっぱりわかりません。 サンプルプログラムを打っても何のために使ってるのかわからないです。 どなたか教えていただけませんでしょうか? よろしくお願いします。

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • 不透明なデータのポインタ宣言

    ライブラリ内で使用し、ライブラリの外には、 中身を公開したくない構造体があります。 ライブラリ関数には必ず、ポインタとしてやりとりされます。 これを外部向けに不透明なデータのポインタとして宣言したいのですが・・ typedef const void *PRIVATE_DATA ; このように宣言してみたのですが、 これでは、否応にもvoidポインタとなってしまい、 char *等と暗黙のキャストが行われてしまいます。 たとえば・・ int lib_func( PRIVATE_DATA priv ) ; こんなライブラリ関数に対して、 lib_func( "HELLO" ) ; こんなおかしな呼び出し方が書けてしまいます。 不透明で、他の型へ暗黙のキャストが行われないポインタの宣言の仕方って、 ありませんでしょうか。。? ちなみに、コンパイラは gcc version 3.4.4 です。

  • 【C++】関数ポインタの代入

    C++の関数ポインタについて質問です。 下記のように関数ポインタを宣言し、3通りの代入を行ってみました。 (3)のように関数名の頭に&を付けた場合と(2)のように&を付けなかった場合で 全く動きが同じになってしまうのですが、何故なのでしょうか? ------------------------------------------ #include "stdafx.h" #include <iostream> using namespace std; void Func1(){ cout<<"Func1が呼ばれました。"<<endl; return; } int main() { //(1) void (*fp1_1)(); fp1_1 = Func1; fp1_1(); //(2) void (*fp1_2)()=Func1; fp1_2(); //(3) void (*fp1_3)()=&Func1; fp1_3(); getchar(); return 0; }

  • C言語の基本的な質問ですが、関数へのポインタの宣言

    関数へのポインタの質問です。 下のように、関数へのポインタを使ったプログラムを書きました。 (関数へのポインタを理解するためのものなので、実用的な意味はありません。(*^_^*) また、このプログラムはコンパイルもリンクも実行も問題なく出来ます。) #include <stdio.h> int add_func(int,int); (*func_p0) (int,int); int main(void) { int (*func_p1) (int,int); int (*func_p2) ( ); int hoge0,hoge1,hoge2; func_p0=add_func; hoge0=func_p0(3,5); printf("0 : 3+5は%d\n",hoge0); func_p1=add_func; hoge1=func_p1(3,5); printf("1 : 3+5は%d\n",hoge1); func_p2=add_func; hoge2=func_p2(3,5); printf("2 : 3+5は%d\n",hoge2); return(0); } int add_func(int x, int y) { return(x+y); } func_p0のように戻り値の型を書かない場合と、func_p1やfunc_p2のように戻り値の型を書くのとでは何が違うのでしょうか。 func_p0は外部変数ですが、自動変数にする(main関数の中で同様に宣言。)とコンパイルエラーになります。 それはなぜですか。 func_p1のように引数の型が書いてあるのと、func_p2のように引数の型が書いていないのでは何が違うのでしょうか。 int (*func_p2) ( );というのは、int (*func_p2) (void);とは違うんですよね?

  • 続ポインタによる関数への配列渡し

    連続での質問すみません。 林晴比古さんの「新C言語入門」で勉強している初心者です。 ポインタを勉強中で、色々な例文をポインタで書けるかどうか 試しております。 上書P199に「安全な数値入力を行うプログラム」が出ています。 これは入力時問題点を抱えるscanfに入力させるのでなくchar型に入力させ、 それをint型に変換して出力するという内容で、案内メッセージも関数内で表示することになっています。 以下そのプログラムを引用します。 #include <stdio.h> #include <stdlib.h> int getint(char msg[]); int main(void) { int n; n = getint("数値を入力してください:"); printf("入力した数値=%d\n",n); return 0; } int getint(char msg[]) { char ss[80]; printf("%s",msg); gets(ss); return atoi(ss); } (以上林晴比古氏「新C言語入門」P199より引用) これをポインタによって書き換えようとしているのですがうまくいきません。 「本引数として主文でint型のnを設定し、それを関数側のchar型のssをポインタにして 仮引数として受け取れば、最後にreturnで返さなくても、参照できるのでないか」 と思い色々試してみましたがうまくいきません。 どうもコンパイルのエラーを確認すると型が違うので駄目なようです。 なるほどそれはそうでした… それ以外の方法も色々試してみましたが、結局うまくいきませんでした。 どのようにすればポインタでは上の文章を表現できるのでしょうか。 (あるいは表現出来ないのでしょうか) お分かりの方、よろしくお願いします。

  • 関数の戻り値にその関数のポインタを返すには?

    関数ポインタの使い方について質問したいです. 関数で,自分自身のポインタを(void*)ではなく関数と同じ型のポインタで返すことは可能でしょうか? (自分自身の関数ポインタと同じ型??) fucn (){ return fucn; } int main(){ fucn()()()(); return 0; } このようにmain関数の中でfucn()()・・・ のように任意個の()を書いたりできないでしょうか?  詳しい方いたらよろしくお願いします.

専門家に質問してみよう