web-dev-qa-db-ja.com

「列化された」コードを長くするために、短い変数名を犠牲にしますか?

私はCSクラスのアマチュアプログラマーで、適切なプログラミングスキルを習得しようとしています。これは私のコードがどのように見えるかで、その端は103列に拡張されています。

int extractMessage(char keyWord[25], char cipherText[17424],
                   int rowSize, char message[388]) 
{
    int keyColumn    = 0;
    int cipherColumn = 0;
    int offset       = 1;
    int nextWord     = 1;

    int lengthOfWord   = 0;
    int lengthOfCipher = 0;

    lengthOfWord = length(keyWord);
    lengthOfCipher = length(cipherText);


    while (keyWord[keyColumn] != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyWord[keyColumn + offset] != cipherText[cipherColumn + (rowSize*nextWord) + nextWord]) {
            cipherColumn++;
            continue;
        }
    }

私はそれらの超長い変数名を取得する前に、i、j、kのようなものを持っていましたが、私の教授insistsは、「専門家の世界」でそのような変数を使用するのではなく、 lenWordは不十分です人々はそれが「レナードの世界文学」の略であると考えるかもしれません。彼は意味のある変数名を選択するように言っていますが、そうすることで、コーディングの黄金律を破って80列未満に保つように感じました。どうすればこれを回避できますか?

17
RaulT

通常、あなたのようにここに投稿されたコードを見ると、横スクロールが嫌いなので編集します。しかし、それはあなたの質問の一部なので、ここで編集を示します。

int extractMessage(char keyWord[25], char cipherText[17424],
                   int rowSize, char message[388]) 
{
    int keyColumn    = 0;
    int cipherColumn = 0;
    int offset       = 1;
    int nextWord     = 1;

    int lengthOfWord   = 0;
    int lengthOfCipher = 0;

    lengthOfWord = length(keyWord);
    lengthOfCipher = length(cipherText);


    while (keyWord[keyColumn] != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyWord[keyColumn + offset] 
        != cipherText[cipherColumn + (rowSize*nextWord) + nextWord]) {
            cipherColumn++;
            continue;
        }
    }
}

そのブレークは意外かもしれませんが、横スクロールのバージョンより読みやすく、名前をij、およびkに短縮するよりも優れています。

ij、およびkを使用してはならないということではありません。 3つのネストされたforループにインデックスを付ける場合、これらは適切な名前です。しかし、ここで名前は、あなたが何が起こっていると予想していたかについての私の唯一の手がかりです。特に、このコードは実際には何もしません。

変数名の長さについて従うのに最適なルールはスコープです。変数の寿命が長いほど、その名前と競合する他の変数が多くなります。名前 CandiedOrange はスタック交換で一意です。チャットに参加している場合は、「キャンディ」と呼んでください。しかし、今のところは、その名前が CandideCandy Chi 、または Candyfloss と混同される可能性があるスコープにいます。したがって、スコープが長いほど、名前は長くなるはずです。スコープが短いほど、名前を短くできます。

行の長さは名前の長さを決して指示しないでください。もしそうなら、コードをレイアウトする別の方法を見つけてください。そのために役立つツールがたくさんあります。

私が最初に探すことの1つは、不要なノイズを取り除くことです。残念ながら、この例は何も実行しないので、すべて不要なノイズです。私は何かをする必要があるので、まずそれを何かにさせましょう。

int calcCipherColumn(char keyWord[25], char cipherText[17424],
                     int rowSize, char message[388]) 
{
    int keyColumn    = 0;
    int cipherColumn = 0;
    int offset       = 1;
    int nextWord     = 1;

    int lengthOfWord   = 0;
    int lengthOfCipher = 0;

    lengthOfWord = length(keyWord);
    lengthOfCipher = length(cipherText);

    while (keyWord[keyColumn] != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyWord[keyColumn + offset] 
        != cipherText[cipherColumn + (rowSize*nextWord) + nextWord]) {
            cipherColumn++;
            continue;
        }
    }
    return cipherColumn;
}

そこに、今それは何かをします。

何かを実行したので、何を取り除くことができるかを確認できます。この長さのものは使用されていません。このcontinueも何もしません。

int calcCipherColumn(char keyWord[25], char cipherText[17424],
                     int rowSize, char message[388]) 
{
    int keyColumn    = 0;
    int cipherColumn = 0;
    int offset       = 1;
    int nextWord     = 1;

    while (keyWord[keyColumn] != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyWord[keyColumn + offset] 
        != cipherText[cipherColumn + (rowSize*nextWord) + nextWord]) {
            cipherColumn++;
        }
    }
    return cipherColumn;
}

ソースコントロールの世界に住んでいて、行が変更されたと報告される唯一の理由は、行の一部が列に並んでいなければならないためではなく、別のことをしているためです。

int calcCipherColumn(char keyWord[25], char cipherText[17424],
                     int rowSize, char message[388]) 
{
    int keyColumn = 0;
    int cipherColumn = 0;
    int offset = 1;
    int nextWord = 1;

    while (keyWord[keyColumn] != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyWord[keyColumn + offset] 
        != cipherText[cipherColumn + (rowSize*nextWord) + nextWord]) {
            cipherColumn++;
        }
    }
    return cipherColumn;
}

