編集:すべての返信者に感謝します。元の投稿で、これらの関数の仕様を変更することは許可されていないことを言及する必要があったため、アサーションを使用したり、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;
}
コードの重複を(具体的に)回避する方法についてのアドバイスをいただければ幸いです。
御時間ありがとうございます!:)