ページへ戻る

− Links

 印刷 

GUIGUI01​/memo24 :: OSASK計画

osaskwiki:GUIGUI01/memo24

ぐいぐい01に関するメモ-24 anchor.png[1]

  • (by K[2], 2009.01.12)
  • メモのうち重要な部分をそのうちまとめてまともなページを作る
Page Top

(37) GOで「ぐいぐい01」アプリを作る(2) anchor.png[3]

  • GUIGUI01​/memo19[4]の続きです。仕様変更ももうそんなにはないと思うので、書いても問題はないかなと。

  • 最初のお題は0から9までの数字の表示です。ex0007.cです。
    #include <guigui01.h>
    
    void G01Main()
    {
        int i;
        for (i = 0; i <= 9; i++) {
           g01_putc('0' + i);
           g01_putc(' ');
        }
        return;
    }
  • これだけです。これをmakeすれば70バイトになります。実行すると以下のような表示が得られます。
    0 1 2 3 4 5 6 7 8 9

  • さてそれではもう少し桁を増やします。でもsprintfは使いたくないので、setdecを作りました。ex0008.cです。
    #include <guigui01.h>
    
    void setdec(char *s, int i, int n)
    {
        int j;
        for (j = n - 1; j >= 0; j--) {
            s[j] = '0' + (i % 10);
            i /= 10;
        }
        return; 
    }
    
    void G01Main()
    {
        int i;
        char s[5];
        for (i = 0; i <= 999; i++) {
           setdec(s, i, 3);
           s[3] = ' ';
           s[4] = 0; /* 終端に0を入れる */
           g01_putstr0(s);
        }
        return;
    }
  • これをmakeすれば144バイトになります。これを実行すると、以下のように表示されます。
    000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019
    020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039
        (中略)
    960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
    980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999

  • もしかしたら最初のほうで、0が000になっていたり、1が001になっているのが気にいらないかもしれませんね。じゃあそれを直しましょう。ex0009.cです。
    #include <guigui01.h>
    
    void setdec(char *s, int i, int n)
    {
        int j;
        for (j = n - 1; j >= 0; j--) {
            s[j] = '0' + (i % 10);
            i /= 10;
        }
        for (j = 0; j < n - 1; j++) {
            if (s[j] != '0')
                break;
            s[j] = ' ';
        }
        return;
    }
    
    void G01Main()
    {
        int i;
        char s[5];
        for (i = 0; i <= 999; i++) {
           setdec(s, i, 3);
           s[3] = ' ';
           s[4] = 0;
           g01_putstr0(s);
        }
        return;
    }
  • これをmakeすれば173バイトになります。これを実行すると、以下のように表示されます。
      0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
     20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39
        (中略)
    960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
    980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999

  • ex0009は桁がそろっていてきれいだと僕は思うのですが、もしかしたら余計なスペースを表示しないほうがお好みかもしれませんね。じゃあそれも直せるようにしてみます。ex0010.cです。
    #include <guigui01.h>
    
    void setdec(char *s, int i, int n)
    {
        int j;
        for (j = n - 1; j >= 0; j--) {
            s[j] = '0' + (i % 10);
            i /= 10;
        }
        for (j = 0; j < n - 1; j++) {
            if (s[j] != '0')
                break;
            s[j] = ' ';
        }
        return;
    }
    
    char *skip_space(char *s)
    {
        while (*s == ' ') {  /* while (A) は for (; A;) と同じ意味 */
            s++;
        }
        return s;
    }
    
    void G01Main()
    {
        int i;
        char s[5];
        for (i = 0; i <= 999; i++) {
           setdec(s, i, 3);
           s[3] = ' ';
           s[4] = 0;
           g01_putstr0(skip_space(s));
        }
        return;
    }
  • これをmakeすれば195バイトになります。これを実行すると、以下のように表示されます。
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
    30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
        (中略)
    7 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 98
    7 988 989 990 991 992 993 994 995 996 997 998 999

  • さてここまではただ数字を数えているだけでした。こんなのくだらないと思うでしょう。でもこういうのは、たとえばcalendarの基礎になっています(calendarなんて結局は公式でその月が何曜日から始まるか計算した後は、1からその月の最終日までsetdecして表示しているだけです。表示をそろえるための多少の装飾はしていますけどね)。
  • それでは今回の最後は、もうちょっと計算らしいことをします。うーん、そうですね、たとえば、0から100までの和を計算してみましょう。ex0011.cです。
    #inlude <guigui01.h>
    
    void setdec(char *s, int i, int n)
    {
        (ex0010.cと同じ内容)
    }
    
    char *skip_space(char *s)
    {
        (ex0010.cと同じ内容)
    }
    
    void G01Main()
    {
        int i, j = 0;
        char s[11];
        for (i = 0; i <= 100; i++) {
           j += i;
        }
        setdec(s, j, 10);
        s[10] = 0;
        g01_putstr0(skip_space(s));
        return;
    }
  • これをmakeすれば183バイトになります。これを実行すると、以下のように表示されます。
    5050
  • もちろんこれは正解です。言うまでもないですが、これをたとえば1000までの和の計算に変えるにはどうしたらいいか分かりますよね?(ちなみに1万までの和にすると、32bitのintではオーバーフローしてしまうので、このプログラムでは正しい答えが出せません)。また、256から512までの和、なんていう変則的な計算もやろうと思えばできるはずです。それに、1から10までの積だって計算できると思います。

  • おまけ
    • [Q] 「ぐいぐい01」の使い方を覚えるメリットってなんですか?それはOSASK-HB用のアプリが書けるだけじゃないですか?あと小さいこと?(笑)。
    • [A] はい、結局はそれだけです。
    • [Q] 単純にC言語の勉強をするとしたら、普通にprintf()とかを使って勉強するほうが将来のためになりますよね?
    • [A] この先5年くらいまでを想定して、仕事に使える能力という意味なら、多分その通りです。
    • [Q] なんですかその言い草は?まるで10年後はそうではないみたいな言い方ですね。
    • [A] はい。ちょっと説明させてください。・・・まずあなたが何かC言語でプログラムを書いたとします。gcc向けということにしましょうか。そのプログラムは、10年後も無修正で動くでしょうか?hello程度なら問題なくコンパイルが通って動くと思います。しかし10KB程度の、世間では比較的小規模とされるプログラムでさえ、gcc-2.x系でコンパイルできたものがgcc-3.x系では動かず、さらにgcc-3.x系で動くものもgcc-4.x系では動かないということが少なくありません。そんな数年ごとにメンテナンスを強いられるようなプログラミングがお望みでしょうか?そんな時代と共に変化するような技術を身に付けたいと思うでしょうか?
    • [Q] なんか急に偉そうですね。じゃあなんですか?「ぐいぐい01」はそうではないといいたいんですか?
    • [A] はい。「ぐいぐい01」はそうではありません。現在は開発途上でその理想を果たせていませんが、それが落ち着けば、一度書いたプログラムは永遠にソースの改変が必要になることはありません。それどころか、再コンパイルさえも不要です。だからソースをなくしてしまったり、クローズドソースでソースが手に入らなくても、将来にわたって安泰です。
    • [Q] でもx86でしか動かないんですよね?x86が主流じゃなくなったら、「ぐいぐい01」だって使えなくなるのでは?永遠は言いすぎですよ。
    • [A] それはそうです。おそらくその頃にはそのCPU用の「ぐいぐい01」が提供されるだろうとは思いますが、bit数の違いやアラインやエンディアンの問題などで、ソースの変更が必要にはなるでしょう。でもそれを言うなら、gcc向けのソースだって全く同じです。これが嫌ならjavaや.netをお勧めします、現状では。
    • [Q] それにgccだって古いバージョンを入手してコンパイルすれば済みますよ。
    • [A] その通りです。でも比較的新しいディストリビューションでは、古いバージョンのgccの入手性がそれほどよくないように思うのですが・・・まあこれが心配ではないのなら、gccでもいいと思いますよ。
    • [Q] それにLinuxのバージョンを上げなければ、そもそも再コンパイルの必要もないですよ。
    • [A] そうですね。でも古いPCが故障して新しいPCを買ったときに、その古いLinuxがその新しいPCにインストールできるでしょうか。・・・結局ソースを持っていなくても、どのOS上でも実行できる「ぐいぐい01」と、OSが変わるたびにソースから再makeしなければいけないgcc向けアプリ。どちらに将来性があるでしょうか。でも将来のことは分かりません。結局「ぐいぐい01」は永遠にマイナーかもしれません。メジャーになろうと努力する気がないので、マイナーのままで終わる可能性は十分に高いです。でも誰かがメジャーにしたいというのならそれをわざわざ妨害する気もありません。みんなが便利そうだと使っているうちに普及してしまうかもしれません。
Page Top

こめんと欄 anchor.png[5]

  • 次回はコマンドライン引数関係のAPIについて書く予定。だけどこのページの人気がイマイチなら書くのはずっと先、ということで。 -- K[2] 2009-01-12 (月) 12:20:21
  • abcdw014向けの記述に修正。 -- K 2009-01-16 (金) 20:01:49

Last-modified: 2009-11-21 (土) 00:00:00 (JST) (319d) by k-tan