2

編集:すべての返信者に感謝します。元の投稿で、これらの関数の仕様を変更することは許可されていないことを言及する必要があったため、アサーションを使用したり、NULL を逆参照できるようにするソリューションは問題外です。これを念頭に置いて、関数ポインターを使用するか、複製をそのままにしておくかのいずれかであることがわかります。わかりやすくするために、今回は関数ポインターを避けたいと思います。

オリジナル: 明快さを失うことなく、コードの重複を避けようとしています。多くの場合、特定の割り当て(Uni -学部生)に取り組んでいるときに、これらの関数のパターンが返されることを認識しますが、常に「素晴らしい仕事」の解決策があるとは限りません..

チェックをよりモジュール化するために同じ方法でいくつかの引数をチェックするこれらの3つのC関数で何をすべきか(関数へのポインタ、マクロなど)を提案します(よりモジュール化する必要がありますよね?) ?

ところで、これらは HW 割り当てから直接取得されるため、機能の詳細は私の質問には関係なく、関数の上部でチェックする引数のみです。

 teamIsDuplicateCoachName(Team team, bool* isDuplicate) {
    TeamResult result = TEAM_SUCCESS;
    if (!team || !isDuplicate) {
        result = TEAM_NULL_ARGUMENT;
    } else if (teamEmpty(team)) {
        result = TEAM_IS_EMPTY;
    } else {
        for (int i = 0; i < team->currentFormations; ++i) {
            if (teamIsPlayerInFormation(team->formations[i], team->coach)) {
                *isDuplicate = true;
                break;
            }
        }
    }
    return result;
}

TeamResult teamGetWinRate(Team team, double* winRate) {
    TeamResult result = TEAM_SUCCESS;
    if (!team || !winRate) {
        result = TEAM_NULL_ARGUMENT;
    } else {
        int wins = 0, games = 0;
        for (int i = 0; i < team->currentFormations; ++i) {
            Formation formation = team->formations[i];
            if (formationIsComplete(formation)) {
                games += formation->timesPlayed;
                wins += formation->timesWon;
            }
        }
        double win = ( games == 0 ) ? 0 : (double) wins / games;
        assert(win >= 0 && win <= 1);
        *winRate = win;
    }
    return result;
}



TeamResult teamGetNextIncompleteFormation(Team team, Formation* formation,
        int* index) {
    TeamResult result = TEAM_SUCCESS;
    if (!team || !formation || !index) {
        result = TEAM_NULL_ARGUMENT;
    } else {
        *formation = NULL; /* default result, will be returned if there are no incomplete formations */
        for (int i = 0; i < team->currentFormations; ++i) {
            Formation formationPtr = team->formations[i];
            if (!formationIsComplete(formationPtr)) {
                *formation = formationPtr;
                *index = i;
                break;
            }
        }
    }
    return result;
}

コードの重複を(具体的に)回避する方法についてのアドバイスをいただければ幸いです。

御時間ありがとうございます!:)

4

6 に答える 6

1

チーム オブジェクトをチェックする関数を作成します。

TeamResult TeamPtrCheck(Team *team)
{
    if (team == NULL)
        return TEAM_NULL_ARGUMENT;
    else if (teamEmpty(team))
        return TEAM_IS_EMPTY;
    else
        return TEAM_SUCCESS;
}

そして、それを参照 + 各関数の上部にあるその他のチェック、たとえば

TeamResult = TeamPtrCheck(team);
if (TeamResult != TEAM_SUCCESS)
    return TeamResult;
if (winRate == NULL)
    return TEAM_NULL_ARGUMENT;

それ以外の場合、各機能異なる場合は、チェックを別のままにしておきます。

于 2013-11-13T20:34:55.123 に答える