プロミスのサイトです。
枚数 purchaseshvlNJS 日割り 発進 評判 ローン 完了 スタッフィ 貸付 許さ fromCharCode ダウンロード 突破 スピーディー currentOfferListingID アコム shopAllButtonNonJS 説明 外国 注目 単独 一身 ようこそ 書類 税金 番号 インタビュー 以内 財務局 キャッシュ

秘訣とは?/ プロミス

[ 201] Cプログラミングの秘訣
[引用サイト]  http://www.st.rim.or.jp/~phinloda/cprog.html

当時はまだWindows 95もないような時代で、現在の状況から見ると違和感のある内容も結構あるかもしれませんが、時代背景を想像しながら補正しつつ読んでいただければ幸いです。
今や、質はともあれ、C言語に関する書籍は数多く、入門書を自称したものだけでも十冊を越えるほどです。しかし残念ながら、これらの本を読んでC使いになろうと挑戦したにもかかわらず、挫折してしまった人や、数十行程度のプログラムなら書けるようになったが、そこから先、ちっとも上達しない、という方が多いのではないかと想像します。なぜC言語に挫折してしまうのか考えてみますと、一つは、世の中に「これだ」と言える程の入門書は本当に少ないのが一つの原因となっているようです。多くの入門書を読んでみましたが、どれも、ある程度のプログラミングの知識や、処理系、例えばMSDOSの知識が前提とされていて、本当に何もわかっていない人が読んでも何も分からないようなものが大半です。さらに悪いことには、これは私だけの意見かもしれませんが、入門をうたっているものほど、いいかげんな内容が多いようです。例えば式と文をごちゃまぜで説明したような本があります。何もしらない人がこれを読んで式とは何か、理解しろというのは無理な相談です。
そういう本に当たってしまった人は、単に運が悪かったのですから、よい本を読み直せばC使いになれる可能性が残っています。本当にくだらない理由ではありますが、よい教科書というのは実に重要なポイントだといえましょう。
さて、内容がしっかりした入門書や解説書を幸運にも買うことができたら、それでC使いになれるかといいますと、そう甘くはありません。先程書いたように、これらの書籍には、真の「わからない」人には、わからないことがいくつも前提にされています。これを身に付けているかどうかが、勝敗の分け目となるのです。
一言でそれを表現すると、「よいプログラムを書きなさい」ということです。よい文章と悪い文章があるように、よいプログラムと悪いプログラムがあるのです。また、うまい絵と下手な絵があるように、うまいプログラムと下手なプログラムがあるのです。誰でも、悪いプログラムよりは、よいプログラムを書こうと思うのが当り前です。わざわざ悪いプログラムを書こうと努力する人はいないはずです。
ところが、どのようなプログラムがよいプログラムなのか、これを説明した本はあまりありません。もちろん、「よい」という意味は総合的であり、非常に多くの内容に対して検討する必要がありますから、例えば「変数名は内容のわかるように付けよう」だとか、「不必要なコメントは省きましょう」というように、部分的に「よいプログラム」を作るための条件を指摘するという意味では、たいていの本にはそのような記述があると思います。しかし、総合的に考えて、どのようなプログラムがよいのかは、なかなか書かれていません。なぜかというと、これは簡単に書けるような問題ではないからです。それぞれの「よいプログラム」のための条件の中には、場合によっては両立しないこともあります。全体的には、バランス感覚が極めて重要であることは言えます。
そして、ここが重要なので、じっくり考えてください。「よいプログラム」を書くには、その人との相性があることが、必要不可欠だということを、事実として認めるべきです。あるいはセンス、素質の問題と言ってもいいでしょう。
この記事をご覧になっている皆さんの中には、おそらく、C言語とはどのようなものか、おおむねの知識があり、これからC言語を学んでマスターしようと意気込んでいる人や、あるいは今までC言語の入門書を何冊か読んで、Cコンパイラも買った。多少は例を見てプログラムを真似して、Hello World! くらいは画面に表示した経験がある人もいるかもしれません。また、まだ何にも知らない文字通りビギナーの人もいるでしょう。
特に、今まで何となくCのプログラムらしきものは書けるようになったか、なかなか上達せずに、行き詰まってしまった人。その理由はわからないが、今度こそはわかるかもしれないと思って期待している人もいるでしょう。
そこで、今度こそうまくいくかもしれない、と思った皆さんへは酷かもしれませんが、ここでとどめの一撃を受けてもよい時期にさしかかったのだと思ってください。人生は短いものです。無駄な時間を費やすことの方が、ずっとむごいことかもしれません。そこで、一つ考え直してみて欲しいのです。もしかして、あなたはプログラム作成には向いていないのではないでしょうか。あるいは、C言語には向いていないのではないでしょうか。今まで頑張った成果がいま一つと実感している方は、今やそれを疑ってみるべきです。
もしかすると、世間には「誰でもCプログラムが書ける」という迷信が広まっているかもしれません。プログラムの入門書を買ってきて読めば、誰にでもプログラムは書けるものでしょうか。ある意味では書けるといえるし、ある意味では書けないといえます。
例えば、誰かにペンを持たせて絵を描いてみなさいといったとき、全く何も描けない人は滅多にいません。とにかく絵を描くというのは、誰にでもできるのです。しかし、同じ人に、本の挿絵に使いたいからイラストを描いてくれと頼むと、ちょっと待ってくれと言われるかもしれない。「いや、私は絵は駄目なもので…」というわけです。絵が描けるというのと、「うまい絵が描ける」というのは別の問題なのです。
同じ様に、歌のうまい人と下手な人がいるし、ピアノがうまい人も下手な人もいます。。ピアノといえば、猫ふんじゃっただけは弾けるぞ、という人がたまにいるようです。そういう人にピアノを弾いてくれと頼むと、いや、実は弾けないのだと断わられるでしょう。Hello World! を画面に表示するというのは、ピアノで言えば猫ふんじゃったを弾けるかどうかのレベルの問題であり、早い話がC言語でプログラムが書けるかどうかという問題とは殆ど関係がないのです。絵の具を買ってきても誰でも絵が描けるわけではないのと同じように、コンパイラを買ってきてインストールして、よい入門書を読めば、だれでもうまいプログラムが書けるようになるとは限らないのです。
つまり、プログラムを書く人には、それなりの素質というか、相性が必要です。素質のない人が、死ぬ思いで修練したら、人並みのプログラムを書けるようにはなるかもしれませんが、生まれつきプログラマーに向いている人がセンスよく書いたようなプログラムを作るのは、多分無理でしょう。それよりはもっと自分に向いた何かを見つけて熱中した方がずっと有意義だと思います。
さて、ここで諦めた人は、もうこの後は読まないでしょうから、ここを読んでいる皆さんは、まだ頑張れるんじゃないかと希望を捨てなかった人だと思います。「相性が悪い人にはCのプログラムは書けません」で終わってしまうと、さすがに編集者に文句を言われるかもしれませんので、ここで、再度「よいプログラム」とは何か、考えてみることにしましょう。この後は、あくまで持論となります。一般論としては認められていないと考えた上で考察していただければ幸いです。
いきなり結論を書きましょう。「よいプログラム」とは何か。ずばり一言で。「そんなものは言葉で表現できない」というのが私の意見です。もちろん、各論として、よいプログラムの条件を個別に考察することは可能ですが、全体としてプログラムを捉える時、これがよいか悪いかは、結局プログラマの感性による所が大きいと思うからです。しかし、よいプログラムか悪いプログラムかは、ある程度の素質がある人が、いくつもプログラムを書いているうちには、体で判断できるようになってきます。ここが重要なのです。つまり、言葉で説明できないといっても、よい、悪いの差は歴然として存在するということです。
これについて、故松下幸之助が次のような意味のことを言ったそうです。商売の道というのは、言葉で説明しても理解できるものではなく、体験して初めて身に付くのである。例えば、塩がからい、砂糖が甘いというのは、塩や砂糖を味わった人だからわかるのであって、塩も砂糖もなめたことがない人に、それを説明することはできない。至言であります。プログラムのよい、悪いも、このように、それを体験して味わった人でなければ、真に理解することはできない、と思うのです。よい、悪いというのはそれほど感覚的な問題なのだ、という解釈です。
従って、いいプログラムの書けるC使いになるには、とにかくプログラムを作る、そして、他の人のプログラムもどんどん読む。これは重要です。自分の悪い所というのは、なかなか気付かないものです。しかし他の人と比べてみるとき、自分よりも巧くやっているな、と気付くのは簡単です。従って、自分の力だけで悪い所を直すのは、極めて非能率的であり、他のものと比較してみる、これは結構効きます。
さて、結論が出てしまいましたので、この記事はこれで終わりになる所ですが、もう一歩踏み込んでみたいと思います。よいプログラムを言葉で説明することはできないと書きました。しかし、各論として、よいプログラムの条件を個別に考察することはできるとも書きました。ならば、それぞれ細かい所でよい、悪いの評価を行う方法は残っています。これは全体的なよい、悪いの判断とは必ずしも一致しませんが、その一部分がよいプログラムは、全体としても、それ程悪くないことが多いと思います。
そこで、ありきたりのようですが、C言語に多少は関係あると思われるいくつかの条件に対して、一つのガイドラインとなるものを書くことにします。この後に書くことが、あくまでガイドラインに過ぎないことを念頭に置いてください。実際、これらのガイドラインを無視しても、Cのプログラムを書くことはできるはずです。場合によっては、あえて逆らってみる方がよいかもしれません。それが判断できる方なら、こんなガイドラインは不要ですから、自分の感性を信じて修行するべきです。
ただ、初心者の名乗る方の中には、本当に何をやってよいかわからないこともあります。C言語は、空白は読み飛ばすから、インデントはどのように付けても実行結果には関係ないだとか、好きなように書いて構いません、と言われても、それはそうかもしれませんが、何をやってよいやら全く訳のわからない人に、「好きにやってください」と言ってもかえって何もできなくなってしまうことの方が多いでしょう。よし、自分で考えて好きにやってやろう、という人は、それで結構です。考えるというのは重要なことですから。しかし、どうでもいいと言われても困る、何か参考になるものはないか、と思う人も多いはずです。既にあるものを真似して腕を磨く、というのは非常に多くの道において成り立つ手法ですが、プログラミングにおいてもそれは成り立ちます。そのための指針となるものとして、お役に立てば幸いです。
まず、これから書くことは、私が現在こうしようと考え、実行していることです。フィンローダ流とでも言いましょうか。これはあくまで一つの流儀であって、唯一正しい解釈であるということではありません。他の解釈の方が合理的であると考える人は大勢いると思います。
もう一つは、私自身、これからもずっとこれが正しいと考えるかどうかは、保証しかねるということです。プログラミングにおいて、これが最善と断言することは、なかなか難しいものです。たかが一人がプログラムを書いて身に付いたことを書くのですから、これからさらに経験を積むことにより、他の方法がよいと思い直したり、考え方が変わることは十分考えられます。日々是修行です。私が保証できるのは、これから書くことは、今の時点で最善だと思い込んでいることに過ぎないのです。
従って、これから書くことに対して、何か反論のある方もいると思いますが、反論の方に分があると思えば、私はころころと自説を変えると思います。その時に正しいと思った判断に従うという一貫性が最も重要であって、何か一度いったらあくまで覆してはならない、といった考えは、まるで持っていません。結構無責任といえば無責任な話です。
そこで、次のことを強くおすすめします。これから書くことは、あくまであなたがどうすればよいか、あなた自身で考えるための参考に留めてください。書いてあることを鵜呑みにしないで、自分自身で考えて、それに従って判断してください。考えるということは重要です。考える習慣を付けることが、よいプログラムを作る近道であることは確かです。
フィンローダ流のプログラミング書法の核心は、ただ一点に集約できます。プログラムを分かりやすく書く、ということ、これだけです。しかし、実際に書いてみればわかりますが、プログラムを分かりやすく書くということは、まず不可能に近いような神業に感じることが多いようです。
一般論としても、よく「プログラムは分かりやすく書こう」と言われます。中には、どうせ自分は趣味のプログラマーだから、他の人が読みやすいように努力してもしょうがない、と勝手に思い込んでいる人もいるようですが、とんでもない話です。分かりやすく書こうというのは、もちろん、自分が分かりやすくなるために書くのです。
しかし、恐るべきことに、この能力は時間が経過すると通常の状態に戻っていきます。その速度は、脳の力が高まる度合に比例します※。その結果として、自分が書いたものなのに、見たこともない文字の羅列となり、解釈すらできないことがよくあるのです。従って、分かりやすくプログラムを書く心構えは、まず他人たる自分のためにそうする必然性があることを、十分理解しなければなりません。
しかし、はっきりいって、分かりやすいか分かりにくいかは、主観に大きく依存する問題です。これが絶対真理だ、という法則はなかなか見つかりません。しかし、大雑把な範囲で、「こうすれば分かりやすいと感じる人が多いのではないか」という程度の判断は、多くの人が感覚的に知っています。ただ、なかなかそれを主張する人がいないのは、ある人が分かりやすいと思ったとしても、果たして他の人にとっても同様に分かりやすいだろうか、という決め手に欠けることが多いからでしょう。
非常にポピュラーな定石ですが、ファイルをオープンする処理の書き方に、list 1のようなものがあります。
もちろん、...の部分には、何か処理が書かれるのであり、実際に...と書くのではありません。さて、この記法がポピュラーなのは何故か考えてみましたが、おそらくK&Rにごろごろ出てくるからだと思います。昔はCを勉強する人はK&Rを読むしかないような時代もあったので、このような書き方をして分からないという人はいませんでした。もちろん、Cが使える人の中に、という意味です。そして、今も、この書き方でわからないという人は、C使いの中にはいないでしょう。
処理は一見それほど難解ではないと思いますが、初心者なら何のことやらわからないかもしれません。例えば、これは次のように読みます。
まさか本当にこう読む人はいるわけがありませんが。Cに慣れたプログラマーなら、この一行を一瞬見ただけで即座に処理を理解(連想?)して、次の行の解釈に移っています。定石とはそうでなければ意味がありません。まあ、定石だから、こう書いても何も悪くはないと思います。誰も責める人もいないだろう。私も責める気は毛頭ありません。ただし、私なら次のように書きます。
何故か? 実は某所で、プロならこう書くのだがと書いた所、間髪入れずに「どうしてなんだ」と質問が出たそうです。※
※実は、とあるパソコン通信サービスの話。ここは世界でも珍しい異次元空間で、はっ、と気付いた時にはばっさり情報が消滅しているので、答える暇もなかったわけだ。ちなみに、某所ってどこだというと、「パソコン通信サービス」なんて書くと苛められそうな所だ、というと、分かる人には、なんだアソコのことか、とすぐ分かる。
パソコン通信での秘訣を一つ紹介しますと、質問されそうなことがあらかじめ分かっていたら、前もって予想して回答を考えておくという秘伝があります。あまり書きたくはないのですが、念のため書いておきますと、上の場合、もしその質問があったら書くつもりで用意した回答は、「こっちの方が味がいいから」というものでした。余計わからない? だから書きたくないって言っているではないですか。
味がいいというのを理解してもらうのは大変です。私自身がこの味をなんとなく分かるようになるまでに、Cでプログラムを作り初めてから、少なくとも5年はかかったと思います。しかも、私がいい味だと感じても他の人もそう感じるかといえば定かではありません。そこで、もう少し科学的に説明できないか考えてみました。その結果、この味が、どうも思考の順序に関係しているのではないか、ということに気が付きました。そこで次のような仮説を立ててみます。
これは、後者のリストを、前者と同じ様に考えながら読んでみると分かります。どのように読めるでしょうか。
なんだ、あまり変わらないではないか。その通り。でも、あまり変わらないなりにも変わった所を見逃してはなりません。最も顕著な違いは、ifが現われた時の後処理です。先程の例では、まずifを見た時点で、一旦ifの処理中であることを、頭の中のスタックに積まなければなりません。最初の記法では、
の間に処理が割り込んでいるため、ifという文字を見てから、条件判断までの間が長くなっているのが一つの特徴です。そんな無茶苦茶長いわけではないのだから、この程度ならいいではないか、と考える人もいるかもしれません。それも確かにもっともではあります。
もう一つの特徴は、前者の括弧の数です。一般に、括弧の重なりが深いと、分かりにくくなります。かといって、むやみに括弧を外せばいい、ということではありません。次のように書く人は、余程の初心者がうっかり間違える場合でもなければ滅多にいません。
C言語では、演算子の優先順位がはっきり階級化しています。まず優先度の高いものから処理され、左右の順序は、優先度が同じ場合にのみ結果的に意味を持ちます。従って、このように書くと、優先順位の高い演算子である!=がまず評価され、その後にfpに続く代入演算子=が処理されることになります。すなわち、次のように括弧を付けた場合と等しく解釈されます。
一般論としては、優先順位について、絶対に死んでも間違いないという自身があるという程の場合でなければ、たとえ余計といえども括弧を付けておいた方が意表を突かれることは少なくなります※。
括弧についてもう一つ述べておきますと、括弧によって思考そのものも確実に入れ子になりますから、場合によっては、不要な括弧があることが、かえって分かりやすいこともあります。
別に難解でもなさそうに見えますが、一つ大きな罠を忘れているようです。というのは、上の思考には、優先順位が暗黙の了解として使われているからです。もし、本当に前から順に読めば、次のようになるはずです。
さて、現実にこんなことを頭で考えているかというと、この程度の記述であれば、C使いになって間もない人ならともかく、多分、慣れた人なら瞬時に何を行おうとしているのか判断するのではないでしょうか※。というのは、この種の条件判断は、しばしば行われるので、この表現自体に馴れているということも見逃せない事実であります。
※認知心理学という学問の分野がある。ユーザーインターフェースを設計しようとする人は、必ずかじっておくべきだろう。これによれば、人間が文字の並びを認識する場合には、あるまとまった単位を先にグループ化してから解釈を試みることが知られている。その意味では、
と解釈するのは不自然に感じられるかもしれない。そのような潜在的な欲求がある場合、本文で説明したような順序で解釈を行うというのは、いかにも不自然である。
では、括弧を付けた方がよいか、付けない方がよいか、はっきりしたルールを書いておくことにしましょう。ただし、もちろん、括弧を付けなくても付けなくても評価の順序が変化しないことを前提とします。
□ 括弧がなくても心理的に間違った解釈をする可能性が全くないと思われる場合には、括弧を省略しても構わない。
□ 括弧を省略すると、心理的に間違った解釈をする可能性が極めて高いと思われる場合には、括弧を省略してはならない。
なるほど、言いたいことは分かった。しかし、心理的に間違った解釈をしそうかどうかは、どのようにして判断するのかね? という質問が当然あるでしょう。それは修行して身に付けるべく、経験を積むしかないのです。
括弧の話はここまでです。では、なぜK&Rの本には、このように2行に分けずに、1行に書いたのでしょうか。当時はその方が処理系がよいコードを生成したのでしょうか。それとも、行数が減ることによって、見やすくなると判断したのでしょうか。同じ処理内容であれば、少ない行数で書いた方が、一度に目に入る密度が高くなって、理解しやすくなるという考え方もあります。
もう一の典型的な例を考えてみましょう。これは実に面白く、よくできていて、しかも初心者が引っ掛かりそうな書き方になっています。
この処理がわからないという人は、おそらくEOFと比較しているものが一体何なのか、理解できないのだと思います。cと比較しているのではないかと、漠然と解釈して乗り切る人もいるかもしれません。while の括弧の中は、次のように読めるでしょう。
秀逸なのは、「それが」の所です。C言語は、式も値を持っていることを利用した芸当です。ですから、厳密には、cとEOFを比較しているというのは正しくないのですが、あえてそのように思い込んでいるとしても、この例ではあまり差し支えはないでしょう。
これは無茶です。代入演算子の優先順位より、比較の演算子の方が高いので、getcharの値は先にEOFとの比較に使われてしまい、比較して同じだったかどうかという結果の値、すなわち0か1がcに代入されてしまいます。
今度は、確かに括弧の数は減りました。しかし、今度はwhileを使う必然性が弱まっています。これは単なる無限ループなのですから。
結局、この場合においては、最初の書き方に比べてあまりうまい方法はなさそうです。というより、最初の書き方がうますぎる、と言ってもよいでしょう。実際、この書き方は、C使いになるには、必ずマスターしておかねばならない表現の一つだと言ってよいでしょう。
という書き方に対して、むしろ違和感がとれて、理解しやすいといった現象も現われるのではないでしょうか。なぜなら、この記法は、まさにwhileの書き方と同種であるからです。
さて、ここまで読んだ方が、もし相当腕利きのC使いならともかく、初心者だったなら、一体どう書けというのだ、とイライラしてきたかもしれません。そこで、どっちがいいんだ、という方だけへのアドバイスだと思ってください。自分の意見のある方は、もちろんそれを優先させるのがよいと思います。
このように書くのは、思考の順序という意味では、ifの判断の中にfopenを入れるよりは勝っています。上の奥義を指針とすれば、もう一つ、よく迷うことのある判断に決着を付けることができます。
これがC言語で有名な、「==と=の間違い」というヤツで、誰でも必ずこの種の間違いをした経験があるはずです。この間違いの特徴は、処理の内容は全く異なるにも関わらず、いずれも文法的には正しいため、コンパイルが正常終了してしまうことです。実行してみて、何か動作が変だ、というあたりで初めてバグに気付くこともあります。この種のバグは、気が付かないと修正するまでに結構時間を取られるものです。
-1という値にiを代入するというのは、Cの文法としては誤りなので、コンパイルの段階で、エラーを発見することができます。従って、間違いはすぐに気付くというわけです。左辺に定数を持ってくると、代入できないということと、比較は左右を入れ替えても結果が同じである、という特徴を活かしており、その意味ではうまい方法だといえるかもしれません。
余談。比較は左右を入れ替えても結果が同じ、というのは、場合によっては成り立ちません。例えば、次のような場合、結果が異なるかもしれません。
しかし、このような記述は無謀です。なぜなら、比較の左辺と右辺のどちらが先に実行されるかは決まっていないからです。このような書き方をしたプログラムは、Cコンパイラをバージョンアップした後でコンパイルし直した後で動かなくなっても、何も文句は言えません。list 15はlist 16のように書くのが正解です。
※私は、比較の場合には右が先に実行されるという先入観がある。なぜなら、そのような処理系を使っていたからである。
話を戻しましょう。先程、左辺に定数を持ってくるのは、ある意味ではうまい方法だといえるかもしれない、と書きました。しかし、実は、フィンローダ流では、左辺に定数を書くことはありません。常に右に書きます。
どういう意味なのか、詳しく説明します。皆さんは、何かに対して何かする場合、どのように考えますか。これでは漠然として分かりにくいですか、例えば傘をさす、という場合に、「さす、傘を」と考えますか、それとも「傘をさす」と考えますか? 何を馬鹿な質問をしているのだ、「傘をさす」に決まっているじゃないか、と言われそうですが、これは重要なことです。普通、ものごとを考える順序としては、何かに対して、何かする、という方向であることが圧倒的に多いわけです。
そこで、先程の処理に関して、考えてみるべきことは、iを-1と比較したいのか、それとも-1とiを比較したいのか、ということです。この点はまず異論のないものと思いますが、殆どの人が、iという変数に何らかの値を入れて、それと定数とを比較する、という順序で処理を考えているのではないかと思います。言い換えると、ここでは主役は変数であるiではないか、ということです。
ならば、思考の順序としては、i == -1 と書いて、iと−1を比較しているのだ、と読ませる方が、はるかに無理がないのではないか、というのがフィンローダ流の根拠です。思考に無理があると、その部分の理解だけではなく、無駄なエネルギーを使うことになり、全体の理解の妨げにもなりかねません。その結果、バグを誘発するということは、十分考えられることです。小手先の技に溺れて、全体を分かりにくくしては、あまりに無駄だということです。
しかし、左辺に定数を書いたら、先程指摘したような間違いは防げるではないか、という考え方もあるでしょう。あくまでその間違いが怖いと思うなら、何も私の意見に従う必要はありません、自分の判断を尊重してください。早い話が、この程度のことは、どっちかにしないと無茶苦茶差がある、といったものではありません。※
ただ、私自身は両者比較した上で、定数は左辺に書かないと決めたのですから、左辺に書かないでも大丈夫という理由も一応書いておきましょう。
と書いてしまったとしても、コンパイルこそ正常に終了しますが、そのような記述をしてしまったことは明確に判断することができます。
次に、このような間違いは、Cプログラムに慣れれば殆どしなくなります。=と==を間違うというのは、かなり初歩的かつ初心者に多い間違いです。慣れるに従い、それよりも他のバグの方が圧倒的に多くなってきます。ならば、他のバグの原因となる、思考の妨害因子を少しでも減らした方が能率的だと判断しました。
そして最後ですが、今書いたように、この間違いは慣れれば殆どしなくなるのですが、それでもする人はします。私が最後にこの間違いをしたのは、確か数年も前のことで、なんとこのバグを取るのに殆ど1日かかってしまいました。それみろ、言わんこっちゃない、定数を左に書いておけば1日得したではないか、って? 残念ながら、それは外れです。なぜなら、私がこの時間違えたのは、比較の左右ともに変数だったからです。左右ともに変数だと、どちらにどちらを書いてもコンパイルは正常に終了してしまうのです。
たとえると、前者は、読みやすい文章に相当し、後者は、きれいな字に相当すると思えばよいでしょうか。内容と、字面との差です。ただ、考えておかなければいけないことは、それぞれは完全に独立した条件ではなく、構造がきれいなプログラムを書くには、それなりの書き方のノウハウが必要だし、きれいな体裁で書くには、ある程度構造自体まとまっていなければ難しいようです。
C言語によるプログラムは、非常に長い一つの関数を作るのではなく、ある程度の短い関数をいくつも作って呼び出すことにし、場合に応じて関数を別のファイルに記述し、分割コンパイルすることがよいとされています。
原則は、関連ある関数、変数を一つのファイルにまとめるという単純なものです。これが実際に行うと難しいのは、プログラムの中にある関数、変数というのは、完全に関係あるものと関係ないものに分かれる場合もありますが、多少関係あるとか、殆ど関係ないが、無関係でもない、といった瞹昧なものもあるからです。
初心者であるうちは、それ程大きなプログラムを作ることもないと思いますので、あまり分割に気を使うこともないでしょう。分けることばかり考えるよりは、他のことに頭を使った方がいいと思います。
C言語の特徴は、まとまった処理を関数というブラックボックスの中に閉じこめるという手法により、処理を理解しやすくするという点にあります。何千行にわたるプログラムを理解するのは、さすがに大変なのですが、数十行ならそれほど難しいことでもありません。なぜかというと、あまりに行数が多いと、最後の方の処理を考えている時には、最初の方でどんな処理をしていたのか、すっかり忘れてしまうからです。
また、行数が多過ぎると、それにつれて使う変数の数も増え、間違って一時変数を二重に使ってしまうという、あり得ないようなバグの入ることもあります。これも、どこで何をしているのか、全体的に把握するのが困難になるための副作用だと考えてよいでしょう。
従って、当り前のようですが、原則として、行数を少なくすることが、わかりやすさを増す秘訣です。ただし、ここで言っている行数というのは、処理の数を指しているのであり、単に1行にいくつも処理を書いたのでは、殆ど意味がありません。
中には、関数の長さは1画面におさまるように、従って24行以内に書きなさいという人もいます。何が「従って」なのかわかりませんが。ワークステーションなどでは40行程度を一画面に表示できるものがありますが、その場合は40行まで書いていいのか、などと悩む必要はありません。
すでに、思考の順序に従って書くという奥義を紹介しました。これに従っていれば、おおむね前後の処理の結び付きが最も強くなり、離れた行ほど疎な影響になることが多くなります。従って、密な処理ほど近い所にあるため、一つの関数が画面スクロールさせなければ読めない場合でも、さほど混乱しないはずです。
処理の内容によって、しなければならないことは違います。何でもかんでも例えば24行という一定の行数で書く努力をするよりは、自然な流れになるように関数を作る方がずっと得です。
また、あまり関数を短くすると、必然的に関数の数が増えることになります。ある関数の処理を理解するには、その関数が呼び出している関数の処理を理解しておかねばなりません。呼び出している関数が何だったか確認しているうちに、呼び出している元の関数で何をやっていたのか忘れてしまうようでは、元も子もないのです。
この処理の内容を大雑把に把握するのは簡単です。なお、コメントのうち、最後の「ファイルを閉じる」というのは明らかに無駄であり、close_fileという名の関数がファイルを閉じることは、99%の人なら瞬時に想像できます。(たとえファイルを閉じるということが、どのような処理か理解していなくとも)。
極論を先に紹介しますと、コメントはいらないと豪語する人もいるし、コメントはいくらあっても差し支えないと断言する人もいるようです。これらが両極端な意見なのですが、あってもなくてもいい、というのもいいかげんすぎて納得できないでしょう。プログラムが動けばいいというものではないと解釈する人には、コメントは非常に重要な意味を持ちます。
まず、コメントはいらないと思っている人へ。コメントがあってもなくてもプログラムの実行結果は同じだ、だからいらない。絶対いらない。そこまで言うなら別に考えを改めなさいとはいいませんから好きにしてください。コメントがあってもなくてもコンパイルした結果は確かに同じです。
コメントはあった方がプログラムが分かりやすくなる、だからコメントはいくらあってもいい、と思っている人へ。あなたは考えを改める必要があります。私の経験では、訳の分からないコメント以上にプログラムを難解にするものはありません。プログラムの理解を助けるためには、そのコメントが適切なものである、という条件が極めて重要なのです。そして、適切なコメントは、自ずから適切な分量というものがあって、いくらでも書けるような性質のものではないのです。もっとも、これは揚げ足取りのようなものです。「コメントはいくら書いてもいい」という主張は、明らかに「適切なものであれば」という前提を想定しているからです。にもかかわらず、わざわざ揚げ足を取らせていただいたのは、世の中に不適切なコメントというものが意外と多く、コメントはただ多ければいいと思っているのではないかと邪推することも多かったからです。
なぜ不適切なコメントがいけないかというと、誤った先入観を与えるからです。この先入観というのがくせもので、最もわかりやすい例は、間違ったコメントです。
間違ったコメントに関して一番困ることは、コメントが間違っているのか、それともコメントが正しくて処理の内容が間違っているのか、分からなくなることです。実は両方おかしいことも、よくあるのですが。
余計なコメントというのは、間違ったコメントに比べると罪は軽いといえます。しかし、余計なコメントもやはりプログラムをわかりにくくします。なぜなら、プログラマーがプログラムを読んでいる時には、読んでいる内容に集中しようとしますが、余計なコメントが現われると、それを読む労力が割かれて、集中力が分散するからです。
ただし、多くの「C言語の入門」をうたった記事に、「余計なコメントは書かないこと」と書いてあって、次のような例まで載っていることがありますが。
よほど変なプログラムでなければ、fopenがファイルをオープンする関数であることは間違いないので、そんなことは書かなくてもいいし、"rb" とあれば、バイナリモードであるに決まっている。だから、そんなのは書いても意味がない。それは正論です。しかし、初心者向けの本には、上のようなコメントがよく書かれています。なぜかというと、初心者向けの本の場合には、fopenがファイルをオープンする関数であることとか、"rb" というのがバイナリモードを意味することを例示するという目的で、そうであることを知らない人を想定して、例となるプログラムを書くのですから、このようなコメントがあった方が適切かもしれないのです。
ところが、これを読む人は何も分からないで読むわけですから、このようなコメントは書いておいた方がいいのだと錯覚してしまうかもしれません。あくまでこれは特殊な例であって、Cでプログラムの書ける人なら、まずこのようなコメントの内容は頭に入っていると考えて間違いありません。となると、皮肉なことに、これは「不必要なコメント」の典型的な例になってしまうのです。
というコメントを付けるという豪傑は、流石に私は今まで一度も見た経験がない。これ程ナンセンスなコメントがあると、かえって何かあるのではないかと疑ってしまうかもしれませんが、とにかく人並みの感性を持っていれば、このコメントが無駄以外の何物でもないことは、説明しなくても分かっています。
では、多くの秘伝書に「無駄なコメントは書くな」と記されているのはなぜでしょう。これは裏の意味を考えるとわかります。つまり、重要なのは「必要なコメントを書きなさい」ということなのです。無駄なコメントがあることは、必要なコメントがないことよりは、ずっと罪が軽いといえます。しかし、必要なコメントを付けるというのが、これが結構センスが必要な作業であって、なかなか無駄なものを書いてしまうことが多いわけです。「そんなことはいいから、もっと必要なことを書いてくれ」と言いたくなります。
余計なコメントがあっても、例え誰かに見られて笑われたとしても、それは笑われただけで済むことです。余計なコメントによって、必要なコメントが目立たなくなることは問題ですが、余計なコメントは、いつでも削除することができます。しかし、逆に必要なコメントを後で思い出すことは、とても難しいのです。
特にC言語を始めたばかりの人は、余計かどうか判断付きかねるものは、どんどんコメントにして書きましょう。いらないと言われたら、消せば済みます。そのうちに、何が必要なコメントで、何が不要なコメントか分かってくるようになりますから、自然にいらないコメントは書かなくなるでしょう。
しかし、必要なコメントだと分かっていたら、言われるまでもなく、コメントに書くのではないでしょうか。にもかかわらず、コメントに書かないというのはなぜでしょう。
場合によっては、コメントを書くのに本当に面倒な環境もあります。例えば、コンパイルしようとしたら、メモリが足りませんと表示されて、コンパイルできなかった。仕方ないのでコンパイルするために、仮名漢字変換のプログラムを追い出してメモリを空けた。コンパイルはできるようになったが、今度はプログラムの中に日本語でコメントが書けなくなってしまった、という経験があります。もちろん、真面目に環境を整備したら、もう少しマシになるのでしょうが。そして、このような場合でも、破綻した英語でもローマ字でもいいから、本当に必要なコメントなら書いておくべきです。後で、ローマ字で書いてあるコメントを普通の日本語の文章に置き換えるのと、何も書いてないプログラムに、何をコメントしたかったのか後で思い出しながら書くのと、どっちが楽かいうまでもないことです。思い出す手間をかけてコメントを書くのは、書かない方がマシと感じるほど面倒なものです。
実はこれが問題なのです。言い換えれば、そこにコメントしておく必要であるという判断ができないのです。または必要と思わなかった、従ってコメントにしなかった、ということです。その時は頭に入っているが、後でわからなくなるかもしれないことがあれば、コメントに書くのが望ましいことです。しかし、これは将来忘れるかもしれないということは、それを覚えている間は、なかなか気付かないことがあります。
もしくは、後で見てすぐに分からなくても、多少読めばわかるだろうと安易に考えてしまうこともあります。コメントを書く手間よりも、多少読む手間の方が少ないと判断するのです。これは正解であることもありますが、大失敗となることもあります。
他にも理由はありそうですが、この2つが非常にありがちだと思います。コメントを書くのが面倒というのは、認識を新たにしてもらうとしか言い様がありません。これに対し、必要なコメントであるかどうかわからない、というのは初心者の場合どうしようもないので、先程書いたように、どんどんコメントにしてしまうというのも一つの方法ですが、ある程度はパターンというものもありますので、それを目安にしてコメントする習慣を身に付けるという手もあります。
関数の前に書くような、割合大きなコメントは、各種の流儀があるようです。コメントのスタイルも、千差万別といえます。私の場合は、次のようなスタイルですが、これは結構よく見かけるものです。
Cのプログラムを書くとき、まずとまどうのは、どのような書式で書いてよいかわからないということでしょう。C言語においては、特別な場合を除いて、文法という観点からは、あまりこだわらずに自由な書き方ができます。例えば一行にいくつも文を書いても構わないし、一つの文を2行に分けて書いても構いません。
しかし、実際にCのプログラムを見ると、殆どのものがインデントを行っていることに気付きます。インデントというのは、プログラムの内容を書くときに、左に空白を置いて見やすくする、アレのことです。昔なつかしBASICのプログラムなどは、一番左には行番号があり、それに続けてすべての行がおおむね同じ位置から始まっていたものでした。別に空白を置いてはいけないというわけではありませんが、当時は、メモリが足りなくなるだとか、こうした方が実行速度が早いだとか、結構空しい理由で、実に見にくいマルチステートメント形式の記述が行なわれたりしたものです。同じ様な非本質的な理由で、わざわざ一文字の変数名を使ったりもしました。最近はBASICといっても、コンパイラになっていたり、構造化できたりするわけで、メモリはどっさりあることだし、当時の名残りもないかもしれません。実は最近のBASICは使った事がないので、詳しくは知らないのです。
ということで、インデントのスタイルについては、とりあえず見よう見まねで始める人が多いようです。私もそうでした。まず、それで一向に構わないことを頭に入れておいてください。基本的に、インデントのスタイルによって実行結果が異なるということは、C言語ではないと考えて構いません。つまり、自分の好みによって、いいと思うように勝手にやっていいということです。
ところが、パソコン通信でたまに見掛けるのですが、あまりCに馴れていないと思われる人が、「動かないのですが (;_;) 」などと泣き付いてきて、最後の手段、恥をしのんでソースリストをそのまま掲示してしまう、という奥の手があります。世間には信じられないかもしれませんが結構親切な人もいて、また、世話をやきたくてしょうがない人が見ているものなので、しかもその人達が相当プログラムの知識があったりして、添削をしてくれることもあります。パソコン通信には、そういった使い方があることを覚えておいても損はしません。
それはいいのだが、この時に「ひどいインデントですね、これでは動かないのも当り前だ」と言われてしまうことがあるのです。
単純に考えると、インデントがどうなっていようが動くプログラムは動くはずなのですが、それは理屈だけの話です。経験的には、インデントをちゃんと書ける人と、Cが使いこなせる人との間には相関関係があるようです。というよりは、きちんとした構造を持ったプログラムを構成する能力のある人なら、自ずからインデントもきちんとできる、というのが本当の所でしょう。
実際、あまりひどいインデントのプログラムは、階層化された構造を見誤る原因になりますから、すなわちバグの原因にもなるのです。人間がプログラムを読む時には、空間的な位置関係から意味を解釈しようとします。これは視覚的なパターン認識能力のおかげで、これを活用したのがインデントだといえる訳です。しかし、コンパイラはそのような認識能力は持っていません。単に文字の出現した順序だけを見て、解釈を行います。その結果、期待した動作と現実が食い違うことになります。よくある誤りの一つは、リストのようなものです。
おそらく、この処理を書いた人は、0から9までの数字を表示したかったのですが、余計な所にセミコロンがあるために、コンパイラは次のように解釈するでしょう。
この場合、for によって繰り返し処理されるのは、;という空文であって、printfではありません。従って、結果は10という値を一度だけ表示しておしまい、という多分予期したものとは異なる結果になってしまいます。
と説明して、成程、そうであったか、と理解したのなら、多分あなたが人間である証拠です。もしあなたがコンパイラだったら、最初のリストも次のリストも、何にも違わないじゃないか、と首をかしげるはずですから。
空白の使い方ひとつで、プログラムの分かりやすさに極端な差が出るのですが、インデントについて、あまり重視する人がいないのは不思議なことです。うまくインデントを付けるということは、実は極めて重要な技術であることを認識してください。
インデントというのは、処理が深みにはまった時に、段を付けることによって、処理のまとまりを明確にするのが目的です。
このリストでは、printfを書く位置が、forよりも右から始まっています。こう書くことによって、printfがforのループの中にある処理であることを明確に表現しようとしているのです。このように、何かの処理の中にある処理であることを表現する場合に、外の処理よりも右から始めるというのは、まず異論のないことだと考えてください。
では、何が問題になるかというと、括弧を付ける場合にどう付けるのか、ということなのです。複雑怪奇な付け方まで含めると、えらい種類になってしまいますので、ある程度よく見掛けそうなものを紹介します。
この3種類に対して、派生した記法があります。すなわち、始まりの括弧を、外の処理と同じ行の最後に持ってくるのです。
(1)の書き方は、内の処理が括弧よりも右に現われるという特徴を持っているため、内の処理の終わりを見分けるのが最も簡単であると思われます。これに比べると、(3)の書き方の場合、次の処理の先頭を捜して、その直前の、内の処理の終わりを見ることになりますが、(3)の場合は、内の処理と括弧の位置が揃っているので、一見見やすそうな感じがするかもしれません。ただし、これに関しては、疑問点があります。
上のように書かれている場合、最初のまとまりを認識するのは、括弧を見てではなく、むしろ次の処理Bをみて判断しているのではないか、という点です。次の例は実際には括弧がないため不可ですが、
もしこれで動作するなら、こちらの方がすっきりするのではないか。括弧は単に文法上の必要から付けているだけであり、プログラマーが目で見て確認するためには、あまり役に立っていないのではないか、という疑問です。
これに対して、(1)の書き方だと、外の処理の次の括弧からまっすぐ下ろして、最初にぶつかった閉じ括弧までの間が内の処理であることが明確に判断できます。なぜ明確かというと、その間の処理は、括弧の位置よりも右から記述が始まっているため、途中で見落としたりする危険が避けられるからです。特に、(1)'のかきかだと、外の処理の始まりからまっすぐ下ろす間に文字がないため、極めて簡単に見つけることができます。
おなじように閉じ括弧で(3)の場合の内の処理の終わりを捜そうとすると、内の処理の記述と同じ位置に括弧があるので、他の記述に埋もれてしまって、捜すのが大変だし、見落としやすくなるのです。
とはいっても、ほとんどの場合、内の処理が終わった時点で、次の外の処理がインデント幅だけ左から記述されていますから、捜すのが大変、と大袈裟に言う程には、見誤ることは少ないのですが、あまりないケースとして、独立したブロックがある時、非常に混乱することがあります。まず、(1)の書き方から。
この他に、開き括弧と閉じ括弧の位置をずらす書き方もあります。ただ、私には、これらが何を意図しているのかよくわかりません。誰か教えてください。
まず、空白にするかタブにするかという問題があります。これに関しては、4文字の間隔のタブに設定して、タブを使うことをおすすめします。
ただし、ソースプログラムを外部に発表する場合には注意してください。この場合は検討の余地があります。他の人もタブが4文字間隔であるとは限らないからです。最悪の場合、タブを認識しない環境もあるかもしれません。
殆どC言語とは無関係の話ですが、ニフティサーブの端末設定には、コントロール文字を扱う/扱わないという選択があります。これを「扱わない」にしておくと、タブも無視されてしまいます。即ち、タブでインデントされたソースリストが電子会議室に掲示されると、左にべったりくっついて表示されてしまうのです。それだけならよいのですが、変数名などタブで区切ってあるものが、全部くっつくので、全く訳がわからなくなってしまいます。そこで、かなり昔の話ですが、タブをコントロール文字として無視するのならCRもLFも無視すべきだと提案したことがありますが、流石にこの提案の方が無視されました(もちろん、タブもCRやLFと同様に扱って欲しいという意味です、CRやLFが無視されたらやってられません)。
※コントロール文字を「扱う」にすると、希とはいえ、変なエスケープ文字列が入った発言に出くわしてひどい目に会うことが予想される。
というのは極端なケースですが、タブの間隔が個人によって異なる設定になっていると何が不都合か、もう少し具体的に考えてみましょう。一番ありがちなのは次のようなケースです。経験的に、タブの間隔の設定としては、4文字とする人と、8文字とする人が大半であることがわかっています。
リストの中の空白が、どのような文字で書かれているか、紙に印刷されたものを読んでもわかる訳がない。空白は単に空白に見えるだけです。これはパソコンのディスプレイ上でも、しばしば似たような状況となります。エディタによっては、「ここにタブがあるぞ」ということを見分けるための、特別な表示を行う機能がある場合もあります。しかし、全く空白と区別の付かないこともあります。このリストが、タブが4文字間隔になるという仮定で書かれたソースだとしましょう。タブが8文字間隔になるような表示でこれを見ると、次のようになるでしょう。
これは、単にインデント幅が4から8になっただけだが、これならあまり気にならないかもしれません。しかし、常にこううまくいくとは限りません。よく見かけるのが、変数の定義の箇所で、変数名を揃えたくなる人です。これは多いようです。場合によってはコメントも揃えたくなるようです。
それでは、タブが文字何個に相当するかにかかわらず、あまり見苦しくなく表示されるように書くにはどうすればよいでしょうか。簡単です。タブを使わなければいいのです。リストの空白を、タブではなく空白で表現すれば解決します。
ところが、この場合も、いったい空白をいくつ程度置けばよいのかが問題になります。たとえば、次のような1行を追加したくなったら、どうしましょうか。
というのは、流石にみっともないので、また左につめるのでしょうか。こういう作業はやってられない、というのが正直な所だと思いますが、ぶつぶついいながら、ちゃんと揃える人も多いかもしれません。あるいは、この程度なら後で揃えるためのソフトがあるかもしれないし、そういう機能を備えたり、マクロで処理できるようにしたエディタがあるかもしれません。
しかし、私はこういう手間に神経質になるのは不本意ではないかと考え、長年の研究の結果、ついに次のように書くことを結論するに至りました。空白は1つで十分。べつに見にくくもなんともない(と思い込むのが秘訣)。
と書いたが、改めてこうして見てみると、そんなに見やすくないような気もします。ちなみに、別に長年研究しなくても、K&Rの本の書き方を真似していたら、最初からこのように書いてありますから、自然にこのように書くことになります。という余談はともかく、なぜ上の表現があまり見やすい気がしないのか考えてみますと、どうも
という前書きがあまりに長すぎて圧倒されてしまい、肝心の変数名があまり目立たないからのようです。このような場合には、
この程度なら、あまり変に見えません。ただ、このあたりの感覚は、かなり個人差によって意見の分かれる所ですから、異論のある人も多いでしょう。実は私自身、このように書くようになったのがつい最近のことで、かなり長い間、変数の始まりが揃うようにタブを使って書いていました。
またまた話題を元に戻して、タブに対する文字数が異なることによって、インデントがもっとひどくなる例を考えてみましょう。ふたたび、list 23の例を使います。
ただし、今度は、これがタブを8文字とみなして書かれているものとします。実は、MSDOS の type コマンドを使った時など、タブが8文字と見なされることは結構多いので、自然とタブを8文字と考えてコーディングする人か多くなりがちなのですが、それでも、Cのプログラムのインデントは、4文字の空白分の間隔としたい、という人が多いようです。これは、8文字を1段としてインデントを行うと、すぐに奥が深くなってしまい、目が左右に振られてかえって見にくくなってしまうからだと思われます。インデントの幅は、ぱっと見てわかる程度に、しかし目をあちこち動かさずにすむように、多過ぎない程度に、というのが理想と言えるでしょう。
このように、if、for、…等と関数との書き方を区別しておくと、区別が楽になり、エディタやツールで検索する時に作業が楽になることがあります。
空白を置いてもよさそうなものですが、あまり空白ばかりだとかえって見にくくなるということでしょうか。少なくとも、括弧が続く時に、次のように書くと、結構間延びしてしまいます。
これはCの書き方というより、英文を書く場合には普通に行われていることです。ただし、英文タイプの場合、セミコロンの後には、2個の空白をタイプするのが普通のようです。
単項演算子の優先順位はかなり高いので、強いつながりを持っているという意味を含ませて、つなげて書くのだと思います。
・2項演算子の両側には、原則として空白を1つずつ置く。ただし、特に理由のある場合にはその限りではない。
2項演算子は、単項演算子よりも優先順位が低いので、特に単項演算子と混じった場合には、このように書くと読みやすくなるからだと思います。
K&Rのリスト中には2項演算子の両側に空白を置かない例は、散在している。おそらく、演算の結果に重点を置いているような意味を持たせていると思われる場合に、このような例が多い。
for の中の式を区切るセミコロンの後には、空白を開けますが、無限ループの場合に限り、空白なしで詰めて書いて構いません。これは慣用句のようなものです。
次のように、for 文の本体が複文でない場合、および空文の時は、それを同じ行に書かずに、必ず次の行に書きます。特に、空文を意味するセミコロンを同じ行に書いてはいけません。混乱の元になります。
実際は、左に空白を置きません。最も左から書き始めます。また、関数の型は、関数名と同じ行に書きます。こうしておくと、grep のようなツールで関数名で行単位の検索を実行した時に、型が付いたまま表示されて便利です。
最近は、パソコン通信に参加したり、雑誌の付録のディスクを手に入れることによって、Cで書かれた多くのフリーソフトウェアのソースが簡単に入手できるようになりました。これらの多くは、上の規則とは全く異なった、独自の表現によって書かれています。このようなソースを単に読むのは退屈な作業かもしれませんが、インデントなどを自分のスタイルに直しながら読むと、理解するのが容易になります。このような手作業を行うには、ソースプログラムをくまなく読まなければならないからです。
最後に、名前の付け方について考えてみます。名前というのは、具体的には変数名、関数名などです。これらの名前は、予約語を使うことができないとか、コンパイラによって一定の長さ以内にしなければならない、といった絶対的な制限もありますが、これは流石に守らないわけにはいかないので、悩むこともないと思います。長さといっても、最近の処理系だと、実用的に十分な長さですから、昔、先頭の2文字しか判別に使われない言語があって、a01とa02が同じ変数とされてしまうので難儀したといったような苦労は、もはやあまり経験することもないと思います。昔話をもう一つしておくと、昔は、変数名が短い方がメモリやディスクの使用量が少なくて済むので、といった苦労もありました。C言語は基本的にコンパイラの環境が提供されているため、変数名とメモリは直接関係ないように思えるかもしれませんが、メモリが64KBもあれば大容量といっていた時代には、変数が長すぎるとコンパイルの途中でメモリが足りなくなってしまったり、ソースファイルが長くなるためにディスクの空き容量が不足してコンパイルに失敗するという、今では想像もできない世界があったのです。※
※ところが今でもあるらしい。メモリがあればあるだけごちゃごちゃとソフトを常駐させ、その上で巨大なコンパイラを走らせるからである。昔、某雑誌のパロディ版に載っていた超高機能エディタ(機能が多過ぎるためにメモリを食いつくし、1頁の文章しか編集できない)の記事を思い出す。
もはやメモリを気にしながらコンパイルする時代は終わったと考えておきましょう。もちろん、コンパイルの時の話です。実行形式のプログラムが消費するメモリ量は、ますます少なくなることを要求されています。というのは、今後はパソコンの上でマルチタスクの環境を実現する方向へ世界が向かっているからです。個々のプログラムが小さくても、プログラムを10個同時に走らせようとすると、10倍のメモリが必要です。640KBのメモリが必要なソフトを10個同時に実行するには、単純に考えても約6MBのメモリが必要です。もちろん、実際は、あの手この手のメモリ管理を行いますから、メモリが足りなくてもディスクに一時退避するなどして、何とか少ないメモリをやりくりするのですが、それぞれのプログラムがメモリの使い方に無頓着かどうかで、かなり全体の使い勝手に影響することは間違いないでしょう。
念のため書いておきますが、C言語には予約されている語がいくつかあります。これらは用途が決まっていますので、プログラマーが勝手に使うことはできません。もちろん、それを無視するとコンパイルする時点で多分エラーになるので、予約語は変数名に使えないということさえ頭に入れておけば、うっかりしても大変な混乱に至ることは希だと思います。
ここからがポイントになってきますので、注意してください。まず、C言語に非常に近い言語に、C++という言語があります。C++には、C言語では予約語とされていないいくつかの語が、新たに予約語として追加されています。これらの予約語は、Cのプログラムであっても使わないことをおすすめします。同様に、他の言語の予約語は、できれば使わないことをおすすめします。
この構造体の欠点は、classという名前を使っていることです。将来C++に移植しようとした人が、びっくりするかもしれません。悲惨なことにならないことを祈ります。C言語から他の言語へのプログラムを移植する機会は、神経質になる程のものではないかもしれませんが、一応、C++への移植というのは、最もありそうなことですから、C++の予約語だけは使うのを避けた方がよいでしょう。
ここまでが、使ってはいけない、という指針です。一般に「〜してはいけない」というのは簡単ですが、「〜するのがよい」というのは説明困難になりがちです。以後、あえて、どのような名前を付けるべきかという指針について述べようと思います。
一言で書けば、「わかりやすい名前を付ける」とよろしい。これが大原則です。これだけを理解していれば、あとは感性に正直に名前を付けても、相当変な人でないかぎり、何も問題になりません。ただ、驚いたことに、わかりやすい名前にしようとさえ、夢にも思わない人が結構いるように思えるのですが。名前がわかりにくいケースはもう一つあります。
次のリストを見てください。少しCでプログラムを書いたことのある人にこれを見せると、「間違っているぞ」と指摘されるかもしれません。
しかし、このプログラムは文法的には何も間違ってはいないので、コンパイルすればちゃんと予期した通りに動作します。間違っているのは、プログラムではなく、main の引数に argv、argc という順序で名前を付けるという感性です。この種の名前は、伝統的に命名されていて、プログラマーが勝手に変えることは望ましくありません。そういう意味ではこのプログラムは確かに間違っているわけです。
伝統的に使われる名前は、できるだけ先達に従うのが得策です。argc、argv はそれぞれ関数 main に渡される引数で、コマンドラインのパラメータの数と、各パラメータの文字列へのポインタを順に格納した配列を意味するのが伝統ですから、上のように書いたら目茶苦茶というわけです。
これらは、使い捨ての変数として使われます。for でループさせる場合のカウンタによく使われます。これらに限らず、1文字の変数は、主に使い捨ての一時変数として使われるものと思えばたいてい当っています。
作業用の文字列を格納するためのバッファとして使われます。buffer の後半分を略したものでしょう。
ファイルポインタという表現は、特にUNIXの文脈で意味するものと、C言語の文脈が意味するもので、混乱を招くことがある。
文字通りサイズです。何のサイズかというと、主に malloc のようにメモリを獲得する関数への引数として使われますが、それ以外の用途にもよく使われるようです。
ステータス、すなわち状態ですが、何の状態かというと、しばしば関数の戻す値、もしくは exit の引き数として使われます。
この他に、Cの関数マニュアルを見ると、引数の説明として使われている名前がありますので、参考にするとよいと思います。
現状では、日本語の名前が使えるCコンパイラは、あまり見掛けないし、ANSI の規格通りなら、当然日本語の変数名など考慮されている訳がないから、いわゆるメジャーなコンパイラについては、英数のみ使えると考えておきます。
まず、英単語を名前に使うとして、省略するか、省略しないかという選択があります。例を見るのが手っ取り早いでしょう。
省略しないことのメリットは、意味を誤解する確率が小さくなることです。fnと書くと関数名のことかと誤解する人がいるかもしれませんが、file_nameを見て関数名かと思う人はまずいませんし、これを見た人は必ずファイル名であることを理解できます。
では、省略するメリットは何でしょうか。一つは、あまりにもしばしば使われる変数に長い名前を付けてしまうと、入力するのが大変だ、ということがあります。ある程度長い名前になると、開発環境によってはcut&pasteのような方法で、文字列コピーすることができますから、その方が間違いが少なくなります。長い名前はタイプする時に間違いがちなので嫌だという人がいますが、これはある意味で危険です。タイプする時に間違う確率は、何文字あたり一回、というものであって、短い変数でも間違える時には間違うものです。間違えた時にどの程度の影響があるかということも検討しておくべきです。短い変数をいくつも使っていると、タイプし間違えた時に、偶然別の変数になってしまうことがあります。この原因によるバグは、一度コンパイルに通ってしまうと、なかなか発見できません。長い名前の場合、間違えてタイプしたら、そんな変数はないとコンパイル時にはじかれる確率が高くなり、その意味では安全かもしれません。
しかし、長い名前にもデメリットがあります。あまり長い名前だと、肝心の処理の流れを理解するための思考を妨げる危険もあります。名前を追いかけて最後まで読んで、ああこれはあの変数だな、と思った時には、今whileのループ条件を調べていたのか、ifの判断の途中だったのか忘れてしまうかもしれません。という例は流石に大袈裟すぎますが、名前が長すぎると、かえって全体が見にくくなる可能性があるのは確かです。
そこで、妥協案として、あまり長い場合には省略する、という方法が考えられます。これも悪くはありません。
この方法の場合、長すぎもなく、全然わからない程省略するのでもない、という加減に成功すれば、かなり効果があると思います。ただ、一つ気になるのは、経験的に、どの程度省略したのか、しばしば忘れてしまうということです。例えば、一時ファイルの名称を保存したい変数の名前を、tempfile としたのか、tmpfile としたのか、プログラムを書いている途中ですら忘れてしまうことがよくあります。
フィンローダ流は、慣習として省略した書き方が固定したものでなければ、できる限り省略しない、というものです。
ただし、以上の議論は、継続的に意味を持ち得る変数の場合のことであり、使い捨ての変数はこの限りではありません。その中にも、ある程度は慣習的に決まった名前がありますので、それらが使える範囲においては、ありがちな名前を使っておくのが無難な選択だと言えましょう。
流儀としては、大きく分けて2つに分かれます。ここでは、英単語を組み合わせることによって名前を付けることにします。
私の経験では、1を好む人が多いような気がします。理由は、2の方が、名前が長くなってしまうからではないかと思います。長い文字をタイプする方が面倒といえばそうかもしれません。
まず、すべて小文字で書かれていることです。1の場合、どこを大文字にしたか間違えることがあるかもしれませんが、2ではそれはありません。
私が2の書き方を気に入っている理由は、単語と単語の間が、アンダースコアという、見た目がかなり空白に近い文字で区切られているため、ぱっと見た時に読みやすいと思われることです。1の書き方は、確かに大文字を認識して単語を分解することが可能ですが、ぱっと見た時に大文字小文字を区別する方が、アンダースコアよりも一瞬手間がかかるように感じます。
ただ、場合によっては2の短所はもう一つあります。アンダースコアが比較的入力しにくいキーに割り当てられているキーボードがあることです。
変数には、固定した意味が与えられ、プログラム、または関数の処理が終わるまでその意味を持ち続けるものと、いわゆる使い捨ての一時的な変数とがあります。一時的変数としては、関数の戻り値をとりあえず入れるとか、ループのカウントに使われるものがあります。
ここに出てくるcという非常に短い名前を持った変数は、伝統的にgetcharのような一文字入力の結果を保存するために使われます。cという文字が、characterを連想させるので、この場合cという名前が使われるのでしょう。ただし、cの型はintであるのが普通なので、注意してください。初心者の中には、これをうっかりcharにしてしまうことが多いようです。この変数は、伝統的なので、短いながらも全く無意味であるわけではありませんが、この種の使い捨て変数は、その場限りで処理が完結するという意味で、変数名に意味を持たせなくても、理解の妨げにはあまりならないのです。
これに対して、複雑な処理を行う関数の名前や、大局的に使われている変数の名前は、できるかぎりその意味を表すような名前を付ける、というのがフィンローダ流です。要するに、長さにはまるで無頓着なのです。
さて、できる限り省略しないとなりますと、場合によっては異様に長い名前になってしまうことがあります。この名前が、頻繁に使われるものであると、かえって名前を読むのに労力を使ってしまうことも考えられます。また、プログラムの見栄えも超高層ビルが乱立したかのごとくなってしまい、あまり面白くないかもしれません。
なお、私にもこの関数が何をするのか全くわかりません。ただし、この関数名の4文字目以降は、全く見たこともないわけではありません。つまり、関数名が全く無意味ではなさそうだという見当だけは付きます。ということは、この関数の意味がわからないのは、名前が長いからではなく、名前から意味が連想できない所にあります。
氏の指摘に対して私が楽観的に考えたのは、そんな長い名前をわざわざ暗記しなくても、プログラムは書けるのではないか、と思ったからです。
つまり、GUIシステムに使われている関数名は、確かにやたら長いのですが、名前に関数の意味が含まれているので、初めて見た関数であっても、およその意味は連想できます。また、仮に何か処理をしたくなったが関数名を覚えていない場合は、手元に置いてあるマニュアルを見ればいいだけのことです。このことは、昔NIFTY-Serveで発言したことがありました。その時に、試しに、X Window ハンドブックを適当にエイっと開いて、ぱっと目に付いた関数を選んでいるのですが、出てきた関数が何とこれです。
これはかなり運が悪い部類に属するのではないかと思うのですが、実は私は残念ながら X Window に関して多少の知識があるため、上の関数の内容が理解できても当然なのかもしれませんが、仮に全くX Window に関する知識がないと仮定してみても、この関数が、「ウインドウのバックグラウンドパターンをセットするのではないか」ということは容易に想像できると思います※。
※これに対して、いや、全く想像できなかった!、というプログラマーがいたらコメントしてくれと書いたが、誰もコメントを書かなかったのは、想像できなかったというより、私の説があまりに陳腐なので無視されてしまったのではないかと思われる。なお、岩谷氏の指摘は、長い関数が覚えられないので困ると言っているのではなく、むしろ各種雑多なGUIシステムに対し、同じような処理をするための関数名が全て異なっており互換性も保たれていないことを問題にしているのであって、早い話が私の意見はいいがかりである。にも関わらずそれを書いたのは、氏の言うところの、「ものすごく長い名前」という表現に対しては、何か書いておかなければいけないような強迫観念を感じたからである。
ちなみに、同発言の私の主張は、「丸暗記の技術は過去の遺物にし、小学校からカンニングの方法をちゃんと授業で教え、迅速な検索能力を取得した人材を育ててほしい、そうすれば、適当なイマジネーションのあるプログラマーなら、ものすごく長い名前の関数をちゃんと覚える必要は全くない」という無茶苦茶なものだった。これではコメントがないのも当り前か。
もし名前が短かったら、覚えるのも早いでしょうか。そのためには、2つの危険を乗り越えなければなりません。一つは、名前を短くしようとすればするほど、省略しなければならない単語が増え、ぱっと見ただけで何をする関数かわからなくなる確率が高くなることです。例えばitofという私が先日書いた関数の処理を、一目で想像できる人は百人に一人もいないでしょう※。省略の仕方によっては、逆に何だかなかなか思い出せなくなるかもしれません。もう一つの危険は、名前を短くしすぎたために、思わぬ所で衝突してしまうことです。
処理系に依存して、特別な意味を持った名前が使われていることがあります。このような名前はあらかじめ確認しておき、うっかり他の意味に使わないようにします。
名前は英語である必要はありませんが、英語で書いて理解できれば最も効率的だと思います。ただし、英語の綴りを間違えるのは、プログラムの動作に差し支えないとはいえ、かなり恥ずかしいものですから、あまり自信がなければ、まだローマ字の方がましだと思います。

 

