チームでプログラムを作成する場合、メンバーがプログラムを読み易いように、 インデンテーション(字下げ)に関して一定のルール(約束事)を設ける。
Visual Studio Code (VSC) にも自動的にインデンテーションする機能 (右クリックして「Format Document」あるいは Shift+Alt+F)がある。 ただし、VSC の自動インデンテーションのデフォルトの設定は、 特に開きブレースの位置が以下に挙げる約束事とは異なる。
そこで開きブレースの位置を変えるために、setting.json
に次の項目を追加する。
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, IndentWidth: 4}",
つまり Ctrl-,
(Mac では command-,
)で「設定」(Settings) というタブを開き、「設定の検索」(Search settings) に「C_Cpp.clang_format_style
」と入力して、
見つかった項目を(はじめは「file
」になっているはずだが、これを消して)「{BasedOnStyle: Google, IndentWidth: 4, UseTab: Never}
」 に変更する。これでこのページに挙げる約束事とほぼ一致するインデンテーションになる。
(すこし長いが「{BasedOnStyle: Google, IndentWidth: 4, UseTab: Never, AllowShortBlocksOnASingleLine: Empty, AllowShortCaseLabelsOnASingleLine: true, AllowShortIfStatementsOnASingleLine: WithoutElse, AllowShortLoopsOnASingleLine: false, AllowShortFunctionsOnASingleLine: Empty, BreakStringLiterals: false}
」
とすると、さらに約束事のなかの例外的事項にも対応する。)
(2023/11/15)BreakStringLiterals: false
を追加
(2023/11/29)AllowShortLoopsOnASingleLine: false
に変更 (2023/12/20)AllowShortFunctionsOnASingleLine: Empty
を追加
インデンテーションと関係ないが、設定のついでに、デフォルトの文字コードも変更しておこう。
やはり Ctrl-,
(Mac では command-,
)で「設定」(Settings) というタブを開き、
「設定の検索」(Search settings) に「Files: Encoding
」と入力して、見つかった項目を「UTF-8 with BOM
」に変更する。
「プログラミング」では、 課題で提出するプログラムのインデンテーションに関して次のような約束事を採用する。 (5番目の約束事以外は、 教科書で採用されている約束事と概ね同じである。)
原則として、一行には文は一つしか書かない。 ただし、次の例のように密接に関連している文の場合はこの原則にこだわる必要はない。
プロンプト(入力をうながすメッセージ)を出力する printf
文と scanf
文
原則通り | 許容範囲内 |
printf("整数を入力してください: "); scanf("%d", &n); |
printf("整数を入力してください: "); scanf("%d", &n); |
関連する変数への代入文
原則通り | 許容範囲内 |
x = 2; y = 3; |
x = 2; y = 3; |
(switch
文のなかで)case 〜:
や default:
から break;
の間に 1 文しかない場合、
原則通り | 許容範囲内 |
switch (…) { case 1: printf(…); break; case 2: printf(…); break; … } |
switch (…) { case 1: printf(…); break; case 2: printf(…); break; … } |
ブレース({
〜 }
)の中の文は、外よりも 4
または 8 字分を字下げする。
ただし、首尾一貫した文字数であれば、4 や 8 という数字にこだわる必要はない。(ただ、1 字は少なすぎる …)
良い | 悪い | 悪い |
if (n1 > n2) { max = n1; min = n2; } |
if (n1 > n2) { max = n1; min = n2; } |
if (n1 > n2) { max = n1; min = n2; } |
ただし、case 〜:
や default:
などのラベルは字下げしない。(または 1 字だけ、あるいは通常の半分程度字下げする。)
一つのファイルで空白文字とタブ文字を混ぜない。 (タブ文字を使わずに空白文字だけで字下げする。 あるいは空白文字を使わずにタブ文字だけで字下げする。)
同じ文字列でも… |
タブサイズ 4 の場合 (Notepad ++, サクラ など) |
タブサイズ 8 の場合 (ブラウザーのデフォルト、メモ帳、Emacs など) |
int main(void) { printf("hello"); printf("hello"); return 0; } |
エディターの設定で、「タブをスペースに変換して挿入」というチェック項目が大抵のエディターにあるはず。 (MkEditor の場合、 VxEditor の場合)
タブ文字を使った場合は、8 字分の空白と解釈する。
自分の使っているエディターでタブの設定方法がわからない場合は、 ソースファイルを「メモ帳」または Web ブラウザーで開いて確認する。
開きブレース({
)は if
や else
, switch
, do
, while
, for
などのキーワードと
同じ行に改行せずに書く。開きブレースのあとは何も書かず改行する。
良い | 悪い | 悪い |
if (n1 > n2) { max = n1; min = n2; } |
if (n1 > n2) { max = n1; min = n2; } |
if (n1 > n2) { max = n1; min = n2; } |
閉じブレース(}
)は対応する if
や switch
,
do
, while
, for
などのキーワードのはじめの文字と列をそろえて書く。
その行には閉じブレース以外には何も書かない。
良い | 悪い | 悪い |
if (n1 > n2) { max = n1; } else { max = n2; } |
if (n1 > n2) { max = n1; } else { max = n2; } |
if (n2 > max) { max = n2; } if (n3 > max) { max = n3; } |
ただし、else
… や do
〜 while
文の while
…
は閉じブレース(}
)と同じ行に続けて書く。(else
や do
〜 while
文の while
は、新しい文の始まりではないことに注意する。)
良い | 悪い |
if (n1 > n2) { max = n1; } else { max = n2; } |
if (n1 > n2) { max = n1; } else { max = n2; } |
do { printf("%d ", n++); } while (n < no); |
do { printf("%d ", n++); } while (n < no); |
(鉄の掟)
if
文, if
〜 else
文 や for
文,
while
文, do
〜 while
文などでは、
選択されたり、繰り返したりされる文が一つだけの場合も、
ブレース({
〜}
)に囲む。
この約束事だけは、 教科書のプログラム例は必ずしも従っていないので、 特に注意する。(教科書 p.61 の ▶ の部分を参照)
良い | 悪い |
if (n >= 60) { count++; } |
if (n >= 60) count++; |
if (n1 > n2) { max = n1; } else { max = n2; } |
if (n1 > n2) max = n1; else max = n2; |
while (n1 < n2) { printf("%d ", n1++); } |
while (n1 < n2) printf("%d ", n1++); |
for (int i = 0; i < n ; i++) { printf("%d ", i); } |
for (int i = 0; i < n ; i++) printf("%d ", i); |
do { printf("%d ", i++); } while (i < n); |
do printf("%d ", i++); while (i < n); |
ただし、else
の対象が一つの if
文の場合の
else if …
というかたちは、 else { if … }
とはしない。
良い | 悪い |
if (n > 0) { printf("正です。\n"); } else if (n == 0) { printf("0 です。\n"); } else if (n == -1) { printf("-1 です。\n"); } else { printf("-2 以下です。\n"); } |
if (n > 0) { printf("正です。\n"); } else { if (n == 0) { printf("0 です。\n"); } else { if (n == -1) { printf("-1 です。\n"); } else { printf("-2 以下です。\n"); } } } |
例外的に、(else を伴わず、else if という形でも現れない if 文の対象が)とても短い文で敢えてブレースに囲まない場合(if
の対象となる文を追加するということが考えにくい、イディオム的なカタチの場合)は、改行せず、
if
と同じ行に書いても許容される。
原則通り | 許容範囲内 |
max = n1; if (n2 > max) { max = n2; } if (n3 > max) { max = n3; } |
max = n1; if (n2 > max) max = n2; if (n3 > max) max = n3; |
(2023/11/29) 例外は else のない if 文だけが対象であることを明示
関数の定義は1列めから書きはじめる。
関数本体の開始を表す開きブレース({
)は、関数頭部のあとに続けて改行せずに書くか、
改行して 1 列めに書く。
関数本体の最後を表す閉じブレース(}
)は、1 列めに書く。
良い | 良い | 悪い |
int main(void) { printf("hello\n"); return 0; } |
int main(void) { printf("hello\n"); return 0; } |
int main(void) { printf("hello\n"); return 0; } |
(コメントの中の数字は、上記の約束事の番号)
4 字の字下げを採用した場合
int main(void) { /* ← 6, { は次の行の1列目でもよい */ int i, j; /* ← 1 */ for (i = 0; i < 10; i++) { /* ← 3 */ for (j = 0; j < 10; j++) { /* ← 1 */ printf("*"); /* ← 5 */ } /* ← 4 */ printf("\n"); /* ← 1 */ } /* ← 4 */ return 0; /* ← 1 */ } /* ← 6 */
8 字の字下げを採用した場合
int main(void) { /* ← 6, { は前の行でもよい */ int i, j; /* ← 1 */ for (i = 0; i < 10; i++) { /* ← 3 */ for (j = 0; j < 10; j++) { /* ← 1 */ printf("*"); /* ← 5 */ } /* ← 4 */ printf("\n"); /* ← 1 */ } /* ← 4 */ return 0; /* ← 1 */ } /* ← 6 */