web-dev-qa-db-ja.com

ループ内にループがあるのはどの時点でタブーなのですか?

ちょっと興味があるんだけど。 Linus Torvalds:からこれを読んだ後、私が今まで持っていた最も多くはforループ内のforループでした

タブは8文字であるため、インデントも8文字です。インデントを4文字(または2文字)深くすることを試みる異端的な動きがあり、これはPIの値を3に定義しようとするのと同じです。

理論的根拠:インデントの背後にある全体のアイデアは、制御のブロックが開始および終了する場所を明確に定義することです。特に、画面を20時間連続して見ている場合、大きなインデントがあると、インデントがどのように機能するかを簡単に確認できます。

さて、8文字のインデントがあるとコードが右に移動しすぎて、80文字の端末画面では読みにくくなると主張する人もいます。 これに対する答えは、3レベルを超えるインデントが必要な場合、とにかくねじ込まれているため、プログラムを修正する必要があるということです

https://www.kernel.org/doc/Documentation/CodingStyle

ループの3番目のレイヤーに行くのは受け入れがたい慣行であり、コード(主にQt)を再構築すると考えました。

ライナスは冗談でしたか?

言語やアプリケーションに依存しますか?

3レベル以上のループが絶対に必要なものはありますか?

23
Akiva

カーネルは単純なアルゴリズムを強く好む

さまざまなアルゴリズムでは、ループ内に深くネストされたループが必要になる場合がありますが、Linuxカーネル(引用が述べられている)のコンテキストでは、通常、迅速なリアルタイム応答が必要です。そのコンテキストでは、深い入れ子は、このドメインのコードフローが複雑すぎて、読みやすさやインデントの問題ではなく、その実行特性のために変更が必要になる可能性があることを示す匂いです。

さらに、Linuxカーネルは、監査性とテストの要件に関してほとんどのアプリケーションコードとは異なります。したがって、単一の関数で4+レベルのネストされたアルゴリズムを持つnotを好むでしょう。各コードフラグメントが何をするか正確にを確認し、考えられるすべての制御フローとEdgeのケースを含めて、詳細を確認してください。深くネストされたコードはそれを妨げます。

19
Peteris

"タブは8文字です"で、この引用を真剣に受け止めることはある程度しませんでした。タブレーターの重要な点は、それらが固定数の文字ではないということです(もしあれば、タブはone文字です)。なんてこった同様に、「3レベルのインデント」という厳格な規則を設定することは正気だと完全に確信しているわけではありません(anythingに対して厳格な規則を設定するのはまともです) 。

ただし、インデントのレベルを制限するisは一般的に妥当な提案であり、驚くべきものではありません。

最終的に、プログラムが3レベルの反復を必要とする場合、それがプログラムに必要なものです。見積もりの​​精神は、プロジェクトからその要件を魔法のように軽減することではなく、ロジックを関数と型にハイブしてコードを簡潔にし、表現力を高めることです。

これは、インデントレベルに関して上記と同じガイドラインにフィードバックするだけです。これは、コードをどのように構造化し、読みやすく、保守しやすく、今後何年にもわたって修正できるようにするためのものです。

重要な点は、フロー制御構成と同じです。コードが理解しにくい場合は、リファクタリングする必要があります。多次元配列の単純な操作を行う場合、最も内側のループのロジックが単純である限り、ループを5または6の深さにネストすることが適切な場合があります。ただし、複雑なビジネスロジックを処理していて、ループの本体が数十行以上ある場合は、そのループを2つ以上の深さにネストしたくないでしょう。コードの 循環的複雑度 を計算してみることができますが、実際に問題になるのは、問題のコードの可読性と保守性です。

16
TMN

ライナスは冗談でしたか?

この作品は遊び心のあるスタイルで書かれており、著者はコーディングスタイルが真剣な実践者の間で議論される方法に精通していることを示唆しています。私たちは皆好みを持っています。その多くは単なる個人的な好みの問題であると私たちは完全に理解しています。彼は、非常に多くの言葉で、"Coding style is very personal, and I won't _force_ my views on anybody"-少なくとも彼が個人的に管理しているコードの外。しかし、与えられたプロジェクトのスタイルの一貫性は非常に良い考えです。特定の関数で複数のスタイルを処理するよりも、嫌いなスタイルにコーディングするほうがはるかに便利です。

明らかに遊び心のある文章の例を次に示します。

However, there is one special case, namely functions: they have the
opening brace at the beginning of the next line, thus:

int function(int x)
{
    body of function
}