ええ、私はそれが少し読みにくくなっていることを知っていますが、そうでなければvdiffツールを使用して変更を検出する人々を狂わせるでしょう。

ここで、行の長さの制限を超えないようにするためにある、これらのばかげた改行を修正しましょう。

int calcCipherColumn(
        char keyWord[25], 
        char cipherText[17424],
        int rowSize, 
        char message[388]
) {
    int keyColumn = 0;
    int keyOffset = 1;

    int nextWord = 1;
    int cipherColumn = 0;
    int cipherOffset = (rowSize * nextWord) + nextWord;

    char key = keyWord[keyColumn];
    char keyNext = keyWord[keyColumn + keyOffset];

    while (key != cipherText[cipherColumn]) {
        cipherColumn++;
        if (keyNext != cipherText[cipherColumn + cipherOffset]) {
            cipherColumn++;
        }
    }
    return cipherColumn;
}

そこで、ループ内のロジックは、ループ内で何が変化するかに焦点を当てています。実際、cipherColumn以外のすべてにfinalのマークを付けることができます。そしてねえ!あれ見てよ。今、それを行う余地があります。

私がしたことは、さらに3つの変数を追加し、1つの名前を変更して、それらを少し並べ替えることだけでした。その結果、たまたま行が!=でばかげた改行なしに収まるほど短くなりました。

keykeyNextの名前は説明的ではないことを確認してください。ただし、これらはそれぞれ一度しか使用されず、それほど長くは使用されません。最も重要なのは、ループ内で興味深いことを行っていないことです。だから彼らはする必要はありません。追加の変数を導入することで、必要に応じて名前を長くする余地ができました。状況は変化するので、最終的には必要になるかもしれません。もしそうなら、私たちに呼吸する余裕があるのは素晴らしいことです。

私もあなたに自由に見せました ジェフ・グリッグのフォーム6バリアント 行の長さの制限を尊重するために入力パラメーターをレイアウトするスタイル。

24
candied_orange

他の人はすでにいくつかの有用な提案をしています、要約させてください:

  • 1行あたり80文字は、80年代の黄金律でした。今日、ほとんどの人は100から130文字で問題ないことに同意しています。
  • 式の中で改行を使用します。
  • 中間結果を導入することにより、長い式を分割します。

私は別の推奨事項を追加したい:長い名前について独断的にしないでください!変数のスコープが大きいほど、より多くの情報をその名前に入れる必要があります。そして一般的に、変数のスコープを小さく保つことは良い考えです。

たとえば、キーワード暗号化テーブルの列に変数があり、この1つのテーブルのみが変数のスコープで使用されていることが明らかな場合は、columnまたはcolと呼んでもかまいません。スコープが大きく、複数のテーブルが含まれている場合は、keyWordEncryptionTableColumnと呼ぶのが理にかなっています。

別の例:2行または3行にまたがるボディを持つループがあり、配列の要素にアクセスするためにインデックスを使用する必要がある場合、インデックスiの呼び出しに問題はありません。このコンテキストでは、arrayIndexOfMyVerySpecialDataSetと言うよりも(少なくともほとんどの人にとって)はるかに読みやすくなっています。

15
Frank Puffer

プログラミング環境の制限により、多くの文体的な規則(ルールではありません!)が長年にわたって生まれました。パンチカード時代に戻って、物理的なソース行に表示できる文字数にhard制限がありました(これが、Fortranが行継続文字用に列6を予約した理由です)。私が80x24のアンバーオンブラックのVT220ターミナルで作業していたのは、何十年も前のことではありませんでした。私が使用したエディターは行を80文字に制限しませんでしたが、水平スクロールを回避するために最善を尽くした場合、人生ははるかに簡単になりました。

