LoginSignup
4
1

More than 3 years have passed since last update.

センスの悪いコード

Posted at

コーディングセンス

コーディングにセンスはあるだろうか。
最適なアーキテクチャを選ぶことだろうか。
テスタビリティ、変更容易性の高いコードを書くことだろうか。
とにかく速くコードを書くことだろうか。

人によって様々あると思うが、
リーナス・トーバルズにとってセンスのある人とは、
大きく見て直感で正しいコードがわかる人らしい。
image.png

たとえば、あるif文の特殊ケースを一般化できると見破ることができる人のことである。
次の例は上記動画で紹介されたコード片を動くコードに変えたものだ。

 #include "common.h"

 typedef struct linked_list
 {
     int value;
     struct linked_list* nextp;
 } linkedlist;

 linkedlist* firstlistp = NULL;

 void initList(int value);
 void addList(int value);
 linkedlist* findList(int value);
 void deleteList(linkedlist* entry);
 void printList();

 int main()
 {
     initList(11);
     addList(12);
     addList(13);
     addList(14);
     addList(15);
     addList(16);
     addList(17);
     printList();

     puts("TEST A");

     linkedlist* lp = findList(14);
     deleteList(lp);
     printList();

     puts("TEST B");

     lp = findList(12);
     deleteList(lp);
     printList();

     puts("TEST C");

     lp = findList(16);
     deleteList(lp);
     printList();

     puts("TEST D");

     return 0;
 }

 void initList(int value)
 {
     linkedlist* newp;
     newp = malloc(sizeof(linkedlist));
     newp->value = value;
     newp->nextp = NULL;
     firstlistp = newp;
 }

 void addList(int value)
 {
     linkedlist* newp;
     newp = malloc(sizeof(linkedlist));
     newp->value = value;
     newp->nextp = firstlistp;

     firstlistp = newp;
 }

 linkedlist* findList(int value)
 {
     linkedlist* currentp;
     currentp = firstlistp;

     while((currentp != NULL) && (currentp->value != value))
     {
         currentp = currentp->nextp;
     }

     return currentp;
 }

 #define BAD

 void deleteList(linkedlist* entryp)
 {
 #ifdef BAD
     linkedlist* prevp = NULL;
     linkedlist* walkp = firstlistp;

     while(walkp != entryp)
     {
         prevp = walkp;
         walkp = walkp->nextp;
     }

     if(!prevp)
     {
         firstlistp = entryp->nextp;
     }
     else
     {
         prevp->nextp = entryp->nextp;
     }
 #else
     linkedlist** indirectpp = &firstlistp;

     while((*indirectpp) != entryp)
         indirectpp = &(*indirectpp)->nextp;
     *indirectpp = entryp->nextp;
 #endif

     free(entryp);
 }

 void printList()
 {
     linkedlist* currentp = firstlistp;
     while(currentp != NULL)
     {
         printf("%d\n", currentp->value);
         currentp = currentp->nextp;
     }
 }

紹介されたのはdeleteList関数。
BADルートとelseルートの違いはif文がないこと.
特殊ルートが消えて一般化された。

可読性

コード品質の話をするとき、可読性の話題が上がる。
BADコードは読みやすいだろうか。
もしレビューでこのコードが出てきたら、BADコードを選ぶかもしれない。
すくなくても私の職場ではそうだと思う。

センスの悪いコード

ある機能を実現するにあたって方法が多数あることがほとんどだと思う。
議論にでてくるのは実行速度、可読性、拡張容易性などだろう。
実行速度は計測できるので、より速いより遅いは客観的に判断できるが、
可読性は人によって見方が違うし、拡張容易性もどこが変更されるかわからない以上限界がある。
どこまで設定ファイルに依存するかも関わってくる。
センスの良い悪いは状況によるかもしれない。
だが、それぞれの状況に対してセンスの良いコードは存在している。
リーナスさんが言っているのはコードのコードの良し悪しがあり、それを直感でわかる人がいるということ。
難しい。

余談

何を言いたいのか考えずに書き始めたらたら結局最後までわからず、結論のない記事になってしまった。
私にはコーディングのセンスも文章のセンスもないらしい。
C言語入門以来にリンクリストを書いた。今まで業務で自分で書くことはなかった。
で、久しぶりに書いたけど、リンクリスト結構難しいと思う。
処理的にこれより難しいものはあるけど、プログラム初心者が書くにはハードルが高いと思った。
追加するときに手前に追加するという概念、削除関数の処理この2個のハードルが高い。
やればできるし、間違ったらすぐSEGVするからデバッグしやすいし、良い振るいとしては機能しているのかもしれない。

初心に返って絵を書きながらコーディングしたら、誰もわからない絵になった。私には絵のセンスもないのか。。。

image.png

4
1
0

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
4
1