C言語の関数プロトタイプを使って複雑な関数宣言を行う方法

このQ&Aのポイント
  • C言語で関数プロトタイプを使って複雑な関数宣言を行う方法を教えてください。
  • 上記のCのコードで、関数プロトタイプにあるint (*i(AdPoint))(int, int); を使ってエラーが発生してしまいます。
  • コンパイルエラーの原因が分かりません。どなたか教えていただけないでしょうか。
回答を見る
  • ベストアンサー

複雑な関数宣言の使い方

#include <stdio.h> typedef int (*AdPoint)(int, int); int add(int x, int y) { int z = x + y; return z; } AdPoint test(AdPoint ap) { return ap; } int (*i(AdPoint))(int, int); int main() { int sum; AdPoint p = add; AdPoint pp = test(p); sum = (*i(pp))(1, 2); //sum = pp(1, 2); printf("%d\n", sum); return 0; } 上記のCの記述で、記述してあるsumをコメントアウトし、下のコメントアウトしてあるものを取って実行させると、期待通り、sum = 3 になるのですが、これと同じことを、関数プロトタイプにある int (*i(AdPoint))(int, int); の関数iを使って行おうとすると、 error LNK2019: 未解決の外部シンボル "int (__cdecl*__cdecl i(int (__cdecl*)(int,int)))(int,int)" (?i@@YAP6AHHH@ZP6AHHH@Z@Z) が関数 _wmain で参照されました。 といったコンパイルエラーが出てしまって、理由が分かりかねています。 御経験のある方、御教示願えたらと思います。

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

  • ベストアンサー
  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.3

> int (*i(AdPoint p))(int a, int b) > { > AdPoint pp = p; > return pp; > } あなたの期待通りならそれで良いのではないでしょうか。 Warningとか出てないなら型の整合性はとれていると思いますが。 まあ個人的には、わざわざわかりにくい書き方せずに AdPoint i(AdPoint p) {  return p; } と書けば良いのではないかと思いますが。 こう書いた方が戻り値がAdPointってことがすぐわかるし。 > sum = (*i(p))(1, 2); も sum = i(p)(1, 2); と書ける。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「変数」は変数であって関数ではないし, 「関数を初期化する」なんてことはできない. #1 で何を言われたのか, 本当に理解できてるの?

tmiyoshi
質問者

補足

#include <stdio.h> typedef int (*AdPoint)(int, int); int add(int x, int y) { int z = x + y; return z; } //AdPoint test(AdPoint ap) //{ // return ap; //} int (*i(AdPoint p))(int a, int b) { AdPoint pp = p; return pp; } int main() { int sum; AdPoint p = add; //AdPoint pp = test(p); //sum = pp(1, 2); sum = (*i(p))(1, 2); printf("sum = %d\n", sum); return 0; } 一応、上の記述で私のやりたいことはできるようになりました。 int (*i())() の関数の中身には、   AdPoint pp = p;   return pp; を書きました。 これでいいのでしょうかね? 何か補足あれば、お願い致します。

回答No.1

iの実体がないですね。 int test(); とだけ書いて test(); と呼び出してるのと同じです。

tmiyoshi
質問者

補足

すいません、言われるとおりです。 変数iは、「intを返す関数へのポインタを返す関数」になるので、 typedef int (*i(AdPoint))(int, int); で宣言してしまうと、関数を初期化することになってしまいます。 やりたいことは、関数iを使って、sum = pp(1, 2); と同じことを実現したいだけなのですが、どのように書けばいいか分かりかねています。

