動作環境
組込みC
# include <stdio.h>
# include <stdbool.h>
void process_return_early(bool *flag1, bool *flag2, bool *flag3)
{
if (*flag1) {
*flag1 = false;
printf("flag1\n");
// 手仕舞い処理
return;
}
if (*flag2) {
*flag2 = false;
printf("flag2\n");
// 手仕舞い処理
return;
}
if (*flag3) {
*flag3 = false;
printf("flag3\n");
// 手仕舞い処理
return;
}
}
void process_nest(bool *flag1, bool *flag2, bool *flag3)
{
if (*flag1) {
*flag1 = false;
printf("flag1\n");
} else {
if (*flag2) {
*flag2 = false;
printf("flag2\n");
} else {
if (*flag3) {
*flag3 = false;
printf("flag3\n");
}
}
}
// 手仕舞い処理
}
int main(void) {
bool flags[] = { false, true, true };
process_return_early(&flags[0], &flags[1], &flags[2]);
process_nest(&flags[0], &flags[1], &flags[2]);
return 0;
}
run
flag2
flag3
備考
- 手仕舞い処理をどのように実装するかで、どちらの方法が読みやすいコードになるか
- return earlyはflagsが増えると縦に伸びる
- nestはflagsが増えると横に伸びる
- 一覧性が高いのはどちらか?
- 1つのフラグに対する処理が見やすいのはreturn earlyかもしれない
- ifの優先順位を変更しやすいのはreturn early
- nestの場合、インデントの変更が必要
- 条件の数によっても読みやすさは異なる
- decision tableなどの使用も要検討
- 違うだろうか
code > terminate関数のコール
# include <stdio.h>
# include <stdbool.h>
void terminate_clearing_flag(bool *flag)
{
*flag = false;
// 手仕舞い処理
}
void process_call_terminate_func(bool *flag1, bool *flag2, bool *flag3)
{
if (*flag1) {
printf("flag1\n");
terminate_clearing_flag(flag1);
return;
}
if (*flag2) {
printf("flag2\n");
terminate_clearing_flag(flag2);
return;
}
if (*flag3) {
printf("flag3\n");
terminate_clearing_flag(flag3);
return;
}
}
int main(void) {
bool flags[] = { false, true, true };
process_call_terminate_func(&flags[0], &flags[1], &flags[2]);
process_call_terminate_func(&flags[0], &flags[1], &flags[2]);
return 0;
}
flag1などの命名はポインタ変数と分かる名前の方がいいかもしれない。
(例: pflag1, flag1ptr, flag1Ptr)
謝辞
@tenmyo さんに優先度付き分岐時の良い実装例を教えていただきました。
情報感謝です。
@mt08さんに関数ポインタの配列テーブル使用例を教えていただきました。
情報感謝です。