古いバージョンのFortran('77、IINMまで)では、長さが6〜8文字を超えるhave識別子さえも使用できませんでした。 80年代まで遅くても、Cは外部名の最初の8文字が意味があることのみを保証していました(そのため、一部のライブラリ関数にはstrpbrkのようなわかりやすい名前があります)。

もちろん、21世紀までの20年、私たちはもはやそのような制限を設けていません。より説明的な識別子を使用する理由はありませんnot

正しいコンテキストでは、ijk完全に合理的で意味のある名前です。ループで配列またはベクトルを反復処理していて、現在の要素を識別するために何かが必要な場合は、iが完全に機能します。私はcurrentElementのような名前は使用しません-それはもう意味がありませんそのコンテキストでは、そしてそれは単に視覚的な混乱を追加します。

とは言っても、あなたの教師は、あなたがより長く、より説明的な名前--すべてについて考えることを強いるのは間違っていません-最初にその習慣に慣れ、それから学ぶことはあなたにとって人生を楽にします必要に応じて節約する場所。 だったを一度にすべてを8文字以下に収めることを余儀なくされた誰かとして、より少ない情報よりも多くの情報を優先するほうが間違いなく優れています。経験を積むにつれて、識別子の長さを節約できる場所と、もう少し説明的にする必要がある場所がわかります。

3
John Bode

私は一般的にあなたの先生に同意します。ただし、失敗する大きなコードで頻繁に使用する変数がある場合は、その意味を明確にした後、省略形を使用することをお勧めします。複雑な算術式や代入がたくさんあるときのように、それらは長い変数名ではうまく読みません。

アウトラインについて:

ExtractMessage(char keyWord[25], char cipherText[17424],
               int rowSize, char message[388]) 

これは意味がありません。行の長さを制限するだけでは読みやすくなりません。これを読みやすくしたい場合は、次のようにします。

ExtractMessage(
  char keyWord[25],
  char cipherText[17424],
  int rowSize,
  char message[388]
  )
{

そして、型識別子を整列させることもできます(intの後にスペースを追加します)。ただし、次のような初期化または引数リストの概要には注意が必要です。

int keyColumn    = 0;
int cipherColumn = 0;
int offset       = 1;
int nextWord     = 1;

問題は、名前を変更したり、変数を追加したりするとき、見栄えを維持するためにブロック全体を再フォーマットする必要がある場合があることです。それはあなたが導入するであろう無意味な変更ほど仕事のためではなく、バージョン管理システムでは恐ろしく見えます。同僚は、あなたがファイルを変更したことを確認し、以前のバージョンと比較して、何をしたかを確認します。次に、すべての行が変更されたときに点灯し、実際の変更が不明瞭になります。これは実際にどれほど悪いかを使用する比較ツールの品質に少し依存しますが、一般に、コードを個人的にしすぎたり、1行のフォーマットを他の行に依存させることはお勧めできません。

アウトラインが目的に役立つ場合があります。ほぼ同じ数十行が連続している場合、アウトラインを作成すると、どこが異なるかを簡単に見つけることができます。

職場では、バージョン管理システムに提出する前に、コードに対して行った高度な書式設定を根絶するいくつかの自動書式設定が行われている可能性があることに注意してください。

3
Martin Maat

免責事項:私はここで私のポイントを明確にするために少し誇張しています。だから、一粒の塩でどんな最上級のものでも取ってください。

あなたの先生は100%正解です:(あなたがLinuxコードを書いているのでない限り)もはや80文字ほどの「黄金律」はありません。そのルールは当時の端末のサイズのために確立されましたが、今日では、簡単にエンディターウィンドウに150文字以上詰め込みます。また、その制限を超えた場合でも、エディターが行をソフトラップして、スクロールする必要がないようにすることが望まれます。 80文字を超えないようにする唯一の理由は、スクロールの必要性でした

とはいえ、実際にラインを無期限に成長させないようにする必要があります。線が長いほど、人間が解析しにくくなります。しかし短い変数名は長い行の問題の解決策ではありません

救済策はさらに適切に名前が付けられた変数を導入することによって論理的に式を分割するです。空白を巧みに使わないでください。適切に名前を付けることができる部分式を特定し、その変数を作成するだけです。 これにより、変数を計算するコードと、その変数を使用するコードの両方が簡略化されます


あなたの質問の一部ではありませんが、とにかくそれについてコメントしたいと思います:=演算子を垂直方向に揃えることは非常に悪い考えです。

これには3つの理由があります。

  1. 垂直方向に整列された演算子を含むブロックの編集は、PITAです。最大の変数の長さが変更(名前の変更、追加、削除)するたびに、ブロック内のすべての行を修正して、「Nice」レイアウトに戻す必要があります。

    もちろん、この問題は有能なエディターを使用することで少し軽減される可能性があるため、それはマイナーな理由です。本当の理由は2番目です:

  2. 再調整によって導入されたこれらの誤った空白の変更は、gitのような最新のバージョン管理システムではうまく機能しません。実際の競合が発生していない場合や、アライメントを使用しなかった場合に競合が発生しない場合は、大量のマージ競合が発生する傾向があります。 これらの偽りの競合のそれぞれは、何もせずに貴重な時間を消費します

  3. アラインメントは意味的意味がゼロです。それは無意味です。アラインメントを使って理解できることは何もありません。ブロック内のすべての行は、それが何をするのかを理解するために、それ自体を読み取る必要があります。上下の行への接続は、純粋に構文上のものです。

アラインメントには意味的な意味はありませんが、かなりのコストがかかるため、これ以上時間がかかる前に、習慣を忘れてください。


80文字の制限が好きなら、Fortranプログラミングを試してください。確かに、新しい規格ではfortran行の制限が132文字に引き上げられていますが、制限を超えたプログラムのコンパイルに障害が発生した場合でも、これは引き続き有効です。プログラミングに長けている場合は、その行の長さの制限を含め、Fortranがすぐに嫌われるようになります。その後、あなたは一生癒されるでしょう。

私自身もいくつかのFortranプログラミングを専門的に行う必要があり、そのことは、その行の長さの制限を最も深く嫌うことを教えてくれました。コンパイラが正しくそれを正しくコンパイルしないという理由だけで、そうでなければ単純で読みやすい行をパーツに分割する必要があることほど、イライラすることは何もありません。そして、コードが1行で表されている場合に最も単純なコード行が確実に存在します。