わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

インデントしよう!(2017年度版)

いきなりですが問題です.2重ループのインデントについて,(1)と(2)のどちらが読みやすいでしょうか.

  /* (1) */
  for (i = 0; i < 5; i++) {
    for (j = 0; j < 5; j++) {
  /* (2) */
  for (i = 0; i < 5; i++) {
  for (j = 0; j < 5; j++) {

さっそくですが解答です.Cに慣れたら,(1)のほうが読みやすいに決まっています.
(2)は,まずiのループがあって,続いてjのループと並ぶため,初学者にとっては分かりやすいのかもしれません.ですが,あとの処理を書いていき,2つの「{」に対応する2つの「}」を書くとなると,どうすればいいでしょうか.次の書き方だと,インデントをしていないも同然です.

  for (i = 0; i < 5; i++) {
  for (j = 0; j < 5; j++) {
  printf("%d", i + j);
  }
  printf("\n");
  }

少しだけ工夫して,次のように書いたとします.

  for (i = 0; i < 5; i++) {
  for (j = 0; j < 5; j++) {
    printf("%d", i + j);
    }
  printf("\n");
  }

これでも,行数が増えてくると,「}」は,どれに対応する「{」なのかが,すぐには分からなくなります.
それに対し,(1)をもとにインデントを行うと,以下のようになります.

  for (i = 0; i < 5; i++) {
    for (j = 0; j < 5; j++) {
      printf("%d", i + j);
    }
    printf("\n");
  }

こう書けば,jのforループから,改行を出力するまでの,4行分が,iのforループの中で行う処理というのが一目瞭然です.そしてiとjの和を出力する処理だけが,jのforループの処理となります.
このようにインデントするためのルールは,次の2つです.まず,行末に「{」を書いたら,その次の行から,インデントレベルを1つ,下げます.そして,(インデントは無視して)「}」から始まる行*1を書くときは,その行から,インデントレベルを1つ,上げます.
ここで,レベルを下げるというのは,より深くインデントするということです.上記のコード例では,空白2文字分が,1レベル分となります.レベルを上げるのは,逆の操作です.
適切なテキストエディタまたは統合開発環境なら,自動でインデントしてくれますが,Windowsの「メモ帳」や,Linuxのgeditで編集する際には,手動でインデントする必要も出てきます.
なお,astyleというコマンドが使えるのなら,オプションをつけて実行することで,ソースファイルを上書き(または別のファイルに保存)して,インデントを一貫したものにしてくれます.自分の授業で使用しているスタイルは,astyle -A3 -s2となります.このコマンドの詳細はArtistic Style(AStyle) — Algo13より読むことができます.
なお,astyleコマンドにも言及した「インデントしよう!」の記事は,昨年,12月に,作成していました*2

*1:「}」のみの行,ではありません.多次元配列を宣言して初期化する際に,「};」という行を書くこともあります.

*2:http://d.hatena.ne.jp/takehikom/20161202/1480690799