0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C > function > return early | nest | terminate関数のコール | 優先度付き分岐でのif | 関数ポインタ配列テーブル使用

Last updated at Posted at 2018-03-07
動作環境
組込み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さんに関数ポインタの配列テーブル使用例を教えていただきました。

情報感謝です。

0
0
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?