Heretic people all over the world have claimed that this inconsistency
is ...  well ...  inconsistent, but all right-thinking people know that
(a) K&R are _right_ and (b) K&R are right.  Besides, functions are
special anyway (you can't nest them in C).

遊び心(1)。

インデントが制御不能にならないようにしようとすることは間違いなく良いアドバイスですが、3レベルの最大値は双曲線になる可能性があります。カーネルソースをgrepし、4つのタブ文字のシーケンスをカウントするつもりはありませんが、Torvaldsが書いたものを少なくとも1つ見つけることができると思います。

一方、誰かが3レベルのインデントを頻繁に超えずにLinuxカーネルを記述できる場合、3レベルの制限は、自分のコードでしばらく試してみる価値があるかもしれません。これは性転換とは違いますね。それは生涯の約束ではありません。

Torvalds(2)よりもプログラミングをよく理解していると思われるインターネット上の誰かに出くわした場合、まあ、どのような人々がインターネット上で大いに話したいと思うかはご存じでしょう。

一方、彼は8スペースのタブについて犯罪的に間違っています。それは、拘束されたままでスロットを通して給餌されるべき男の絶望です。 4つのスペースは明らかに正しいです。

(1)しかし、彼が誤って楕円の前にスペースを置き、その後ろに2つのスペースを置き、完全に停止した後に2つのスペースを置いたことに注意してください。間違っている、間違っている、間違っている。そして、彼は異端者を非難するために勇敢なゴールを持っています。 異端者はあなたです、トーバルズ! IT IS YOU!

(2)「 ソース管理システムの設計方法を理解する 」について話したい場合は、議論の余地があるかもしれません。

注:同じ編集を繰り返し送信した親愛なるユーザー:引用された資料の書式は、著者が意図したとおりに正確に保持されます。それは、固定幅のテキストのフォーマットについてかなりの考えを与えた誰かによる、固定幅のテキストで書かれた固定幅のテキストのフォーマットに関するエッセイからであるからです。書式設定は、作者の意図の意識的な部分であり、主題に関連しています。

さらに、私は自分のテキストでその書式設定を再度参照しました。プリフォーマットを削除すると、脚注(1)が意味不明になってしまいます。プレフォーマットが削除されている場合、脚注のテキスト(1)も、文の終わりで完全に停止した後のスペースのペアを参照しているはずです。とにかくその脚注を削除した理由は、書いたときよりも面白くないからです。しかし、脚注を削除せずに書式を削除することは役に立ちません。

13
Ed Plunkett

Linusは非常に鈍いスピーキングスタイルと乾いたユーモアのセンスがありますが、この場合冗談ではありませんでした。 algorithmが2レベルよりも深くネストする必要がある状況がありますが、これは、コードをインデントする以外の方法を使用して実現できます。 Linuxカーネルスタイルガイドでは、深くネストされたループを維持することが難しいため、これらの他の方法を強く推奨しています。これが、Linusがここで述べていることです。

別の方法の例として、再帰を使用したり、内部ループを独自の関数に分割したり、中間データ構造を作成したりできます。

過度の入れ子は、書きやすいが読みにくいケースの1つです。大きなタブの深さを設定することは、Linusが書くのも面倒にする方法です。

9
Karl Bielefeldt

質問をする人としない人のアドバイスが異なる質問がたくさんあります。 「2レベル以上の深さでネストされたループがあるか」と尋ねると、その質問をしている人の答えは「いいえ」です。あなたが尋ねたら、それをしないでください。質問する必要がないほど十分な経験がある場合は、どちらの場合も正しい答えがわかります。そして、答えがあなたのためではないので、あなたが答えに同意しなくても議論しないでください。

3
gnasher729

これは、尻尾が犬を振っている教科書のケースのようです。

80文字のディスプレイを使用している場合、もちろんコードが可能な限りコードに最適な構造

残りのポイントに取り組む:

私はそれが受け入れがたい慣習だと思った。

あなたはこれを読みすぎていると思います。文脈を適切に理解せずに、読んだものすべてを福音とする衝動に抵抗します。

彼は冗談でしたか?

コンテキストを確認するのは難しいですが、上記の私の元のポイントを参照してください。

言語またはアプリケーションに依存しますか?

まさにその通り。端末(または端末エミュレータ)でコーディングする可能性が高いメインフレーム/ミッドレンジ言語を使用します。

3レベル以上のループが絶対に必要なものはありますか?

はい、一部のブルートフォースアルゴリズムでは非常に一般的です。プロジェクトオイラーの 問題31 を参照してください。これは、多数のループ(正確には8)を使用してブルートフォースで解決できる問題の典型的な例です。

1
Robbie Dee

ライナスは冗談でしたか?

いいえ、それらは公式のガイドラインです。

言語やアプリケーションに依存しますか?

コーディングのガイドラインは一般的に言語とアプリケーションに依存しますが、深くネストされたコードalwaysは読者に負担をかけます。

ネストされたコードの問題は、一般に、循環的複雑度が増加することです。つまり、コードがネストされているほど、関数内に存在する可能性のある実行パスが多くなります。潜在的な実行パスの組み合わせが急増すると、コードについて推論することが難しくなるため、一般的には回避する必要があります。

なぜ3なのか?主観的なコーディングガイドラインは、強制するのが難しく、自動的に実行することが不可能です。インデントの最大レベルで客観的なコーディングガイドラインを設定するには、数値に同意する必要があります。選択したLinuxカーネルで3。

それは恣意的であり、明らかに彼らにとっては十分です。

3レベル以上のループが絶対に必要なものはありますか?

ただし、アルゴリズム的には、おそらく十分に表現力のある言語では、コードを(関数またはクロージャーにかかわらず)小さなチャンクにいつでもリファクタリングできます。

明らかにネストを少なくして、コントラクトをスペルすることなく相互に呼び出す小さな関数の多くで難読化されたコードを書くことができます...

...しかし、明確な契約を持つ小さな機能は、一般的に明確な契約を持つ大きな機能よりも監査がはるかに簡単です。

0
Matthieu M.