言語
サーバ関連
ツール
API
読み物
その他
[AD]
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 【 Webプログラミング Code Sample 】 Since2001/11/23 Code023: Cプログラミング 〜C言語は関数の集合体〜 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Produced by ichikoro.com ▼毎週月曜日と金曜日に配信しています。 ▼等幅フォントでご覧いただくとキレイに見えます。 ▼登録・解除はこちらから可能です。 < http://www.ichikoro.com/webp/ > ※バックナンバーへのリンクもあります。 ※お友達にもぜひお勧めください(^^)/ ─【Contents】─────────────────────────────── 01.Review ................... 前回のおさらい 02.Guide .................... printf関数:これまでの復習 03.Guide .................... printf関数:出力書式 04.Guide .................... printf関数:使用例 05.Guide .................... 関数ってなに? 06.Guide .................... C言語は関数の集合体 07.Question ................. 今週の問題 08.From Editor .............. 編集後記 【 Webプログラミングは毎週2本立て! 】 ・月曜日版はWebの実際の活用方法などを特集します。 ・金曜日版はHTMLやCGIなど一つの分野について最初から 解説する講座になっています。現在はC言語入門です。 こんにちは、編集者の勝部です。 先週の土曜日だから...9日ですね、いつぞや見逃したロード・オブ・ザ・リン グ見に行って来ました。ヨーロッパはいいですね!大自然の中をロングショット で。う〜ん、たまりません。確かにCGとか使ってるんですけど、自然が上手い具 合にマッチしていて(映像は)なかなか見ごたえがあります。 ただ全体的に小奇麗にまとまってはいるんですが、話自体に奥深さが無いとい うか、人間ドラマが単調というか(^^; 世界観が上手くストーリーに昇華できて ないなぁという印象です。暗い感じが終始漂っているので、明るい気持ちにな りたい人は見に行かない方がよいかと。 あー、もう!心のそこから泣かせるか笑わせてくれる物が見たいぞ! 非常に欲求不満なのです。映画でも演劇でも本でも何でもいいから虜 にされる物求む。っていうかもう自分で作るしかないのか?(^-^; そんなわけで、今週もそろそろいってみましょう。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 01.Review 「前回のおさらい」 ────────────────────────────────────── 前回は、色々なサンプルをご紹介しました。 /* * 消費税を考える */ #include<stdio.h> int main(void) { int price = 200000; float rate1 = 0.03; float rate2 = 0.05; printf("%d\n", price); printf("%10.2f\n", price * rate1); printf("%10.2f\n", price * rate2); printf("%10.2f\n", price + (price * rate1)); printf("%10.2f\n", price + (price * rate2)); printf("%10.2f\n", (price * rate2) - (price * rate1)); return(0); } 今回は、その中でも皆さん気になっていると思われる“printf”を 取り上げたいと思います。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 02.Guide 「printf関数:これまでの復習」 ────────────────────────────────────── printfとは、これまでのサンプルからお分かりの通り“表示”を行う物です。 一番シンプルな例は printf("Hello!"); といったように、ダブルコーテーションで囲まれた文字列を表示するという 物です。これはみなさん分かりますよね。 ※ダブルコーテーションで囲まれたものは“文字列”として扱われます。 http://ichikoro.com/webp/back_list/index.cgi?cd=00015 次に出てきたのは変数を表示できるという物でした。 #include<stdio.h> int main(void) { int a = 100; printf("a = %d\n", a); return(0); } もう何度もサンプルが出てきているので、みなさんピン!と来ていると思いますが、 この %d の部分が変数の値と置き換わるのです。 「ちょっと待って、これまでに%d以外にもいくつか出てきているよね?」 するどい! 例えば、第1項の中にもありますが、 #include<stdio.h> int main(void) { float rate = 0.03; printf("%10.2f\n", rate); return(0); } といった具合に、今度は %10.2f の部分が変数と置き換わっていました。 ずばり答えを言ってしまうと、 printf("ここに表示する際の書式を記述", 書式で使用する変数もしくは値1, 書式で使用する変数もしくは値2, 書式で使用する変数もしくは値3, 書式で使用する変数もしくは値n); といったように指定するのです。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 03.Guide 「printf関数:出力書式」 ────────────────────────────────────── では、この書式についてご説明しましょう。 基本的に自由に文字を記入することができます。 例: "こんにちは" "ご一緒にポテトはいかがですか?" "君がため惜しからざりしいのちさへ 長くもがなと思ひけるかな(藤原義孝)" "↑なんて事を、しれっと言ってみたい物ですな" などといった具合です。 ただ、半角の '%' で始まるものについては、前述した通り特別な意味を持ちます。 結論から言うと “変数や演算結果など、指定する何かしらの値と置き換える” といった物ですが、様々なオプションや値の変換などが可能です。 具体的に言うと、下にあるような書き方ができます。 ※ % と 変換指示子 以外は省略が可能です。 ※ よく使うものしか書いていません。 % [フラグ] [最小フィールド幅] [精度] [変換就職子] 変換指示子 [フラグ] - マイナスを指定すると左詰に出来ます 指定しない場合は右詰になります + 値が正の値の場合、数値の前に + が付加されます。 逆に不の値の場合、数値の前に - が付加されます。 0 ゼロ字詰め(ゼロパディング)されます。 # 例えば16進数の場合、先頭に 0x(0X) が付加されるなど、 どんな値かわかるようになります。 [最小フィールド幅] 10進数値 ここで指定された数よりも値が少ない場合は、フィールド幅 を満たすまで、空白スペースで埋められます。 ※フラグに0が指定されている場合、0で埋められます。 [精度] .10進数値 例えば、“.3”というような指定になります。 よく使われるのは、小数点以降の桁数の指定です。 [変換就職子] h、l、L ※説明割愛。そのうちします。 [変換指示子] d 10進数の整数 o 8進数 x 16進数(小文字) X 16進数(大文字) f 浮動小数点 e,E 指数 c 文字 s 文字列 p ポインタ(アドレス) % %を文字列中に書きたい場合、“%%”とします 全部を覚える必要はありません。 主要なものだけ抑えておきましょう。 「とは言っても、これだけじゃ全然ピンとこないぞ(ーー;)」 むー、確かに。 では使用例を次の項で解説しましょう! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 04.Guide 「printf関数:使用例」 ────────────────────────────────────── まずはこのプログラムを実行してください。そして、実行結果を見ながらそれぞれが どういう意味をもっているか考えてみてください。 #include<stdio.h> int main(void) { int i_int = 15; /* intで扱うのは整数 */ double b_double = 9.876; /* doubleで扱うのは浮動小数点 */ char c_char = 'i'; /* charで扱うのは文字 */ printf(" 1:%d \n", i_int); printf(" 2:%5d \n", i_int); printf(" 3:%05d \n", i_int); printf(" 4:%-5d \n", i_int); printf(" 5:%+5d \n", i_int); printf(" 6:%+5d \n", i_int*-1); printf("\n"); printf(" 7:%o \n", i_int); printf(" 8:%x \n", i_int); printf(" 9:%X \n", i_int); printf("10:%#o \n", i_int); printf("11:%#x \n", i_int); printf("12:%#X \n", i_int); printf("\n"); printf("13:%f \n", b_double); printf("14:%1.3f \n", b_double); printf("15:%5.10f \n", b_double); printf("\n"); printf("16:%c \n", c_char); printf("17:%s \n", "abcdefg"); printf("\n"); printf("18:%% \n"); printf("\n"); return(0); } 実用的な例だと、こんな使い方がよくされます。 /* * YYYY/MM/DD hh:mm:ss 形式に変換する */ #include<stdio.h> int main(void) { int yyyy = 2002; /* 西暦年 */ int mm = 3; /* 月 */ int dd = 15; /* 日 */ int hou = 1; /* 時間 */ int min = 2; /* 分 */ int sec = 3; /* 秒 */ /* 表示 */ printf("%4d/%02d/%02d %02d:%02d:%02d \n", yyyy, mm, dd, hou, min, sec); return(0); } 読んでいればそのうち分かるようになると思いますが、 実際に使う場合はこんな感じです。 /* * 現在時間(ローカル)を表示する */ #include<stdio.h> #include<time.h> int main(void) { time_t ct; struct tm *now; int yyyy, mm, dd, hou, min, sec; /*-------------------------------------*/ /* 現在時間取得 */ /*-------------------------------------*/ ct = time(NULL); /* 暦時間 */ now = localtime(&ct); /* ローカル時間 */ /*-------------------------------------*/ /* 変数に格納する */ /*-------------------------------------*/ yyyy = now->tm_year + 1900; mm = now->tm_mon + 1; dd = now->tm_mday; hou = now->tm_hour; min = now->tm_min; sec = now->tm_sec; /*-------------------------------------*/ /* 表 示 */ /*-------------------------------------*/ printf("%4d/%02d/%02d %02d:%02d:%02d \n", yyyy, mm, dd, hou, min, sec); return(0); } 実行するたびに結果が変わりますよね (^-^)/ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 05.Guide 「関数ってなに?」 ────────────────────────────────────── printfについてはバッチシでしょうか?最初のうちはよく使う関数ですので、ここで しっかりと抑えておいてください。特にCGIで使う場合、printfは“必須”だったり します。慣れれば簡単...というか、とっても便利ですよー (^-^)/ さて、これまで“関数”という言葉を使ってきましたが、この関数とは一体どんな 意味なのでしょうか?よく、数学の関数のイメージがつきまとって最初は気持ち悪 いというようなことを聞きます。私みたいに学校の数学をあまり熱心に聞いていな かった人にはあまり違和感がないと思いますが(^-^; 実際に国語辞典を引いてみると、 > かんすう くわん— 【関数】 ・ かん— 【函数】 > > 〔数〕〔function〕二つの変数 x・y の間に、ある対応関係があって、x の値が > 定まるとそれに対応して y の値が従属的に定まる時の対応関係。また、y の x > に対する称。この時 x は単に変数または独立変数と呼ばれる。y が x の関数で > あることを y=f(x)などと表す。ふつう関数といえば、x の値に対して y の > 値が一つ定まるもの、すなわち一価関数をさす。従属変数。 出典:大辞林第二版 Copyright:(C) Sanseido Co., Ltd. 2002. All Rights Reserved とあります。 じっくり読まないとよくわからないのですが(^^; y = f(x) とあった場合、 「関数fの結果がそのままyの値になる関係」 とでも言い換えれるでしょうか。 ※違ってたら教えてください(^^; もともとこの“関数”という言葉は、英語(米語か?)の function を日本人が訳した 物のハズです。そこで、今度は function の意味も英和辞典で調べてみましょう。 > func・tion > n. 機能, 働き; > 【文法】 機能; 任務; 職務; 儀式; 会合, 催し; > 【数】 関数. > − vi. 作用[機能]する (as). > > function call > 【コンピユータ】 ファンクション・コール, 関数呼び出し. > function code > 【コンピユータ】 命令コード. > function key > 【コンピユータ】 ファンクションキー. > function library > 【コンピユータ】 関数ライブラリ. > function procedure > 【コンピユータ】 関数手続き. > function subprogram > 【コンピユータ】 関数副プログラム. 出典:EXCEED英和辞典 Copyright:(C) Sanseido Co., Ltd. 2002. All Rights Reserved 色々とご意見などあると思いますが、以上の引用を参考に考えると、関数とは 下のような意味があると考えられると思います。 ・関数(function) - 関数とは、何らかの“機能(部品)”のことである - 関数には、何かしらの値が与えられる - 関数は、与えられた値に対して(を元に)、何らかの加工(処理など)を行う - 関数は、何かしらの値(結果)を返却する ※返却する値がそのまま “関数の値” となる では、これをprintf関数に置き換えて考えてみましょう。 ・printf関数 - printfとは、指定の書式に従い表示を行う“機能(部品)”である - printfには、任意の書式(文字列)と、書式で必要な値が与えられる - printfは、与えられた値を元に、表示の処理を行う - printfは、成功した場合は表示したバイト数を、 失敗した場合は負数を返却する。 と言い換えれます。 実際のコードで確認してみましょう。 #include<stdio.h> int main(void) { int a = 100; printf("a = %d", a); return(0); } ・printf関数 - printfとは、指定の書式に従い表示を行う“機能”である 上のプログラムを実行すると、a = 100 と表示されます。 - printfには、任意の書式(文字列)と、書式で必要な値が与えられる ここでいう書式とは "a = %d" となります。 書式で必要な値とはもちろん、変数aのことです。 - printfは、与えられた値を元に、表示の処理を行う 上記の書式にしたがって、表示を行います。 - printfは、成功した場合は表示したバイト数を、 失敗した場合は負数を返却する。 おっと!これはまだ説明していませんでしたね。 さっそく確認するコードを書いて見ましょう。 #include<stdio.h> int main(void) { int a = 100; long result; /* 普通に表示 */ result = printf("a = %d\n", a); /* printfの実行結果を変数に代入 */ /* さっきの実行結果を表示 */ printf("result = %d\n", result); return(0); } ここまでで、printfは見事な関数であると証明できたと思います(笑) そうそう、上記コードで /* 普通に表示 */ result = printf("a = %d\n", a); /* printfの実行結果を変数に代入 */ この部分、勘のスルドイ方は気がつかれたと思いますが、 y = f(x) と、ほぼ一緒ですよね(^-^) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 06.Guide 「C言語は関数の集合体」 ────────────────────────────────────── C言語はこれら機能(function)の集合体です。 この関数には、大きく2種類に分けることができます。 ・標準ライブラリ関数 あらかじめ用意されている関数。 printfのような物をはじめ、文字列を検索、比較する物があれば、 ファイルの読み書き、メモリの制御をする関数もあります。 ・ユーザー関数 あなた自身の手で、関数(機能)を作ることができます。 もちろんそれを呼び出して使用することも可能です。 当面は標準ライブラリ関数をメインに紹介していきますが、そのうちユーザー関数 の作り方についてもご紹介します。 そうそう、みなさんがプログラムを記述している部分はmain関数と呼ばれています。 というのは最初のころお話しましたよね? int main(void) { } この関数だけはちょっと特殊で、こいつの役目は、様々な機能(function)を呼び出 し、それを統括することです。色々な関数がファイルの中にあったとしても、コン パイラはまず、main関数を見つけにいき、main関数にそって実行を行います。逆に このmain関数がなければ、プログラムは動作しません。というかコンパイル(リン ク)を通りません(^^; C:\>bcc32 test.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.c: ↑文法的には正しいため、コンパイルは通ります。 Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照) ↑リンク時にmain関数がないため、実行可能ファイルを作成できなかったのです。 だからみなさんはmain関数の中にプログラムを書いているのです。 こういう話が出てくるたびに、色々なところで取り合げられるのが、「世界最小のプロ グラム」です。コンパイル(リンク)を無事通過し、問題なく実行できる必要最小限の 構成はこんな感じです。 main(){} なんと一行、8バイトなんですね。 実際に実行してみましょう。 C:\>bcc32 test.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.c: 警告 W8070 test.c 1: 関数は値を返すべき(関数 main ) Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland C:\>test 何も処理を記述していないので、もちろん実行したって何も起こりません。 コンパイル中に警告が出ましたが、実行するのに問題は何らありません。 余談でした(^^; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 07.Question 「今週の問題」 ────────────────────────────────────── Q. 一回目のprintfから返却される値が、1234(byte) になるように下記のプログ ラムを“一箇所”修正しなさい。 ※必ず一箇所だけの修正に留めること。 #include<stdio.h> int main(void) { int a = 100; long result; /* 普通に表示 */ result = printf("a = %d\n", a); /* printfの実行結果を変数に代入 */ /* さっきの実行結果を表示 */ printf("result = %d\n", result); return(0); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 編 集 後 記 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ うーん、今回はかなりこゆかったですねぇ。もちろん目的は“関数”について知って もらいたかったという所です。実際に自分で関数作るようになればピン!と来るよう になります。また、今後説明していく様々な関数を使っていくうちに、次第にこうい うもんなんだと、感じるようになると思います。 キチンと考えながら読んでくださいね(^-^)/ 見ているだけでは身につきませんよ〜。 冒頭でロード・オブ・ザ・リングの話をしましたが、 ヨーロッパといえば、「ハリー・ポッターを探しにイギリスへ」という本を今週は 読んでました。原作を三冊ともあっと言う間に読んじゃいまして、手持ち無沙汰な ところに出会ったのがこの一冊。「ハリー・ポッターの料理・お菓子Cooking Book」 とどっちにしようか結構悩んだんですが(笑) で、この本、観光本というよりはむしろトラブル日記なのでした。 そこら辺に出回っているハリポタ関連本とは違い、ほのぼのとした雰囲気で笑わ せてくれる作者のトラブル体験談や、リー君(現地のガイド役)のやさしさにホロ ッと来たり、なんと行っても最後に訪れる“奇跡”。とってもさわやかな気持ち になれます。思わず「イギリスに旅に行きたいなぁ」という気になっちゃいまし た(^-^) ・ハリー・ポッターを探しにイギリスへ http://www.amazon.co.jp/exec/obidos/ASIN/4102901310/stagefan-22 ※映画見てから読みませう。 ・ハリー・ポッターの料理・お菓子Cooking Book http://www.amazon.co.jp/exec/obidos/ASIN/4876938059/stagefan-22 ※立ち読みしてたんですが、イギリスの家庭料理とか載ってるんですよね。 向こうの人が普段何を食べているのか興味あるじゃないですかぁ。 原作に事あるごとに出てくるカボチャジュースも興味津々です。 バタービールも飲んでみたいぞ〜。 そしてこの原稿を書いている最中にDVDを思わず予約。それも金のスニッチバー ジョンという豪華版!マトリックスのコレクターズボックスに引き続きやってし まいました。しかしこの内容で通常版の3倍は高いぞ。でも買うけどね、あは(^^; ・ハリー・ポッターと賢者の石 DVDスペシャルBOX 金のスニッチバージョン http://www.amazon.co.jp/exec/obidos/ASIN/B00005TO3B/stagefan-22 ではでは、次回は9月1日午前11:00、ロンドンのキングズクロス駅 9と4分の3... じゃない、月曜日にお会いしましょう (^-^)/~~ ※え、しつこいって?(^^; ■Information 「Webプログラミングからのお知らせ」 【相互広告募集のお知らせ】 読者数を増やしたいメルマガ発行者さんを募集しています。お互いに一定期間(1〜 3回程度)広告を掲載し合いませんか?詳細はご相談ください(無料) お問い合わせ: mm-webp@ichikoro.com 【コラム募集のお知らせ】 Webプログラミングでは、寄稿していただけるコラムやプログラムなどを募集して います。たくさんの読者の方にあなたをアピールする場にもなります。ぜひ有意義 な情報やご意見をお送りください。 お問い合わせ: mm-webp@ichikoro.com ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 【 Webプログラミング Code Sample 】 発 行 : ichikoro.com 発行責任者 : 勝部 麻季人 < mailto:katsube@ichikoro.com > 発行部数 : 1787部(前回) Webサイト : < http://www.ichikoro.com/webp/ > お問い合わせ先 : < mailto:mm-webp@ichikoro.com > Powerd by まぐまぐ All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■