今回は50章、つまり100章の半分に達したということで、少し趣向の違うことをやりたいと思います。それは命名法、つまり、変数や関数の名前の付け方について話したいと思います。
とはいっても、「こうでなくてはいけない!」という命名法などは特にありません。分かりやすい名前の付け方、一般的な使い分け、そういったことを話していきたいと思います。
今回の要点はこんな感じです。
では、いってみましょう。
みなさん、変数や関数の名前はどのようにして付けていますか? 自分のルールを決めている人、他人に勧められたルールに従っている人、そして適当につけている人、いろいろいるでしょう。
もちろん、C/C++言語には決まった命名法などはありません。だからといって、あまり好き勝手に名前を付けていると、あとからプログラムを見たり、他人に見てもらったりするときに理解の妨げになります。ある程度一般的に広まっているルールや、自分なりのルールを身につけておくと、きっと役に立つことでしょう。
では、先ずは名前の長さについて話しましょう。
この講座に出てくる変数名、関数名は、ある1つの例外を除いて、意味のよく分かる名前を付けています。もちろんいきなり一目見て「この意味しか考えられない」という程ではありませんが、前後関係、やりたいことを考えれば大体意味の分かるように付けているつもりです。
初心者、または面倒臭がりな人はついつい1,2文字程度の名前で楽をしようとしてしまう事が多いようです。しかし、これは感心できません。よく分からない名前ばかり付けていると、ちょっと開発に間があくと意味がよく分からなくなり、バグの誘発にも繋がります。少々打つのが面倒だろうが、意味のよく分かる名前を付けるようにしましょう。あまり長すぎるのも、誤入力の可能性があって逆に困りますけど。そこら辺は調整して下さい。
VC++6.0以降では省入力システムが導入されているので、VC++6.0以降では幾分か楽になると思います。
さて、「ある1つの例外」と言いましたが、これは for 文によく使っている変数 i の事です。もちろん、いつも for 文に i を使っているわけではありません。これは、「for 用の変数で、その変数がそれ以上の意味を持たない、または持たせる必要がないときには i を使う」というルールを設けているのです。これは一般的にも使われているので( i ではないかもしれませんが)、特に反発することもないでしょう。もちろん、全てに意味ある名前を付けても構いません。
次は、変数の型や種類に関してです。
この講座の変数には、数は n( number の略)、文字列は sz( string (zero-terminated) の略)、ポインタは p( pointer の略)、というような接頭辞を付けています。こうしておくと、その変数がポインタなのか、数なのか、ということが一目で分かるようになります。
どういうルールを設けるかは人によって少しずつ違いがあるみたいです。このルールをあまり好かない人もいるようです。ですが、ルールを持っておくと、理解の助けになります。変数にはなるべく接頭辞を付けて、型や種類がよく分かるようにしましょう。最低でも、数値か、ポインタか、ははっきりしておくと便利です。
次は変数と関数、マクロの差別化に関してです。
変数と関数、そしてマクロでは名前の付け方を少し変えておくといいでしょう。一般的には、変数には接頭辞を付ける、マクロは全て大文字にする、というものがあります。
変数では、接頭辞を付けることがもう目印になります。接頭辞とその他のものを見分けられるように、続きは大文字で始めます。接頭辞を嫌う人には、全て小文字で書く人もいます。
関数については、全て小文字にする、もしくは単語単位での先頭を大文字にする、という2種類があります。昔は前者が主流でしたが、現在は後者が主流です。これは趣味に任せていいでしょう。
次はマクロですが、特別な理由がない限りマクロには全て大文字を使うようにしましょう。前に口を酸っぱくして言いましたが、マクロは変数や関数とは別の次元のものです。そして、マクロが原因の様々なバグも存在します。「これはマクロだ!」という目印があれば、注意して使うことができます。そのためにも、マクロは全て大文字で名前を付けるようにしましょう。
作業環境によって処理を分けるというテクニックの一環としてマクロに小文字を混ぜることもあります。しかしそれは特別な場合であり、普通のマクロでは大文字を使うようにしましょう。
最後は複数の単語を連ねた名前についてです。
名前に意味を持たせようとすると、複数の単語を連ねて1つの変数名を作るようなことがよくあります。例えば、あるデータが有効かどうかを判定する関数の名前を is と valid([形]有効な)の2つの単語を繋げて作る("Is this valid?" という疑問文をもとにしています)、などです。
この時 isvalid という関数名にしてしまうよりは、IsValid や is_valid という名前にした方が意味の区切りがよく分かり、読みやすくなります。この場合は合計文字数が7文字と少ないので isvalid でも大して気にならないかもしれませんが、これが長くなってくると一目では意味が分からなくなってしまいます。子音で終わる単語と母音で始まる単語を繋ぐと、さらに読みにくくなります。
意味の単位の分かるように名前を付けましょう。
さて、命名法についてはこれで終わりです。命名法で一番大切なのは「分かりやすい」ことです。それは「バグの軽減」に繋がります。少しずつでいいので、自分なりのスタイルを身につけるようにしましょう。
ただ、あまり独特なルールになりすぎると、誤解を招くこともあるかもしれません。標準的なルールに自分のルールを追加する形が一番いいのかもしれません。
さて、予告通り、これから第48章の問題の解答を発表します。問題は以下の通りでした。
44は44、81は84、というように、その数以上の4の倍数のうち最も小さい数を求める式を作って下さい。
では、変換する方法を、式ではなく、先ずは言葉で表現してみましょう。
先ずは順に変換前の値と変換後の値を列挙してみましょう。
変換前 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
変換後 | 0 | 4 | 4 | 4 | 4 | 8 | 8 | 8 | 8 | 12 |
すると、0は0、1〜4は4、5〜8は8、という風に、4つずつ値が並ぶことが分かります。まぁ、当然なんですけど。
計算でとびとびの値を出すには、「ある数で割った余りを引く」というのが一般的に使われます。しかし、4で割った余りを引いても、0〜3は0、4〜7は4、8〜11は8、という風にずれてしまいます。
だからといって「余りを引く」という方法が使えないわけではありません。よく上の文を見れば解答が見えてくるはずです。では、上の文の一部を抜粋してみます。
1〜4は4、5〜8は8
4〜7は4、8〜11は8
これはもう答を言っているようなものですね。元の数に3を足して、それからその数を4で割った余りを引けばいいのです。
これを式に直すと、元の数を x とすると
(x + 3) - (x + 3) % 4
ということになります。
しかし、「余りを引く」ということは整数型の変数を使えば以下のように行うこともできます。
(x + 3) / 4 * 4
余りを引くということは、商に除数をかけることと同じ事です。それは割り算の商と余りと除数の関係式
P = Q × x + R ( P ÷ x = Q ... R のとき)
から見てもよく分かることでしょう。
このようにすれば問題の答となる数が得られます。
さて、ここまでは一般的な話です。普通はこれで正しい答なのですが、この問題はこれで終わりではありません。というのも、ここでは4の倍数を求めるからです。
4というのは2進数で表現すると100です。4とは2進数ではとてもキリのいい数字で、このことが特殊な解答をもたらしてくれます。
1つには、4で割る、4をかけるをビットシフトで行うことが考えられます。
(x + 3) >> 2 << 2
しかし、これよりも効率のいい方法があるのです。
もし、この問題が「100の倍数」を求める問題としたらどうでしょうか? その時は「100で割った余りを引く」などと言わずに、「1,2桁目を切り捨てる」と言ったはずです。C/C++言語では10進数にとって切り捨てる演算はできませんが、これが2進数にとってなら実現できるのです。
そうですね。特定のビットを0に置き換えることのできるビット演算であるANDを使えばいいのです。2進数で下2桁を0、他を1にした数値とANDをとれば、下二桁を切り捨てることができます。つまり、次のようになります。
(x + 3) & 0xFFFFFFFC
int の大きさは32ビットです。つまり、「2進数で下2桁を0、他を1にした数値」というのは 0xFFFFFFFC になります。
しかし、この 0xFFFFFFFC というのは気持ち悪いですね。64,128ビット機などには対応してくれません。(64,128ビット機では int の大きさは普通は64,128ビットになるはずです。)
そういうときにはNANDを使います。「2進数で下2桁を0、他を1にした数値」というのは、「2進数で下2桁を1、他を0にした数値」つまり3のNOTをとったものです。つまり、
(x + 3) & ~3
が答になります。ずいぶんすっきりしましたね。
実はこのルーチンはビットマップを扱うときなどに必要になる、実用ルーチンです。そして同時に、アクロバティックな計算のいい練習材料にもなります。
さぁ、あなたは正解できたでしょうか?
では、最後にもう一度要点をまとめておきます。
次回からはいよいよファイルを扱ってみたいと思います。ファイルを扱えるようになるだけで、格段にできることの幅が広がることでしょう。
それでは次回まで。
Last update was done on 2000.7.4
この講座の著作権はロベールが保有しています