関連するQ&A

  • 関数宣言

    3次元で領域を確保するプログラムをmalloc関数を用いて書きました。しかし、プログラムが長いので関数宣言をしなさいといわれたために、以下のプログラムを書きました。しかし、途中でつまづいてしまい、どのように関数を用いたり、関数を定義すれば良いのか混乱しています。初心者ですが、どうかお願いします。 /*ソース*/ #include<stdio.h> #include<stdlib.h> int main(){ double ***C; f3Malloc(C,.,.); //数値を代入(関数の使い方?) f3Free(C,.,.); } /*3次元配列(返し方?)*/ double*** f3Malloc(C,,){ int i,j,x,y,z; x = 2; y = 3; z = 4; C=(double***)malloc(sizeof(double**)*x*y*z); for(i=0;i<y;i++){ C[i]=(double**)malloc(sizeof(double*)*y*z); for(j=0;j<z;j++){ C[i][j]=(double*)malloc(sizeof(double)*z); } } } /*メモリの解放(返し方?)*/ void f3Free(C,.,.){ int i,j,x,y; x = 2; y = 3; for(i=0;i<x;i++){ for(j=0;j<y;j++){ free(C[i][j]); } free(C[i]); } free(C); }

  • 関数のプロトタイプ宣言

    #include <stdio.h> #define N 3 #define M 4 int sum(int [][M]); (関数のプロトタイプ宣言) int main(){   ・   ・   ・ return(0); } int sum(int x[][M]){    ・    ・ } 以上のプログラムより、関数のプロトタイプ宣言や、関数内の 行列の定義でint sum(int [][M]);や int sum(x[][M]){}となっていますが なぜ、列にMだけを代入することだけでよいのでしょうか? また、教科書に関数のプロトタイプ宣言ではint sum(int [][]);だけでもよいと書かれていたのですが 実際、コンパイルしてみたところ 'int[]' 型のサイズは未知あるいはゼロとエラーがでました。 これは、コンパイラによってできるものとできないものがあるのでしょうか?? よろしくお願いします。

  • 関数についての質問です。

    c言語を勉強しています。関数で戻り値がありますが、関数の処理の仕組みが理解できません。本等で勉強し僕の考え方が間違っていたら教えてください。 お願いいたします。 #include <stdio.h> int buy(int x,int y ) { int z; //1 printf("%d万円と%d万円の車を買いました。");//2 z=x+y; //3 return z; //4 } int main(void) { int num1,num2,num;//5 printf("いくらの車をかいますか?\n");//6 scanf("%d",&num1);//7 printf("いくらの車をかいますか?\n");//8 scanf("%d",&num2);//9 sum=buy(num1,num2);//10 printf("合計で%d万円です。\n",sum);//11 return 0;//12 } まず最初に 整数型、int num1,num2,numを読みます。 次に//7と//8で数値を入力します。 そして//10で値を格納し int buy( int x,int y)に値をわたします。 ※正確には関数buyに渡す。 そして計算をし計算結果 zをreturn で int buy(int x,int y )の buyに値を渡します。 そのあと呼び出し元の//10のbuyに値をかえします。 そしてプログラムが終了します。 間違っていたら教えてください。

  • 合計値を求める関数

    #include<iostream> using namespace std; //sum関数の定義 int sum(int x, int y) { return x + y;  } int main() { int num1, num2, ans; cout << "1番目の整数を入力して下さい。\n"; cin >> num1; cout << "2番目の整数値を入力して下さい。\n"; cin >> num2; ans = sum(num1, num2); cout << "合計は" << ans << "です。\n"; return 0; }  ここのreturn x+y;の所の合計値を戻り値として返す処理の仕組みを解りやすく教えて欲しいです、戻り値はちょっと解りづらいです、よろしくお願いします。

  • 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);とは違うんですよね?

  • GlobalAllocの変数を関数に引き渡したい

    あるプログラムでGlobalAllocで指定バイト数を割り当てた変数を別の関数に引き渡したいのですが、やりかたが分からず困っております。 手元にある本はGlobalAllocについてすら書いておらず… 以下のようなプログラムになります。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー int math( int a, int b, unsigned short c ){ // 関数中身の演算に意味はない unsigned short sum; for( int i=a; i<b; i++ ) sum += c[i]; return sum; } int main(){ int Depth = 6; int sum; unsigned short *mem = GlobalAlloc( GPTR, Depth*sizeof(unsigned short) ); sum = math( 1, 3, mem ); // これな風にmemを値を引数として渡したい return 0; } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー お分かりになる方がおられましたら、ご回答いただけると幸いです。 宜しくお願い致します。

  • C言語のソースコードについて教えてください。

    以下のソースコードを学習用C言語開発環境で行ったのですが、 『ファイル「C:/Users/ユーザー名/AppData/Local/EasyIDEC/project/タイトル/main.c」の 「41行目」で記述エラーを発見しました。 「,」を付け忘れています。』 という、コンパイルエラーが表示されました。 何度も見直したのですが、よくわかりません。 #include <stdio.h> int main(int argc, char *argv[]) { char answer ; answer = 'n' ; while(answer =='n') { int input ; input = 0 ; int add ; add = 1 ; int sum ; sum = 0 ; printf("数値を入力して下さい。:") ; scanf("%d", &input ) ; int i ; i = 0 ; while(i < input) { sum =sum + add ; printf("\n%d",sum) ; i++ ; add++ ; } printf("\n1から%dまでの総和は、%dです。" , input , sum) ; while(1) { printf("\n終了しますか? y/n:") ; scanf(" %c , &answer) ; if( (answer != 'y') && (answer != 'n') ) { printf( "y or nを入れてください。") ; } else { break ; } } } return 0 ; }

  • 関数内に関数は無理でしょうか? 子スレッド

    CやC++についてまだよくわかっていないのですが、関数内に関数を書くと 「コンパイラ エラー C2601 ローカル関数の定義が正しくありません。」となります。 そこで以下の子スレッドのように関数を関数外に定義して、利用する変数も関数外に定義しました。 変数を外部に定義すると、メモリアクセスになるので、できるだけ避けたかったために 関数内に子スレッドを最初書いていたのですが、何か良い方法はありますか? 子スレッドの引数や戻り値を利用できればいいのですが、そんなことできるのかもわかりません。 あと、関数を配列のように定義できるのでしょうか? test_thread_0, test_thread_1と逐一書くのが面倒です。 int sum1 = 0, sum2 = 0; unsigned __stdcall test_thread_0(void *lpx) // lpxはおまじない? { // 全て足す for (int i = ST1; i <= EN1; i++){ sum1 += Data1[i] * Data2[i]; } return 0; // 正常という意味? } unsigned __stdcall test_thread_1(void *lpx) { // 全て引く for (int i = ST2; i <= EN2; i++){ sum2 -= Data1[i] * Data2[i]; } return 0; }

  • プログラミング 関数について教えて下さい。

    プログラミングについての質問です。 関数を使った以下のプログラムを作成し、実行してみたのですが、上手くいきません。 どこかおかしいのでしょうか? 教えていただけると幸いです。ご回答お待ちしております。 #include <stdio.h> double add (double x,double y); int main(void) { double a,b,c; printf("double型の数を入力して下さい。\n"); scanf("%f\n",&a); printf("もうひとつdouble型の数を入力してください\n"); scanf("%f\n",&b); c=add(a,b); printf("入力された2数の和は%fです。\n",c); return 0; } double add(double x,double y) { double z; z=x+y; return z; }

  • C言語 main関数とsum関数の記述順について

    はじめまして。 【苦しんで覚えるC言語】(Web版)でC言語を学んでいる初学者です。 【第1部:C言語基礎編】>【関数の作り方】>【自作関数を作る】の部分(http://9cguide.appspot.com/11-01.html#S2)でつまづいています。 下記のような、1から100までの数字の合計を表示するプログラムが例題として取り上げられています。 しかし、ここが理解できないので、次の【プロトタイプ宣言】に進めずにいます。 例題1  sum関数をmain関数の後に記述した場合(プログラムが実行されない)。 #include <stdio.h> int main(void) { return 0; } int sum(void) { printf("%d\n",(1 + 100) * 100 / 2); return 0; } 例題2  sum関数をmain関数の先に記述した場合(プログラムが実行される)。 #include <stdio.h> int sum(void) { printf("%d\n",(1 + 100) * 100 / 2); return 0; } int main(void) { return 0; } 例題1の場合、【まずmain関数を作り、次にsum関数を作りました。この場合、main関数を解析している段階では、sum関数は発見されておらず、従って、main関数の中では、sum関数を使うことは出来なくなってしまいます。】との説明がありますが理解できません。 コンパイラがどのような順番でプログラムを処理しているか理解できていないので分からないのだと思います。 例題1の場合と例題2の場合の両方について、コンパイラがどのような順番でプログラムを処理しているのかを具体的に教えてください。 どうかよろしくお願い致します。

専門家に質問してみよう