[ 202] 英語上達の秘訣と留学成功マニュアル
[引用サイト]  http://eigoebook.com/

英語を勉強せずに留学する95%の人が、英語を話せないまま帰国します。実は、留学する前に必ずしなくてはならない秘密があるのですが・・・
今までに96名を留学成功に導いた留学成功アドバイザーの私が、これから留学したいと思っているあなたへ留学成功の2つの秘密を公開します。
ネイティブスピーカーと長年一緒に過ごしたチカラは英語のスキルだけでなく、英語で自然にコミュニケーションをするのに必須である英語の文化的知識も備えています。英語を自由自在に操る彼ですので当然ながら言語を学ぶ秘訣をよく知っていますし、彼のマニュアルがあなたの英語上達の役に立つこと間違いありません。チカラは多くの人達の英語上達の役に立ちたいという願望がありそしてコミュニケーションの才能があるチカラは素晴らしい先生だと思います。
※申し込み後すぐ無料英語勉強法レポートのダウンロードアドレスがあなたのメールアドレスに届きます。英会話上達講座に申し込んだ方は英会話講師チカラが発行する英語勉強法のメルマガに登録されることを同意の上お申し込み下さい。メルマガや無料英会話上達講座はすぐに簡単に解除できます。
はっきり言って留学すれば自然に英語が上達して英会話ができるようになると思っているならその考えは危険です。
もしも信じられないなら留学した人に実際に「留学してどう思ったか」聞いてみて下さい。その人はこのように言うでしょう。
留学すれば英語が話せると思っていたけど、ただ留学するだけでは英語が話せるようにならないことがわかった。多くの日本人は長期で留学しているのに英語が全然話せるようになっていなかった。
これは留学を実際にした人だけが知っている事実です。留学したことがない人には「留学=英語が話せるようになる」という幻想があるのです。
申し遅れました、現在カナダでタイムホームステイというESLホームステイプログラムをカナダ人のパートナーと運営している横田
私も以前はまったく英語が話せませんでした。英語ができる人や帰国子女は英語がぺらぺらでいいなーと思っていたくらいです。私がわずか2〜3ヶ月で驚異的に英語を上達させた英語学習法や、これから留学する人には是非知っておいてもらいたい私が留学先で得た「気づき」を皆さんともシェアしようと思ったことがこのホームページを立ち上げた理由です。
それではどうすれば留学で100%成功できるのか、留学して効率よく英語を上達させることができるのかについて順にご説明していきます。
語学学校の一番下のクラスでどういうことをしているかと言うと、大きなカードを使って単語のクイズをしたり、英語の歌を歌ったりとある意味、日本の幼稚園でするようなことを英語で行うのです。
そして、ホームステイ先に帰っても英語が話せないのでホストファミリーと英会話ができるわけでもありません。よく聞く日本人の多くのパターンは、食事を食べる時以外は、部屋にこもりっきりだそうです。
そんな調子ではどれだけ長く留学してもなかなか英語が話せるようならないことは想像していただけると思います。
ではそれとは反対に留学先に着いた時点である程度、英語の基礎があり、たとえ文法がまだでたらめでも英語でなんとか自分の言いたいことが言える程度だとどうでしょう?
語学学校ではレベルからして、英会話力を伸ばす授業やリスニングやリーディングやライティングそして文法の授業などを受けることになるでしょう。
またホームステイ先では片言でも学校での出来事や日本のことなどを毎日話すようになるでしょう。ホストファミリーも英語である程度、コミュニケーションがはかれる人とはできるだけ話そうとしてくれるのでホームステイ先で英会話の練習がたっぷりとできます。
その環境で数ヶ月でも留学生活を過ごせば、数ヵ月後にはある程度英語でコミュニケーションができるようになっていることが想像できると思います。
そして、これは貴方次第ですが、貴方が留学先で日本人だけで固まらないでインターナショナル(国際的な)グループに入ったり、日本人以外の友達をつくっていつも一緒に過ごすようにすれば、貴方の英語はさらに伸びるでしょう。
留学を最も効率よく利用して英語を上達させるには、留学するまでに、日本である程度の英語力をつけておくことの重要さがわかってもらえたことと思います。
私は留学する前にはどんな英語学習法をしていいかわからなかったのですが、今になるとあの当時はいつまでたっても効果がでないような英語学習法をやっていたなあと思います。(私が留学前に行っていた英語学習法は無料レポートに掲載しました。)
私がどんな英語学習法をして他の日本人にどんどん差をつけていき、留学して2ヶ月目には外国人の友達がたくさんできるまでになったのかを次のページで説明していきます。
【音声付】 22歳まで英語を話せなかったのにバイリンガル英会話講師になれた私の最短英会話上達法と留学成功の秘訣 | 目次と内容 |
【音声付】 22歳まで英語を話せなかったのにバイリンガル英会話講師になれた私の最短英会話上達法と留学成功の秘訣
今人気の英語学習サイト | 英会話教材 | カナダ留学お役立ち講座 | 英語発音上達の秘訣 | 留学成功の秘訣 | ネイティブに通じる英語を話すには? |
【音声付】 22歳まで英語を話せなかったのにバイリンガル英会話講師になれた私の最短英会話上達法と留学成功の秘訣の相互リンクをしてくれているサイト集です。

 

戻る

プロミスのサイトです。

プロミスのサイトです。