掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26449

関数のポインタの意味は?
投稿者---def(2006/03/18 18:14:59)


たまに見かけるのですが、関数のポインタはどういう場合に使うのでしょうか?
便利なら使ってみたいのですが...

VisualStudio2005(C++)


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:関数のポインタの意味は? 26450 επιστημη 2006/03/18 18:27:29
<子記事> Re:関数のポインタの意味は? 26456 TJ 2006/03/19 04:11:11
<子記事> Re:Cでの関数ポインタの典型例 26458 si 2006/03/19 14:43:16
<子記事> Re:関数のポインタの意味は? 26462 def 2006/03/19 23:08:21


No.26450

Re:関数のポインタの意味は?
投稿者---επιστημη(2006/03/18 18:27:29)


>たまに見かけるのですが、関数のポインタはどういう場合に使うのでしょうか?

標準関数 qsort がいい例。
大小判定を関数ポインタで与えることによって、
どんな順序でのsortも可能です。

関数ポインタなしでこれを実現できるだろうか?




この投稿にコメントする

削除パスワード

No.26451

Re:関数のポインタの意味は?
投稿者---def(2006/03/18 18:43:46)


正直なところ、qsortを使ったことがないので何とも言えません(^^;)
基本的に入門向けのC++の本には関数のポインタには触れていませんでした。
この辺の技術が載っている書籍などが有れば教えていただきたいです。

.....近くに大きい本屋がないのがつらい


この投稿にコメントする

削除パスワード

No.26452

Re:関数のポインタの意味は?
投稿者---επιστημη(2006/03/18 19:35:36)


>正直なところ、qsortを使ったことがないので何とも言えません(^^;)

じゃ使ってみて。 関数ポインタの便利さがわかるから。



この投稿にコメントする

削除パスワード

No.26453

Re:関数のポインタの意味は?
投稿者---def(2006/03/18 23:06:47)


#include <iostream>
#include <stdlib.h>
using namespace std;


int compare(const int *p, const int *q)
{
    return *p - *q;
}

void main()
{
    int dat[] = {1,0,92,34,8,57,1023948,756,3309,2348,75,102,394,87,5};
    int count;

    qsort(dat, (sizeof dat/sizeof dat[0]), sizeof(int), (int (*)(const void*, const void*))compare);
    for(count = 0; count < (sizeof dat/sizeof dat[0]); count++)
    {
        cout<<count<<"\\"<<dat[count]<<endl;
    }
}


使ってみました。
これで私が関数のポインタの恩恵にあずかったのでしょうか?


この投稿にコメントする

削除パスワード

No.26454

Re:関数のポインタの意味は?
投稿者---通りすがり(2006/03/18 23:25:23)


関数ポインタの役割って関数型言語のラムダ式を弱めたような感じじゃないでしょうか?詳しくは適当な関数型言語の説明を参照して下さいm(._.)m 無責任ですいません。



この投稿にコメントする

削除パスワード

No.26455

Re:関数のポインタの意味は?
投稿者---επιστημη(2006/03/19 00:36:48)


>これで私が関数のポインタの恩恵にあずかったのでしょうか?

うん。compare関数をいくつか用意しとけば、
qsortにどれを食わすかでsort順を切り替えられる。



この投稿にコメントする

削除パスワード

No.26457

Re:関数のポインタの意味は?
投稿者---RAPT(2006/03/19 11:11:00)


それで間違いではありませんが、通常、qsort()の第4引数でキャストが必要な書き方はせず、
呼び出される関数の側でキャストします。

#include <iostream>
#include <stdlib.h>
using namespace std;


int compare(const void *p, const void *q)
{
    return *(const int *)p - *(const int *)q;
}

void main()
{
    int dat[] = {1,0,92,34,8,57,1023948,756,3309,2348,75,102,394,87,5};
    int count;

    qsort(dat, (sizeof dat/sizeof dat[0]), sizeof(int), compare);
    for(count = 0; count < (sizeof dat/sizeof dat[0]); count++)
    {
        cout<<count<<"\\"<<dat[count]<<endl;
    }
}



この投稿にコメントする

削除パスワード

No.26460

Re:関数のポインタの意味は?
投稿者---RiSK(2006/03/19 22:28:05)


>それで間違いではありませんが、

いいえ,間違いです。

>通常、qsort()の第4引数でキャストが必要な書き方はせず、

ポインタの方を変えて,関数を呼び出すと未定義動作になります。

>呼び出される関数の側でキャストします。

御意。


