Dokusyo-nissi Bessitu 2007-04-08 φ(-_-) ■[lang]はじめての C [Learning GNU C] アルゴリズムを用いたプログラムやバッファ処理等々の解決は後まわしにして、 "Learning GNU C" をしばらく訳していくことにします。 http://www.nongnu.org/c-prog-book/online/ (ぼくと同じで英語がダメダメなために C に近づけない人も多いだろうし ...) Learning GNU C はし書き 1. 対象となる読者層 ようこそ Learning GNU C へ。この本の目的は GNU ユーザがどうすれば C で software が書けるかを教えることだ。それは第一に初心者のための tutorial とし て書かれたが、経験をつんだプログラマにとっての reference としても十分に役だ てられる。基本は初めの数章ですべて規定されていて、初心者は以前の復習のため にざっと目を通すことでこれらの章を注意深く読むことができる。そこでの全ての 情報にはそれ以前にプログラムの知識は想定していない。 読者には GNU のシステムを備えたコンピュータにアクセスできることが想定されて いる。対象となる読者層が GNU のユーザであるにもかかわらず、この本の内容はま た OpenBSD、FreeBSD あるいは NetBSD のユーザへも 98% は適切なものだろう。全 てのコマンドはプログラミングの例題に並べて説明されているが、コンピュータを shell (コマンドライン) から使うある程度のあなたの知識が役にたつはずだ。あな たがその経験を必要とする software の唯一のものはテキストエディタだ。どんな テキストエディタでも実行されるだろう。 GNU Emacs はプログラマにとって特に優 れたものだ。それは 20年以上にわたって開発され何百もの役だつ特徴を含む。 GNU Nano はあなたが使えるシンプルなテキストエディタであり、プログラマの一部では vi (vee eye と発音) を好んで用いている。もしあなたにすでにお気に入りのテキ ストエディタがあるならそれを使うことができる。またプログラマのために適応し た Anjuta や K Development のようなグラフィカルなエディタもあるが、多くのプ ログラマはテキストにもとづくエディタのほうを好む。 2. このテキストの範囲 この本の内容は 2つの課題に分けることができる -- C の核となるもの、それとプ ログラマが利用できるようつくられた標準機能だ。私が挙げる標準機能は GNU Libc に用意されていて、それはあらゆる GNU のシステムの一部で C の機能であるライ ブラリだ。これらの課題はどちらもそれ以外のものがないと使いようはそれほどな いが、language の核のところをスタートし始めた時の、そして最終的にはより多く の Libc を検討する際の要 (かなめ) となる。 C Programming を教えることを企図 したこの課題の処理では、そこでそれぞれの章が前のものの上へと組み立てること で (自然と) 増していく方法をとっている。この language のいくつかの特色は -- それは終わりに近づくと現われるが -- ただプログラマが経験して実際に使ってみ ることだ。 C language ではそれ自身が、コマンドの反復、データ保存それに数式の実行という 結果をだす。同じように重要なのはそれがこうした Libc という特別な機能を用い る方法を備えていることだ。 Libc では、ファイルの読み書き、データのソートや検索、ユーザからの入力受理、 ネットワーク越しの交信、簡便な translatable program の作成、その他多くのこ とを機能として備えている。 2007-04-09 φ(-_-) ■[lang]はじめての C [Learning GNU C] 3. なぜ C を学ぶのか? C は standard (標準) だ。それはプログラマの programming language だ。それは GNU や BSD の基幹システムでの standard な programming language だ。そこで作 動するこうしたシステムやアプリケーションの多くが C で書かれている。 C は 30 年以上前に OS やアプリケーションを書くために開発された。それは小さく、その 拡張性のある設計はコンピュータ産業の発展に寄与してきた。その時代と人気とに より、C は非常に支持される language だ。 C programming をより簡便にするため の tool があり、こうした tool はしばしば非常に練られていて high-level な standard をもっている。この本で用いることになる全ての software は C で書か れている。 4. なぜ GNU を用いるのか? GNU は完全な UNIX 仕様の OS であり開発にはまさに 20年以上費している。 GNU の software はその安定性と standard に添っていることとが認められている。 多くの GNU システムがカーネルのように Linux で用いられる。そうしたシステム はたいてい GNU/Linux システムとして知られている。 2007-04-11 φ(-_-) ■[lang]はじめての C [Learning GNU C] 5. なぜ Free Software なのか? GNU に関する最も重要なことは、それが Free Software として知られる完璧なシス テムであることだ。 software は、それがどんな目的に対しても使えること、その software に変更を加えられること、他者と software を共有すること、そしてその software の修正版が配布できることの自由を人々がもつ場合、それが "Free Software" である。 software が Free Software でないものは所有権 proprietary をもつ software と 呼ばれている。それがそう呼ばれるのは、人はその software が彼らの所有に属す ることを主張し、それの他からの共有や変更を禁止しているからだ。 モラルという見地からすると、Free Software を書くことはより多く社会に働きか ける方法の 1つだ。 Free Software ではそのユーザに彼らの望む変更を加えること (または他のだれかにそうした変更をしてもらうこと) のためその software を自由 に使えることを認める機能が与えられている。それは人々にその隣人と software を共有することで援助することを認める。所有権をもつ software はその反対だ -- それはだれかが援助を求めたとき "Yes" と答えれば犯罪となることを人々に告知し 共有は違法なことだとする。そして Free Software はその software を改良したも のを配布することにより人々が彼らのコミュニティを援助することを認めている。 Free Software はまた、貧しい人々や発展途上国の人々に対し区別することはない 。彼ら全員にこうした自由を認めることで彼らにその「特典」に対する法外な金額 を支払うことなく彼らがコンピュータで使用することを許している。 最後に技術的な利点がある。 Free Software は市場での操作から自由である。それ はユーザに余分な数の software を購入するよう強要することからそれ自身を制限 している。それぞれの GNU (software) は (それ単体でも) できるかぎり有用であ るよう設計されている。プログラマとしてあなたは大きなプロジェクトで使われて いる同じ C programming language を使用することができる。 free でない program は通常その機器のみで読み込み可能な形式で配布されている 。それは program 内部で何が進行しているか知ることができないことを意味する。 対照的に、Free Software では人間が読むことができる形式のソースコードの状態 になるよう要求される。プログラマとしてあなたは Free Software のあなたの好き などんな箇所のソースコードでも読むことができる。もし program にまちがいがあ ればそれらを訂正することも可能だ。 こうしたまちがいの訂正や機能性の追加は GNU Software にとってより役にたつ。 全てのコードにおいて同様の再調査が有効だ。 Free Software はこの世界をより良く変えていくだろう。 2007-04-21 φ(-_-) ■[lang]はじめての C [Learning GNU C] 第1章 C 入門 1.1. プログラミング言語とはなにか? プログラミング言語はコンピュータによって実行される命令処理系統をレイアウト するための様式 (format) と定義される。プログラミング言語は 3つのカテゴリー に区分することができる -- interpretted 言語、compiled 言語それと機械語だ。 これらのタイプのうち機械語のみが直接コンピュータによって理解される。 機械語はコンピュータの CPU (中央集積回路) が理解できる命令の組み合わせだ。 全ての命令と情報は数字で表わされる -- コンピュータに対しては非常に高速だが 人の頭脳にとってはその読み書きがとても困難だ。コンピュータプログラミングの 仕事を容易にするため人々は assembly 言語とよばれるよりやさしい言語をつくり あげた。assembly 言語は機械語のコマンドを利用するために text による name を 用意したものだ。これはプログラマに彼らの code にスペースやタブを加えること を可能にしたという事実とともに assembly 言語でははるかにやさしくプログラム が作成された。そして assembly code により assembler を提供することで該当す るコンピュータの CPU の機械語に翻訳させることができた。 assembly 言語の使用はすみやかに拡大しそれは「第2世代の言語」として知られる ようになったが assembly 言語にはまだ 2つ問題がある。まず第1にそれぞれのコマ ンドは 2つの数の加算やメモリからの値の load のような非常に基本的な仕事しか できない。こうした小さなコマンドを使うのはまったく面倒だ。 2つ目の問題はず っと大きい。 assembly 言語で書かれたプログラムは特定の CPU のタイプに制限さ れる。それぞれのタイプの CPU はそれ自身の機械語をもちそのためそれ自身の assembly 言語をもつ。その次の仕事が多くの CPU の機械語に翻訳できる言語の設 計だった。 そうした機械から独立した新しい言語は「第3世代」のまたは "High-level" 言語と して認知されていった。容易に読めるよう設計されたそうした言語は英単語、数字 記号そしてわずかな句読点文字からなっていた。これらの言語では例えば次に示す ように 2つの数の加算と結果のメモリへの割り当てを簡潔に表現した単純な命令文 を可能にした。 data = 10 + 200; rather than: Load R1, 10 Load R2, 200 Addi R1, R2 Store R2, L1 (追記) 訳文を全体にわたって訂正 ...oLr 2007-04-22 φ(-_-) ■[lang]はじめての C [Learning GNU C] 1.2. C とはなにか? compiler とよばれる tool は high-level の code を機械語に変換するとき使われ る。プログラムは C で書くことができそれは compiler に特定の hardware へ正確 に命令させるのに適していたのでどんなコンピュータに対してもコンパイル*1 (compile) がされた。 では C が assembly 言語と比較してどれだけ読みやすいかを知るためそれぞれで書 かれた小さなプログラムを下に見てみよう。 Example 1-1. C vs. Assembly language .section .rodata .LCO: .string "Tax Due: %d\n" .text .align 2 .globl main .type .main,@function main: pushl %ebp movl %esp, %ebp subl $24, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp movl $1000, %eax movl $400, %edx movl $0x3e6147ae, -12(%ebp) subl %edx, %eax pushl %eax findl (%esp) leal 4(%esp), %esp fmuls -12(%ebp) fnstcw -18(%ebp) movw -18(%ebp), %ax movb $12, %ah movw %ax, -20(%ebp) fldcw -20(%ebp) fistpl -16(%ebp) fldcw -18(%ebp) subl $8, %esp pushl -16(%ebp) pushl $,LCO call printf addl $16, %esp movl $1, %eax leave ret .Lfel: .size main,.Lfel-main And the program in C: #include int main() { int wages = 1000; int tax_allowance = 400; float tax_rate = 0.22; int tax_due; tax_due = (wages - tax_allowance) * tax_rate; printf("Tax Due: %d euro\n", tax_due); return 0; } たとえ C を知らなくてもあなたはどちらがよりわかりやすいと感じただろうか。ど ちらのプログラムもその出力 (output) は同じだ。 "Tax Due: 131 euro." (上に) 示された assembly の code は "80836" の命令系で書かれ異なる命令系統 が使われる機械では作動しないだろう。 C の code はほぼどんなコンピュータでも コンパイルすることができる。 2007-04-24 φ(-_-) ■[lang]はじめての C [Learning GNU C] 1.3. Programming Tools GNU は GCC とよばれる compiler をともない出現した。最初それは "GNU C Compiler" と名付けられたが C 以外の言語もコンパイルできるためその名前を "GNU Compiler Collection" に変更された。 GCC をインストールしたかどうかを調 べるには次のようにタイプする、 ciaran@pooh:~/book$ gcc --version ciaran@poor:~/book$ あなたのインストールした GCC の version は、たぶん (それぞれ) 異なっている だろうが、例えば "2.95.2" あるいは "3.3.0" に似ているものなら OK だ。仮りに "command not found" といったエラーメッセージが出たなら GCC はインストールさ れていない。 CD から GNU をインストールしていれば GCC はそこで見つかるはず だ。もしあなたが CD からアプリケーションをインストールする方法を知らないの であれば友人か GNU システムをインストールしたことがあってあなたのためにそれ をしてもらえる人をつかまえることだ。 2007-04-26 φ(-_-) ■[lang]はじめての C [Learning GNU C] 1.4. GCC 入門 では tiny という小さな code とそれをコンパイルする方法を示そう。ここでの要 点は GCC の使い方を示すことなのでまだ C の code の説明は行なわない。 GCC で コンパイルするこれが最小の code だ。それはなにも実行しない。 Example 1-2. tuny.c main() { } この 1つの code をテキストエディタ上からタイプし tiny.c というファイル名で 保存する。その終わりに ".c" を付けることでどんなに長い名前でも選ぶことがで きる。これは C で使われる拡張子 extension でありプログラムをコンパイルする 時に GCC が拡張子をチェックする。ファイルが保存されれば次はタイプすることで 実行プログラムへとコンパイルができる。 ciaran@poor:/~book$ gcc tiny.c ciaran@poor:/~book$ このコマンドは成功しても出力を返さないはずだ。もしなにかエラーメッセージが でたならタイプしたプログラムにまちがいはないかを調べる。 8個の単語について チェックしそれがおそらく正確にできたと仮定して次に進もう。 "a.out" というフ ァイルがディレクトリ内にできたはずだ。それは上記の code からつくられた機械 語のプログラムでありそれを動かしても実際にはなにも実行しないことがわかるだ ろう。 "a.out" という名前は歴史的な理由によっており assembler の出力にして はそっけない。 この code は GCC がコンパイルするとしても厳密には完全ではない。 GCC では警 告することでなにが欠けているかを知らせるようにできる。今のところ警告のメッ セージを理解するのは期待できないのでここではただ GCC の警告が実行されること を示そう。コンパイルの時のコマンドを変更し "-Wall" を加えることで警告がされ るようになる。 ciaran@poor:/~book$ gcc -Wall tiny.c tiny.c:2: warning: return type defaults to 'int' tiny.c: In function 'main': tiny.c:3: warning: control reaches end of non-void function ciaran@poor:/~book$ こうした警告はプログラムが完全には正確でない理由を表示する。これらの警告を とり除くにはあと2つ line を加えないとならない。これが最小で有効なプログラム だ。 Example 1-3. tiny2.c int main() { return 0; } "-Wall" オプションでこれをコンパイルしても応答はされないだろう。 ("a.out" のかわりに) プログラムに与えようと思う名前を指定するには "-o filename" とい う別のオプションを使うことで可能だ。 ciaran@poor:/~book$ gcc -Wall -o tiny-program tiny2.c ciaran@poor:/~book$ ls tiny2.c tiny-program ciaran@poor:/~book$ ./tiny-program ciaran@poor:/~book$ 2007-04-29 φ(-_-) ■[lang]はじめての C [Learning GNU C] 1.5. なにが C の有効性を決めるのか? プログラマにとって「C の有効性」はその compiler によって定義される。 C には 多くの様式 dialect が存在するがありがたいことにそれは全てよく似ている。また 他に Objective C や C++ のような C をもとにした言語がある。こうした言語はそ の外観はとても C に似ているがその扱い方が全く異なる。 GCC は (Objective C や C++ を含む) 多くの他の言語と同様 C の多くの様式を解釈する。 1.5.1. "K&R" C C は 1969年から 1973年の間に Dennis Ritchie によってつくられた。 1978年 Dennis Ritchie は Brian Kerningham とともにすばらしい C の tutorial 『プロ グラミング言語 C』を出版した。それはこの言語の初めての正式な定義だった。こ のオリジナルの様式を用いる場合はそれは時に Traditional C と呼ばれた。まずい ことにこの本には多くの言語の未定義な局面が残されていてそれは compiler を書 く人がこうした局面をどう扱うかに関して定義しなければならないことを意味した 。その結果 1つの code はどの compiler が使われるかによってさまざまに振る舞 うことになった。この様式はあまり長くは用いられていないが GCC はとても古いプ ログラムをコンパイルする際でもそれをサポートする。ここでは歴史的な目的にの みそれに言及する。 1.5.2. ISO C 1983年 ANSI はより厳格な standard (標準) を作成しまたこの言語で彼らの見つけ たほんの少しの欠陥を調整するための委員会を設立した。 1989年には ISO によっ て受理された standard が最終的に決定した。この新しい様式は C89 として知られ ることになる。それはまた ISO C または ANSI C とも呼ばれる。 GCC は compiler によるその適応が最も確認されたものの 1つだ。 1.5.3. C99 ANSI C は不定期にその standard を改訂する会合を開く。 standard の最新の改訂 は 1999年に発表されそれは C99 として知られている。 C99 をサポートする compiler はまだほんのわずかであり多くの重要なソフトウェアをそれぞれの OS で 変更するには時間を要する。 GCC による C99 のサポートは (これを書いている時 点で) ほとんど完璧だが開発者たちはそのために努めている。 1.5.4. GNU C GNU C は C89 に最も似ているがそれは C99 での新しい機能に加えて他にもいくつ かの拡張をもつ。こうした拡張は C99 によっては良好な解決策が提供されないとい う問題点を捜し出すことから注意深く加えられる。 GNU C は GCC の初期設定 default の様式でありこの本で用いられる様式である。それらを用いる場合には GNU での拡張はできる限り示すよう努めるが通常では GNU C を十分に使うほうがよ り適切だ。 ISO C を用いるのはプログラムを最低限の水準線での基準に限定するこ ととなりそれは単に特殊な場合でのみ使われるだろう。 1.5.5. 様式 dialect の選択 もし初期設定以外である様式を用いたい場合にはそうした選択を "-std=" に続けて 様式の名前を換えることで指定できる。そうした名前には c89, c99, gnu89 それと gnu99 がある。 "gnu89" が現在の初期設定だが C99 のサポートが完全になれば "gnu99" が初期設定となるだろう。変更は特別注意するものではない。 1.5.6. 将来の standard GCC に加えられたこうした拡張は新しい ISO C に対する inspiration が主な源泉 となっている。 ANSI C グループが多くの compiler での拡張を移植したとわかれ ばその将来における必要性を再検討しもしそれが利益になると判断すれば standard にそれを移植する方法を計画する。 GCC での拡張のうちいくらかは次の standard に導入されいくらかはそうならないだろう。 1.6. 結論 これで前置きは終わりだ。今ではプログラミングとは何なのかを理解したと期待を して。次の章では実際になにかを行なうプログラムを書きそれがどう動くのかを説 明しよう。 2007-05-01 φ(-_-) ■[lang]はじめての C [Learning GNU C] 第2章関数から始めよう 2.1. 関数とはなにか? 関数は C のプログラムを組み立てている block (区画) のことだ。ほとんどの C のプログラムは関数と呼ばれる -- 名前をもった -- code の block から成り立っ ている。プログラムを書くときには必要な仕事を実行する多くの関数を書くことに なる。しかし多くのプログラマに必要な例えば画面に text を表示するというよう な平凡な仕事がたっぷり存在する。誰もが車輪を再発明するかわりに GNU のシステ ムではそうした多くの仕事に対してあらかじめ定義された関数のライブラリが準備 されている。長年にわたって数千のこうした関数が蓄えられた。もし BINGO のよう なゲームをプレイするプログラムを書いていたならゲームに特定した関数を自分で 書かないといけないだろうが他の人がすでに乱数発生用の関数を書いているのを見 出すだろう。 全ての C のプログラムは main() と呼ばれる関数を 1つもたなければならない -- それはプログラムの実行をどこから始めるかということだ。プログラムの code は main() の中に完全に含まれるだろうが 1つのプログラムは多くの小さな関数に分割 されるのがより一般的だ。 われわれの見る最初の役にたつ code は 1つの classic だ。コンパイルし実行する とそれは画面上に簡単なあいさつを表示する。プログラムは main() と呼ばれる関 数を定義しそれは printf() と呼ばれる関数を呼び出す (使用する)。 printf() は われわれのために "Standard Device Input/Output Library" によって用意された 関数だ。このライブラリは全ての GNU システムで準備されている。これがその小さ なプログラムだ。 Example 2-1. hello.c #include int main() { printf("hello, world\n"); return 0; } 先に進むまえにこのプログラムをコンパイルして実行する。全てうまくいけば terminal (標準出力装置) に "hello, world" という文字列の text が表示される だろう。忘れてしまった場合のコンパイルのコマンドはこうだ。 ciaran@poor:~/book$ gcc -Wall -o hello hello.c ciaran@poor:~/book$ ./hello hello, world ciaran@poor:~/book$ もしなんらかのエラーあるいは警告メッセージがでたならあなたの code とこの本 の code とが正確に合致しているかを調べる。どんなメッセージを受け取るにして もそれはどこで間違ったかをその code の line で伝える。 code が正確にタイプ されていればこうしたメッセージを受け取ることはないだろう。 2007-05-04 φ(-_-) ■[lang]はじめての C [Learning GNU C] 2-2. line ごとの分析 それぞれの line がなにをしているのかを手早く説明しよう。仮りにいくつかの箇 所で自信がなくても心配いらない。もっと多くの例題をたっぷりやっていこう。 #include この line は GCC が "the Standard Device Input/Output library" からその関数 の使い方についての情報を取り入れる include ことを示している。通常標準入力装 置 the standard input device はキーボードであり標準出力装置 the standard output device は (モニター上に表示される) terminal のことだ。このライブラリ はとても広く使われているのでこの本の中で多くの関数と出会うだろう。 int main() この 2つの line で関数 main() の定義が始まる。 2つの line についての主要な ことは後ほど説明しよう。 { カッコ curly brace を開くことで code の block の開始を合図 signal する。こ のカッコとそれと対の閉じるカッコの間の全ての code が関数 main() の内容にな る。 printf("hello, world\n"); この line では関数を呼び出している。関数はすでに定義済だ。 printf() を呼び 出すときはなにをそこに表示するかを指示する引数 argument を渡さないといけな い。 return 0; return という statement (命令文) は関数 main() の実行を終わらせるのでこの line から後ではどんな statement も実行されないだろう。 main() はプログラム を抜け出し終了する。関数を終わらせるとき back でそれを呼び出した側へ値 value を渡すことができる。それは返り値をセットすることで行なわれる。 main() は常に (小数点を伴わない正あるいは負の数の) 整数を返す。 compiler へは main () の定義より前に "int" を置くことでこの要求を合図する。 main() から抜け出 す際問題がなければ 0 を返す慣習 convention になっている。 } カッコを閉じることで main() を構成する code の block の終了を合図する。 main() 本体を構成する 2つの line は statement として知られている。より具体 的にいえばそれらは (第4章で出会うことになる複合命令文 compound statement と 対照の) 単純命令文 simple statement だ。 C における statement は話しことば での sentence (文?) にあたる。 simple statement はセミコロンによって終了す る。プログラムでの改行は任意であり C では改行はけっして必要とされないがそれ は code をずっと読みやすいものにする。上の関数 main() が 0 の値を返すことは すでに述べた。多くの関数において返り値はプログラム内部で使うことができるが main() から抜け出すときにプログラムの終了を合図するのでそれ -- 返り値 -- は shell へ戻される。プログラムの返り値は shell に保存されるのでそれを知りたい ときは次のようにタイプする。 ciaran@poor:~/book$ gcc -Wall -o hello hello.c ciaran@poor:~/book$ ./hello hello, world ciaran@poor:~/book$ echo $? 0 ciaran@poor:~/book$ 2007-05-05 φ(-_-) ■[lang]はじめての C [Learning GNU C] 2.3. コメント コメントはプログラムに説明文をつけ加える方法だ。それは compiler には無視さ れるのでどんなときにもプログラムに影響することはない。あなたの書くプログラ ムがもっと大きくなればその code であなたがなにをしたかを思い出させるコメン トが役にたつことがわかるだろう。この本の例題へはそこでなにが行なわれている のか説明するコメントをつけていく。プログラムに入れるコメントを書き込むには 2つ方法がありもっとも普通の方法ではコメントの始めと終わりとにそれぞれ "/*" と "*/" をつける。この種のコメントは複数の line にまたがることができる。 2 つ目はコメントの始めに "//" をつける方法だ。こちらのコメントは line の最後 が (そのままコメントの) 終わりになる。コメントをもつ "hello, world" プログ ラムがこれだ。 Example 2-2. hello2.c /* このプログラムは スクリーンに * text を 表示し * 終了する */ #include int main() { /* printf() で 文字列 text を 表示 */ printf("hello, world\n"); return 0; // 0 は エラーが ないことを 示す } コンパイルの際この code は正確に実行ファイル executable を作成する。最初の コメントの 2行目と 3行目はアスタリスク '*' で始まっている。これは必ずしも必 要でないがコメントが 4行にわたることをはっきりとさせる。