5


0

PHP、C ++など 構文の説明

なぜ、ほとんどのプログラミング言語で、ステートメントの後に「セミコロン」が必要なのに、「if」、「elseif」、「else」のようなものの後ではなく、* _ required_ *であるのはなぜですか。

コンパイラーはすべて改行を探しますか?

*私は何かが足りないのですか?*それは本当に私には意味がありません…​

6 Answer


11


通常、コンパイラはほとんどの空白を無視するため、セミコロンが必要です。 if、elseif、elseのようなステートメントの後には必要ありません。ステートメントの終わりではないからです。 これらは、ステートメントまたはステートメントのブロックが続く場合にのみ完全なステートメントです。


2


これらの言語のコンパイラは、ステートメントの終了に空白を考慮しないためです。 ステートメントは何らかの方法で終了する必要があり、セミコロンで終了します。 ステートメントを正しく終了する限り、すべてのコードを(恐ろしい、恐ろしいアイデアですが)1行で書くことができます。


2


一部のコンパイラは、空白の割り当てを無視し、セミコロンを使用してステートメントを決定します(変数の割り当てvs. \ {}コードブロックの場合。

pythonのような他の言語は、空白を使用してステートメントとifブロックを見つけます。


2


これは、ステートメントと式の違いに関連しています。 Cなどの言語では、一連のステートメントを含むブロックが必要です。 「if」や「while」などの制御フロー構造は、すべて独自のステートメントです。

void foo() {
    if (bar) {
        /* ... */
    }
    while (baz) {
        /* ... */
    }
}

`foo()`内のすべてがステートメントであるため、ここではセミコロンは必要ありません。 問題は、ステートメントが期待される場所で `bar()`のような式が必要な場合はどうでしょうか? Cの文法では、式の後にセミコロンを追加することでそれができると言われています(言い換えると、式の後に `;`が続くことはステートメントです)。

したがって、これは無効です:

void foo() {
    1 + 2
}

「1 + 2」は式だからです。 あなたはそれを声明に変える必要があります:

void foo() {
    1 + 2;
}

何が起こっているかを完全に理解するために、ブロック( `{foo();}`のようなカーリーの何かもステートメントであり、 `if`の文法は次のようなものであることに注意することが重要です:

if (  )  (else )?

これが、 `if`ステートメントが本体または単一のステートメントのブロックを持つことができる理由です:ブロックは単一のステートメントです。


1


「;」を使用する理由ステートメントを終了するには '\ n’ではなく。

言語のセマンティクスに影響を与えるものとして空白を使用する言語はほとんどありません(改行は空白です)。 これは、開発者にとって非常にエラーが発生しやすいためです(ホワイトスペースはすべての目に見えないためです)。

空白を使用してセマンティクスに影響を与える言語を見ると、プログラマーへの影響がわかります(通常、特別なツールは、物事を調整するために構築されています)。 タブの代わりにスペースを挿入し、これによりループが早期に終了したためにフラストレーションが生じた場合に髪を引き裂いた多くのハゲ開発者(男性と女性)。 :-)

また、言語のセマンティックな意味を変更するために空白を使用しないことにより、言語の人間の読者だけに空白を使用して、コードを読みやすい形式にしようとすることができます(人間にとって)空白を乱用して意味を隠すことができます)。

すべてのステートメントが空白ではない理由

ステートメントの終わりを確認する方法が必要なだけです。 +ステートメントの終わりがどこにあるかが明らかであり、パーサーがステートメントの終わりを検出できるようにするための追加の区切り文字は必要ありません。


1


ソースコードは一連のステートメントです。 区切り文字を使用して、ステートメントを区切る必要があります。 改行を区切り文字として使用すると、コードを構成できません。 非常に長い行は、スクロールによってのみ読み取り可能になります。 (スクロールを避けるために、通常、長い行は分割されます。)例えば:

ParserUtils.RefreshProperty(m_cfg.PORTAL_ID, ParserUtils.CreateHashFromUrl(strDetailLinkUrl), Convert.ToInt32(m_cfg.Type), strPrice, strAddress, strStreet, strPostCode, strFeatures, strDescription, strImgFile, strBedrooms, strReception, strBath, strStatus, strLink, strPropType, strOutside, strTenure, strKeywords, strFullText, strContactInfo, m_ieBrowser.URL);

これは非常に見苦しく、この代わりに、この行を複数の行に分割して読みやすくします。

    ParserUtils.RefreshProperty(m_cfg.PORTAL_ID,
    ParserUtils.CreateHashFromUrl(strDetailLinkUrl),
    Convert.ToInt32(m_cfg.Type), strPrice,
    strAddress, strStreet, strPostCode, strFeatures, strDescription, strImgFile,
    strBedrooms, strReception, strBath, strStatus, strLink, strPropType,
    strOutside, strTenure, strKeywords, strFullText, strContactInfo,
    m_ieBrowser.URL);

改行が区切り文字である場合、これは不可能です。 改行が演算子である場合、「If」、「while」、および「for」は完全に混乱します。 このコードを見てください:

for (int i = 0; i < n; i++)
    {
        if (i % 2 == 0)
        {
            System.out.println("It can be divided by two");
        }
        {
            System.out.println("It can't be divided by two");
        }
    }

セミコロンではなく改行が演算子である場合、このソースコードは非常に見苦しくなります。

for (int i = 0
     i < 0
     i++) { if (i % 2 == 0) { System.out.println("It can be divided by two")
                          } { System.out.println("It can't be divided by two")
                          } }

このコードは読みにくく、区切り文字として論理的に有効です。 たとえば、妻は次のような紙(アルゴリズム)に私のタスクを書き込みます。

Buy food(Bread, Meat, Butter),
Go and pay the taxes,
Call your mother, because she wants to talk to you

これらのタスクはコンマで区切られていますが、パラメーターもコンマで区切られていることに注意してください。 コンピューターは人間ほどインテリジェントではないため、パラメーター区切り記号としてのコンマとタスクの区切り記号としてのコンマを区別する必要があります。 結論として、タスクの区切り記号は、パラメーターの区切り記号よりも大きいコンマです。 これが、ステートメントの区切り記号がセミコロンであり、パラメーターの区切り記号がコンマである理由です。