• ブログ
  • ふぉとす
  • キーワード
  • ブックマーク
  • 写真
  • ログイン

Title

« 2007年03月13日 | 2007年03月15日 »
  • I'm always disgusted at members of a labor union and their activity. 2007-03-14 00:00:00

     C言語の復習をちょっとやってみました。関数へのポインタとかなつかしいです。関数へのポインタは構造体のメンバになれるんだっけ、と思ったので試してみました。
     まずはヘッダファイルのkaeru_string.h。

    #ifndef _INCLUDE_KAERU_STRING_
    #define _INCLUDE_KAERU_STRING_
    
    typedef struct kaeru_string {
            int (*str_set)();
            char *(*str_put)();
    } *String;
    
    extern String str_new(void);
    extern void str_free(String);
    
    #endif
    

     次にkaeru_string.c。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "kaeru_string.h"
    
    static int string_set(const char *);
    static char *string_put(void);
    
    static char *data;
    
    String str_new(void)
    {   
        String  new;
    
        new = (String)malloc(sizeof(String));
        new->str_set = string_set;
        new->str_put = string_put;
        data = NULL;
    
        return new;
    }
    
    void str_free(String self)
    {   
        free(data);
        data = NULL;
        free(self);
        self = NULL;
    }
    
    static int string_set(const char *source)
    {   
        int size;
    
        size = strlen(source);
        if (size < 0) {
            return -1;
        }
    
        data = (char *)malloc(size + 1);
        strcpy(data, source);
    
        return 0;
    }
    
    static char *string_put(void)
    {
        return data;
    }
    

     そしてmain.c。

    #include <stdio.h>
    #include "kaeru_string.h"
    
    int main(void)
    {   
        String a;
    
        a = str_new();
    
        if (a->str_set("I'm C Programmer!")) {
            printf("error\n");
            return -1;
        }
    
        printf("%s\n", a->str_put());
    
        str_free(a);
    
        return 0;
    }
    

     結果は

    I'm C Programmer!
    

     クラスみたいなものが作れないのかな、と思ったので関数へのポインタを構造体のメンバにしてみたのだけど、すぐにおかしいことに気づいた。main.cを

    int main(void)
    {
        String a;
        String b; 
    
        a = str_new();
        b = str_new();
    
        if (a->str_set("I'm C Programmer!")) {
            printf("error\n");
            return -1;
        }
    
        if (b->str_set("And I'm Ruby programmer!!")) {
            printf("error\n");
            return -1;
        }
    
        printf("%s\n", a->str_put());
    
        str_free(a);
        str_free(b);
    
        return 0;
    }
    

    こうすると結果は、

    And I'm Ruby programmer!!
    

     シングルトンみたいになってしまった。外部変数のchar *dataはただひとつの変数なのだから当然だけど。さらにfreeでdataを何度も開放していることになってしまっていてヤバそう。
     そういえば、static指定の関数でも、関数へのポインタ経由なら他ファイルからもアクセスできてしまうみたい。static指定の情報まではポインタに引き継がれないんだね。当然と言われれば当然なのだろうけど。

     シングルトンはイヤなので、dataを構造体の中にいれてみよう。こっちのほうがクラスっぽくて自然だろうし。
     と思ったけどすぐにダメなことに気づいた。構造体の中のdataを指すためにStringへのポインタ自体を関数の引数にしなくちゃいけなくて、結局構造体の中へ関数へのポインタを入れる意味がなくなっちゃうのです。つまりは、薄々感じていた平凡な形になってしまうわけです。kaeru_string.h, kaeru_string.c, main.cの順に並べると、

    #ifndef _INCLUDE_KAERU_STRING_
    #define _INCLUDE_KAERU_STRING_
    
    typedef struct kaeru_string {
            char *data;
    } *String;
    
    extern String str_new(void);
    extern void str_free(String);
    extern int string_set(String, const char *);
    extern char *string_put(String);
    
    #endif
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "kaeru_string.h"
    
    String str_new(void)
    {   
        String  new;
    
        new = (String)malloc(sizeof(String));
        new->data = NULL;
    
        return new;
    }
    
    void str_free(String self)
    {   
        free(self->data);
        self->data = NULL;
        free(self);
        self = NULL;
    }
    
    int string_set(String self, const char *source)
    {   
        int size;
    
        size = strlen(source);
        if (size < 0) {
            return -1;
        }
    
        self->data = (char *)malloc(size + 1);
        strcpy(self->data, source);
    
        return 0;
    }
    
    char *string_put(String self)
    {   
        return self->data;
    }
    
    #include <stdio.h>
    #include "kaeru_string.h"
    
    int main(void)
    {
        String a;
        String b;
    
        a = str_new();
        b = str_new();
    
        if (string_set(a, "I'm C Programmer!")) {
            printf("error\n");
            return -1;
        }
    
        if (string_set(b, "And I'm Ruby programmer!!")) {
            printf("error\n");
            return -1;
        }
    
        printf("%s\n", string_put(a));
        printf("%s\n", string_put(b));
    
        str_free(a);
        str_free(b);
    
        return 0;
    }
    

    結果は

    I'm C Programmer!
    And I'm Ruby programmer!!
    

     とりあえず形にはなったけど、なんだかクラスっぽさはなくなったね。本来ならprivateにしたいchar *dataにアクセスできちゃうし、そのデータと関数との関連も疎になった感じ。C言語でクラスみたいなものを作ろうというのが変なのかも。

     追記です。

    typedef struct kaeru_string {
            char *data;
    } *String;
    

     これってもう構造体の意味がなかったね。ただのcharポインタでOKです。

    Commentコメント(0) Pageリンク元(17) Append 87
  • The Long Goodbye
    作者/アーティスト: Jeffery Deaver
    メディア: ペーパーバック
    映画ドラえもん のび太の海底鬼岩城 6[ビデオ]
    メディア: -
« 2007年03月13日 | 2007年03月15日 »

プロフィール

おおいしつかさ

Amazon商品の一覧

人気の記事ベスト10

  • 1.apache+mod_proxy_balancer+mongrelでRailsを動かす方法
  • 2.Perlでevalを使ってみる
  • 3.バージョン管理をsubversionからgitに移行してみた
  • 4.tokyobikeのドロップハンドル化
  • 5.ubuntu8.04でデュアルディスプレイを使う
  • 6.restful_authenticationを使ってみた
  • 7.URLなど、長い英字を折り返して表示する方法
  • 8.Rspecでコントローラのspecファイルを書く
  • 9.フラグメントキャッシュをRailsで使う。
  • 10.RailsとPostfixで受信メールを処理する方法

コメント

  • ユル(プログラマが若隠居をしたら)
  • ユル(風邪ひいた)
  • ユル(バイクがへたくそになっていた)
  • おおいしつかさ(便利になって不便になる)
  • 武石(便利になって不便になる)
  • ユル(劇場版 天元突破グレンラガン)
  • ユル(フラニーとゾーイー (新潮文庫): サリンジャー, 野崎 孝: 本)

過去の記事

2006年
12月
2007年
1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
2008年
1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月

キーワード一覧

ActionScript AmazonResources git javascript kaeruspoon milook NSR Objective-C Rails Ruby Ruby on Rails subversion Thin tokyobike ubuntu VAIO VAIO typeZ Waves Xen ぐりぐり カンタロー スノボー ドトール ドライブ バイク プログラミング ユルさん 執筆 日本酒 模型 真中洋嗣 自転車

Youtube

ニコニコ動画