4

これは初心者レベルの質問ですが、空の if ステートメントを使用することをお勧めします。

次のコードを検討してください。

void RabbitList::purge()
{
    if(head == NULL)
    {
        //cout << "Can't purge an empty colony!" << endl;
    }
    else
    {
        //Kill half the colony
        for(int amountToKill = (getColonySize()) / 2; amountToKill != 0;)
        {
            RabbitNode * curr = head;
            RabbitNode * trail = NULL;

            bool fiftyFiftyChance = randomGeneration(2);

            //If the random check succeeded but we're still on the head node
            if(fiftyFiftyChance == 1 && curr == head)
            {
                head = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check succeeded and we're beyond the head, but not on last node
            else if(fiftyFiftyChance == 1 && curr->next != NULL)
            {
                trail->next = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check succeeded, but we're on the last node
            else if(fiftyFiftyChance == 1)
            {
                trail->next = NULL;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check failed
            else
            {
                trail = curr;
                curr = curr->next;
            }
        }
        cout << "Food shortage! Colony has been purged by half." << endl;
    }
}

ご覧のとおり、5 行目の if ステートメントは現在コメント アウトされています。これはデバッグ用のテキストであり、コンソールにフィードバックを送りたくありません。if ステートメントが何もしないようにするのは悪い習慣と見なされると確信しています。私は戻ってくることができることを知っています。

しかし、戻り値の型が void であるため、エラーが発生します。たとえば、戻り値の型が void でない場合はどうなりますか?

4

7 に答える 7

6

戻り値の型が void であっても、それは合法でreturnあり、確かifに中括弧があるため、少なくともこれは発生するのを待っているバグではありません。ただし、見栄えがよくなく、読む/理解するためにもう少し作業が必要です。

あなたはそれを次のように言い換えることができます

if(head == NULL) // or if(!head)
    return;

....

これにより、else の必要がなくなり、コードの残りの部分はネストされたスコープではなく、関数内にあるという嬉しい特典が得られます。

于 2013-01-11T01:12:33.457 に答える
5

単一のブランチの場合は、次のように直接記述します。

if (head != 0) {
    // whatever
}

複数のブランチの場合、最初のブランチを空にすることで、次の条件を簡素化できる場合があります。

if (head == 0) {
    // nothing to do
} else if (head->next == 0) {
    // whatever
} else {
    // whatever else
}

はい、追加のレイヤーを使用して最後のものを書くことができます。

if (head != 0) {
    if (head->next == 0) {
        // whatever
    } else {
        // whatever else
    }
}

しかし、特に 2 番目の形式が 3 つまたは 4 つのレベルの if で終わる場合は、最初の形式の方が明確です。

ああ、そして

if (head == 0)
    return;

関数に余分な終了ポイントが導入されるため、難しい場合があります。以前はこのフォームのファンでしたが、ここ数年、かなり頻繁に削除するようになりました。

于 2013-01-11T13:08:24.310 に答える
2

繰り返しと冗長性を削除して、関数を書き直しました。それは適度に小さく沸騰します。

void RabbitList::purge()
{
    if(head == NULL) return;

    //Kill half the colony
    for(int amountToKill = (getColonySize()) / 2; amountToKill != 0;)
    {
        RabbitNode * curr = head;
        RabbitNode * trail = NULL;

        bool fiftyFiftyChance = randomGeneration(2);

        if(fiftyFiftyChance == 1 )
        {
            if( curr == head)
                head = curr->next;
            else
                trail->next = curr->next;

            delete curr;
            --size;
            --amountToKill;
        }
        else
        {
            trail = curr;
            curr = curr->next;
        }
    }
    cout << "Food shortage! Colony has been purged by half." << endl;
}
于 2013-01-11T02:06:24.137 に答える
2

if最初の までの部分を取り除き、elseそれを に置き換えます。これは反対の条件であるため、if-else 状況でif (head)を置き換えるのに最適です。elseただし、関数全体のインデントの余分なタブの問題があります。その時点で、それはより好みになりますが、私自身はチェックを早めに行い、インデントを持たないことを好みます.

どこからでも戻る必要がある場合は、 で戻ることができますreturn;

于 2013-01-11T01:12:33.700 に答える
2

私はこれが主観的であると実際に信じていません。なぜデッドコードを書くのか? 初心者の証です。代わりに、あなたが求めている条件をチェックして、それを終わらせてください:

if(!head)
   // stuff
于 2013-01-11T01:13:13.603 に答える
1

@Oli がコメントで述べたように、これは主観的なスタイルの問題です。次の 2 つの選択肢があります。

if (<something is true>) {
    // Do nothing
} else {
    // Some code goes here
}

また

if (!<something is true>) {
    // Code goes here
}

特に条件が適度に複雑な場合は、前者の方が後者よりも読みやすい状況を想像できます。

于 2013-01-11T01:37:46.593 に答える
0

私はそれを残します。

しかし、ログを仮想化します (std::cout は常に役立つとは限りません)。

struct NullLogger : public Logger
{
    virtual void log(std::string const&) {}
};

// By default use the Null Logger
// But if you need to debug just pass a useful specialization of logging.
void RabbitList::purge(Logger const& logger = NullLogger())
{
    if(head == NULL)
    {
        logger.log("Can't purge an empty colony!");
    }
    else
    {
于 2013-01-11T03:38:28.357 に答える