先輩,読みやすいコードってなんスカ.

2025年6月14日tech

あなたと共同開発をしている友人の佐藤くんは「 a, b, i, n, temp, val 」 など,変数や関数にこういった命名をしてしまう...つい2週間前に自分で書いたコードを自分で読めないことがあるみたいです(!).
佐藤くんこれを反省していて,当面の目標はソースコードの美しさを追求することだそうです.
「読みやすいコードを書きたい」,と.ところで読みやすいコードってなんなんすかね.

そもそも,なぜ読みやすいコードがいる?

佐藤君が趣味や学生時代に研究で書いたプログラムと,エンジニアとして書くコードは根本的に違います.研究で書いたコードは,なんとか動けばいいし,不具合で困るのは自分だけですし,コードの寿命もせいぜい数年です.一方エンジニアは商品開発という目的のためにソースコードを書きます.取り巻く環境,使用言語,寿命,利用者に大きな違いがあるようです.

エンジニアのコードに求められるのは「読みやすいコード」です.この読みやすいコードとはなんでしょうか.
・誰が読んでも意図が明確
・直感的に理解ができる
・保守性や拡張性に優れる

誰がコードを利用するのか,いつまでコードが利用されるのか,エンジニア自身にはコントロールすることができません.コンパクトなコードと読みやすいコードは異なります.理解しやすいように,と追求した結果コンパクトなコードになります.

本題:名は体を表す?

さて,次のコード,どっちが読みやすいでしょうか.

for(i=0;i<max;i++){
    if(toshi=="tokyo"){
        cnt++;
    }
}
for (index = 0; index < numCity; index++) {
    if(cityName = "tokyo") {
        countTokyo++;
    }
}

temp,cntなどの略語はなるべく避けるべきです.temporary(一時的な)の略なのか,temperature(温度)の略なのかわかりません.count(カウント)なのかcountry(国)なのか,どっちの略なんでしょうか.日本語をローマ字で書くのも避けるべきじゃないでしょうか.例えばtoshi.都市(city)でしょうか.年(year)でしょうか.それとも歳(age)でしょうか.a, b, n, m, x, y, temp, ret, calcなどの略語は混乱を招くため,避けましょう.

色々な単語を探して使ってみましょう.
・stop → 停止はわかるが,再開するのかな?
・pause → 一時的に停止して,再開しそう!
・kill → 完全停止して,再開はなさそう!
・create → 何か作るっぽい
・generate → 自動で作ってそう!

変数は名詞を意識しましょう.
 pauseCalc とか,maxVal とか,studentNum とか.
関数名は動きを意識しましょう. 
 get_page_number とか, calc_atom_dimension とか.

ちなみに,forやwhileのループで使う「 i 」 とか 「 k 」 とか.このようなループインテレータや一時的なバッファなどに限り許されることが多いみたいです.


命名に規則を.

変数や関数の命名にはルールがあることが多いです.大きく4種類あるみたいです.
スネークケース
snake_caes アンダーバーで繋げます.
キャメルケース
camelCase 後ろの単語を大文字にします.
パスカルケース
PascalCase. 前の単語,後ろの単語を大文字にします.
ハンガリアン
gwData

わたしは変数にはキャメルケース,関数名にはスネークケースを使います.グローバル変数であることを明示したいため,ハンガリアンの要素も軽く取り入れます.

float gAtomNum  //gでグローバルを明確に.
void calclation_atom_position(int atomId, atomVelocity) {
    int atomPosition = atomId * atomVelocity;
}

どうして atomNum にしたの?どうして atomval にしたの?と,問われても答えられるように頑張りましょう!

ロジックは明快に‼️

DRY原則,というものがあります.Don’t Repeat Yourself , 繰り返しを避けよ.
避けるべき記述 {
・演算式が巨大;
・記述が冗長;
・多重ループ;
・いらない変数;
・メモリを管理できていない;
}
例えば a,b,c の3つの整数のうち,最大の整数はどう求めたらいいでしょうか.

う〜〜む,こんなコードを書いてみました.

if (a > b) {
    if (a > c) {
        max = a;
    } else {
        max = c;
    }
} else {
    if (b > c) {
        max = b;
    } else {
        max = c;
    }
}

う〜〜〜〜〜〜む.こんなコードも書いてみました.

max = a;
if (max < b) {
    max = b;
}
if (max < c) {
    max = c;
}

どちらも最大値を求めることができます.が,下の方が理解しやすく,コンパクトな気がします.

スコープも大事,ですよね

前提として,グローバルな変数や関数は使うべきではありません.
・どこでどのように参照されているか把握しづらい
・ローカル変数と衝突しても気付きにくい.

グローバル変数はどこからもアクセス,書き換えができるため自由で便利です.が,そこが危険ですね.可読性,保守性,拡張性の観点からも使うべきではありません.

関数をちゃんと作りたい!

私は以下のような関数がある場合,修正の検討をします.
・呼び出すたびに異なる挙動をする
・直接関係のない複数の仕事をする
・関数外にあるコードから影響をうけやすい

関数の粒度というキーワードがあり,1つの関数で1つの明確な目的のみ持たせるようにします.SRPC(単一責任原則),ここのモジュールが請け負う責任は一つにすべきです.目安として,ディスプレイに収まるくらいの関数の長さがイイとか...例えば,input_and_output()みたいな関数は,入力も出力も,その間にある計算もしそうです.こういう時は関数を分けてみましょう〜.

コーディングスタンダード

代表的なコーディングスタンダードを紹介します.
・CERT Cコーディングスタンダード
・MISRA – C
・IPAコーディング作法

静的コード解析ツールも紹介します.
・Coverity
・LlocWork
・C++TEST
・cppCheck
・sparce


最後に

1年,2年,3年かかってでも,少しずつ身につけていきましょう.

tech