第 2 章 C プログラムの書き方 CPro:02-01 概要 C プログラムの構成要素は関数 ( プログラム = 関数の集まり ) 関数は, ヘッダと本体からなる 使用する関数は, プログラムの先頭 ( 厳密には, 使用場所より前 ) で型宣言 ( プロトタイプ宣言 ) する 関数は仮引数を用いることができる ( なくてもよい ) 関数には戻り値がある ( なくてもよい void 型 ) コメント ( 注釈行 ) は /* と */ で囲む コメントはできる限り詳しく, たくさん残す ( 英語で. 多バイト言語は使わない ) ブロック ( 複数の文を一まとまりとする ) は中括弧 { } で囲む C プログラムのデータには定数と変数がある 定数や変数の値は演算子で操作する 2.1 プログラムの動作 02-02 C のプログラムは, 必ず main という名前の関数から実行を開始する 基本は上から下へ ( 逐次実行 ) 飛び越し, 条件判断 (if else 等 ) ループ ( 繰り返し ) 関数の呼出 1
test2_1.c (p.33) 1 main() { main 関数の定義 02-03 2 printf( Now I m in main. n ); 3 func(); 4 printf( nnow, I m back in main. n ); 5 printf( And that s all I m going to do for now n ); 6 } 7 空行 ( あってもなくても良い ) 8 func() 9 { 10 関数の定義 printf( Now I m not in main. In func sub. n ); 11 } cc test2_1.c コンパイル a.out 実行 ( cygwinの場合は a ) Now I'm in main. Now I'm not in main, but in func sub. Now I'm back in main. And that's all I'm going to do for now! 実行結果 2.2 C の関数 02-04 Cの関数は call by value 入出力はライブラリ関数として用意されている putchar getchar printf scanf fputs fgets 2
test2_2.c 02-05 1 int addup(); /* test2_2.c (p.37) */ 2 main() 3 { 4 int i; 5 int sum; 6 7 i = 0; 8 sum = 0; 9 sum = addup(i); 10 printf("i was squared - it now equals to d n", sum); 11 } 12 /* 13 * add 1 to i if result is less than or equals 5, and then squar 14 */ 15 int 16 addup(i) 17 int i; 18 { 19 while (i <= 5) { 20 i = i + 1; 21 printf("i is d n", i); 22 } 23 i = i * i; 24 return i; 25 } cc test2_2.c a.out i is 1 i is 2 i is 3 i is 4 i is 5 i is 6 i was squared - it now equals to 36 02-06 3
2.3 関数の定義 CPro:02-07 ライブラリ関数の利用以外に 自分で関数を定義することができる. 名前 引数の個数と型 戻り値 test2_3.c 1 /* test2_3.c (p.40) 2 * Convert 1776 into Roman Number 3 */ 4 int romanize(); 5 main() 6 { 7 int a = 1776; 8 9 a = romanize(a, 1000, 'm'); 10 a = romanize(a, 500, 'd'); 11 a = romanize(a, 100, 'c'); 12 a = romanize(a, 50, 'l'); 13 a = romanize(a, 10, 'x'); 14 a = romanize(a, 5, 'v'); 15 romanize(a, 1, 'i'); 16 putchar(' n'); 17 } 18 /* 19 * 20 */ 02-08 4
21 int 22 romanize(i, j, c) 23 int i, j; 24 char c; 25 { 26 while (i >= j) { 27 putchar(c); 28 i = i - j; 29 } 30 return i; 31 } cc test2_3.c a.out mdcclxxvi 02-09 C の演算子 02-10 + & * - ^? : ( 三項 ) -- / == > >= ++!= << < <= &&! ~ >> *( 単項 ) ( ポインタ ) &( 単項 ) ( アドレス ). ( 構造体のメンバ ) -> ( 構造体のメンバ : ポインタのとき ) -( 単項 ) = 5
2.4 識別子 ( 名前 ) について 02-11 予約語 ( キーワード ) を除く 英字数字の組み合わせ 先頭は必ず英字 大文字, 小文字を区別 有効な文字数は処理系により異なる? [ 予約語 ] auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void while 等 C 言語入門問題集ー若林研究室ー 基本かつ重要問題, 無印 ふつうの問題, 難易度高の問題 02-12 2-1 2 つの引数 ( 整数 ) をそれぞれ, 足す ( 関数名 addi), 引く ( 関数名 subi), 掛ける ( 関数名 muli), 割る ( 関数名 divi) の結果を返す 4 つの関数を作成し, それらを 1 個のソースファイルとし prog02-1sub.c という名前で保存せよ. 各関数における計算処理は ( 除算も含め ) 整数演算でよい. そのソースファイルのみを先にコンパイルしてオブジェクトファイルを作れ (main 関数はなし ). つぎに, これら 4 つの関数を含んだファイルとは別に prog02-1main.c という名前で, それぞれの関数の実行を試すための main 関数を含んだプログラムを作成してコンパイルし, 先にコンパイルしておいた 4 つの関数を含むオブジェクトファイルと併せて ( リンクして ),1 つの実行プログラムを生成し, 実行せよ. 2-2 円の半径 ( 実数 ) を与えて ( 読み込んで ), 円周の長さを計算する関数と, 円の面積を計算する関数をそれぞれ ( 別の関数として ) 作成せよ. それらの関数を実行するメインプログラムも作り, 動作を確認せよ. ( ヒント ) 実数値を標準入力から読み込むには scanf 関数を用いる. [ 例 ] scanf("f", &radius); ( 入力する変数の前に "&" を付ける ) これを実行すると,float 型の変数 radius に値が 1 つ読み込まれる. 6
2-3 つぎのプログラム ("test2_3.c") 1 /* 2 * Convert 1776 into Roman Number and print 3 */ 4 int romanize(); 5 main() 6 { 7 int a = 1776; 8 9 a = romanize(a, 1000, 'm'); 10 a = romanize(a, 500, 'd'); 11 a = romanize(a, 100, 'c'); 12 a = romanize(a, 50, 'l'); 13 a = romanize(a, 10, 'x'); 14 a = romanize(a, 5, 'v'); 15 romanize(a, 1, 'i'); 16 putchar(' n'); 17 } 18 /* 19 * 20 */ 21 int 22 romanize(i, j, c) 23 int i, j; 24 char c; CPro:02-13 25 { 26 while (i >= j) { 27 putchar(c); 28 i = i - j; 29 } 30 return i; 31 } 02-14 を変更して, 整数 ( 例えば 1776) を引数として与えると, ローマ数字に変換した文字列 ( 例 mdcclxxvi) を返す関数 ( 関数名 i2roman) を作れ ( 関数の仕様を工夫すること ). その関数の実行を試すプログラムも作成し, いろいろな値を入力して実行してみること. 2-4 前問 (2-3) の関数とは逆に, ローマ数字の文字列 ( 例えば mdcclxxvi) を引数として与えると, 整数 ( 例 1776) に変換した結果を返す関数 ( 関数名 roman2i) を作れ. 7