本題のサンプル:
#include<stdio.h>
#include<ctype.h>
int IsPeriod(int c){return c=='.';}
void FilteringEcho(int(*filter)(int)){
    int c;
    while((c=getchar())!=EOF)if(!filter(c))putchar(c);
}
int main(void){
    unsigned int n;
    int(*const table[])(int)={isupper,islower,IsPeriod};
    if(scanf("%d",&n)!=1||n>3)return 1;
    FilteringEcho(table[n]);
}



この投稿にコメントする

削除パスワード

No.26461

Re:関数のポインタの意味は?
投稿者---RiSK(2006/03/19 22:43:53)


>ポインタの方を変えて,

ポインタのを変えて,

>if(scanf("%d",&n)!=1||n>3)return 1;

if(scanf("%u",&n)!=1||n>3)return 1;


この投稿にコメントする

削除パスワード

No.26456

Re:関数のポインタの意味は?
投稿者---TJ(2006/03/19 04:11:11)
http://home.f01.itscom.net/toge/programingreport/


私は微分方程式を解く関数を作成したときに関数ポインタを使いました。
汎用的に作れて便利です。

構造体に関数ポインタ含ませとくとCでC++っぽい事ができたり(カプセル化とかいう話とは無縁ですが)、使う関数を動的に変化させたりできます。
私はやったことないですが(^^;

適材適所で使うと結構面白いと思いますよ。


この投稿にコメントする

削除パスワード

No.26458

Re:Cでの関数ポインタの典型例
投稿者---si(2006/03/19 14:43:16)


コマンドライン引数で、ディレクトリリストのフィルタを変更するサンプル
Linux , gcc4
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
// リンクファイルとディレクトリをフィルタ
int filter0(const struct dirent *p)
{
    if (p->d_type == 0x0A || p->d_type == 0x04) return 0;
    return 1;
}
// ディレクトリだけをフィルタ
int filter1(const struct dirent *p)
{
    if (p->d_type == 0x04) return 0;
    return 1;
}
// フィルタ関数配列
int (*filter[])(const struct dirent *p) = { filter0,filter1 };

int main(int argc,char *argv[])
{
    struct dirent **namelist;
    int n,i;
    int filterf = -1;
    if (argc > 1) {
        for ( i = 1 ; i < argc ; i ++ ) {
            if (argv[i][0] == '-') {
                if (argv[i][1] == '0') filterf = 0;
                else if (argv[i][1] == '1') filterf = 1;
                else filterf = -1;
            } else {
                if ( filterf < 0)
                    n = scandir(argv[i], &namelist,0, alphasort);
                else
                    n = scandir(argv[i], &namelist, filter[filterf], alphasort);
                if (n < 0)
                    perror("scandir");
                else {
                    while (n--) {
                        printf("%s 0x%X\n", namelist[n]->d_name,namelist[n]->d_type);
                        free(namelist[n]);
                    }
                    free(namelist);
                }
            }
        }
    }
}




この投稿にコメントする

削除パスワード

No.26462

Re:関数のポインタの意味は?
投稿者---def(2006/03/19 23:08:21)


色々作ってみます。
ポインタの専門書でも読もうかなぁ...


この投稿にコメントする

削除パスワード

No.26463

Re:関数のポインタの意味は?
投稿者---RAPT(2006/03/20 02:03:57)


ポインタの専門書でも読もうかなぁ...
専門書はまだ早いかと。かえって混乱しそうな。 それよりも、有名な「C言語 ポインタ完全制覇」あたりがお奨めです。




この投稿にコメントする

削除パスワード

No.26464

Re:関数のポインタの意味は?
投稿者---def(2006/03/20 04:08:12)


ポインタだけではなく、C++/CLIもやらないといけないし、Windows32APIやDirectX、3D係数学もやらないといけない。とどめはシェーダ言語.....
DirectXや3D係数学については資料が揃うので何とかなるのですが、C++/CLIは専門書が見つからないので、噛みつくのが一苦労です。
Win32APIは別に知らなくてもDirectXのAPIで代用するのが多くて、別に知らなくても困らないですね。必要になったらリファレンスをめくる形で大丈夫です。

まぁ、C++も初心者向けの本は載っていないところがあるし、その載っていないところを筆者は教えてくれないので何処を自分が知らないかを見つけるのが難しいと。
ネット上で検索すると、見たこともないような型キャスト"static_cast"がいきなり使われていて読めなかったりします。

ちなみに今C++を学んでいるのは"初めてのC++"という本で、一応「演習と解説」という二つのシリーズ(?)で構成されているのですが、やはり書いていないところが多く特に難解なキャストについては触れていませんでした。
ああ、STLもやってないやorz

書いた二冊以外にどんな書籍が必要でしょう...
無駄にDirectXやWin32API、シェーダ開発の本は揃ってるのにC++だけは揃わないんですね。どうする俺...


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