■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
【 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
発行責任者 : 勝部 麻季人
< katsube@ichikoro.com >
発行部数 : 1787部(前回)
Webサイト : < http://www.ichikoro.com/webp/ >
お問い合わせ先 : < mm-webp@ichikoro.com >
Powerd by まぐまぐ
All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■