C LANGUAGE TECHNOLOGY

【C言語】制御文とは【if/else/while/do-while/for/switch/break/continue】

2021年6月30日

悩んでいる人

C言語の制御文を教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOS(Linuxカーネル)の授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
  • プログラミング歴15年以上,習得している言語: C/C++PythonSolidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開
  • 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
  • 最近は自然言語処理AIイーサリアムに関する有益な情報発信に従事.
    • (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
    • (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.

こういった私から学べます.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

制御文とは

制御文とは,プログラムを開発するためには,適切に実行を制御する文のことです.

プログラムを制御するとは,ある条件を元に文を実行するかどうか判定したり,繰り返し処理を実行して「プログラムの流れ」を変えることです.

具体的には,変数等を利用して条件式の真偽を判定して,条件分岐や繰り返し処理を実行します.

本記事では,以下の制御文を紹介します.

  • if文
  • if-else文
  • else-if文
  • while文
  • do-while文
  • for文
  • break/continue文

if文

if文は,ある条件をもとに次の文を実行するかどうかを判定します.

if文は多くのプログラミング言語で利用されているので,簡単に理解できます.

if文の書式

if文の書式は以下のようになります.

まず,式aを判断し,式aが真ならば文bを実行します.式aが偽ならば,文bは実行しません.

if文を利用するコード

if文を利用するコードは以下になります.

このコードは,2つの変数を読み込んで,その大小を比較するものです.

まず,int型の変数a,bを定義し,次に,それぞれの変数に値を読み込みます.

そして,if文で大小比較をして表示しています.

実行結果は以下になります.

3行目の行末で「3 2」と入力したら,4行目で「a = 3 is larger than b = 2.」と表示されます.

6行目の行末で「3 3」と入力したら,7行目で「a = 3 is equal to b = 3.」と表示されます.

9行目の行末で「3 4」と入力したら,10行目で「a = 3 is smaller than b = 4.」と表示されます.

複文

制御した文が2文以上ある場合は,その部分をカッコ{}で囲みます.

{}で囲まれた文は複文と呼ばれます.複文は,ひとかたまりで1つの文として扱われます.

C言語では,制御文はその次にくる1文のみを制御します.

したがって,複数の文を1度に制御したいときには,複文にしなければなりません.

複数の書式

複数の書式は以下になります.

if文で複数の文の制御

例えば,if文で複数の文を制御したい際には,以下のように記述します.

前述したコードでも複文を利用しています.

コーディングスタンダードにも関連しますが,if文等で使う時は複文にした方が無難です.

後で文を追加したり削除したりしたい時がよくありますので,その時に{}を追加したり削除したりするのは面倒ですよね.

また,防御的プログラミング(意図しないコードのバグから保護するプログラミング)の観点からも複文は有用です.

なので,if文の書式は複文を利用して以下のようになると覚えておきましょう.

ここで,Linuxカーネルは複文による防御的プログラミングをしていないことに注意して下さい.

Linuxカーネルを学びたいあなたはこちらからどうぞ.

if-else文

if-else文は,if文と同様に条件判断をする制御文です.

if-else文とif文の違いは,条件式が真の時と偽の時で実行する文がそれぞれ決まっていることです.

つまり,条件式が真の時だけ実行される文と,偽の時だけ実行される文があります.

if-else文の書式

if-else文の書式は,以下のようになります.

式aが真の時は,文bのみが実行されます.式aが偽の時は,文cのみが実行されます.

つまり,条件式が真か偽かにより,文bか文cのどちらか一方だけが実行されます.

if-else文を利用するコード

if-else文を利用するコードは以下になります.

このコードは,整数を入力して,偶数かどうかを判定します.

偶数は,2で割った余りが0ならば真,1ならば偽になります(14行目).

真の場合は15行目,偽の場合はelse文の17行目を実行します.

else-if文

else-if文は,ある条件を元に条件分岐する時等に利用するif文のバリエーションの1つです.

if文とif-else文,else-if文を使いこなすことで,複雑な条件式を書くことができます.

else-if文の書式

else-if文の書式は以下のようになります.

式aが真の時は文b,式cが真の時は文dのみが実行されます.

式aと式cがともに偽の時だけ,文eが実行されます.

このように,else-if文は,ある条件を元に多方向に分岐するのに適しています.

ここで,以下の部分は何回でも繰り返して書けます.

また,最後のelse文は省略することができます.

else-if文を利用するコード

else-if文を利用するコードは以下になります.

このコードは,1文字を入力して,その文字を小文字,大文字,数字,あるいはそれ以外であるかを判定します.

まず,9行目でint型の変数cを定義しています.

次に,11行目で入力を促すプロンプトを表示した後に,12行目でscanf関数を利用して1文字入力しています.

そして,14~22行目でif文とelse-if文,else文を利用して判定をしています.

この場合,scanf関数で文字入力をしているので判断もASCIIコードで行っています.

’a’のようにシングルクォーテーションで挟むと,aのキャラクターコード(ASCIIコード)を表します.

ASCIIコードは,’1’から’9’,’A’から’Z’,’a’から’z’まで連続的に1ずつ増えています.

このelse-if文のような比較で小文字,大文字,数字を区別できます.

実行結果は以下になります.

3行目の行末でc,6行目の行末でC,9行目の行末で3,12行目の行末で;を入力すると,それぞれ小文字,大文字,数字,それ以外と正しく判定していることがわかります.

while文

while文は繰り返し判定する制御文です.

ある条件を元に,以下の文を繰り返すかどうかを制御します.

これに対して,今まで出てきたif文,else-if文,else文は,基本的にはある条件を元に次の文を実行するかどうかを判定するので,1度だけしか実行されません.

while文の書式

while文の書式は,以下のようになります.

式aが真ならば文bが実行されます.

そして,また式aを判断します.

式aが真の間は文bが繰り返し実行され,式aが偽になるとwhile文から抜け出します.

while文では,式aが最初から偽の場合,文bは1度も実行されません.

while文を利用するコード

while文を利用するコードは以下になります.

まず,14行目のscanf関数でiの値を入力します.

16行目のwhile文で変数iとMAX_COUNT(値は10)とを比較します.

iがMAX_COUNT未満ならば17行目のprintf関数で変数iを表示して,インクリメントします.

実行結果は以下になります.

3行目の行末で0を入力したら,iの値が0になります.

まずwhile文が真になり,printf関数で「i = 0」と表示した後に変数iがインクリメントされて1になります.

10回ループした後でwhile文から抜け出し,while.cの20行目でループの外に出たということを表示します(14行目の「Out of the while loop. i = 10」).

また,16行目の行末で100を入力したら,iの値が100なのでwhile文を実行せずに「Out of the while loop. i = 100」のみを表示します.

do-while文

do-while文は,while文と同様に繰り返しを制御する制御文です.

while文では,繰り返しの判定を実行文の前に行いました.

do-while文とwhile文の違いは,do-while文では繰り返しの判定を実行文の後ですることです.

do-while文の書式

do-while文の書式は以下のようになります.

最初に,文aが実行されます.

その後に,式bが判定され,式bが真の時に文aが繰り返し実行されます.

式bが偽になるとループから抜け出ます.

while文と異なり,do-while文は文aが1度は必ず実行されます.

ここで,Python言語にはdo-while文がないので冗長なコードを書かなくてはならないこと,Ruby言語はloop break if文で対応することに注意して下さい.

Python/Ruby言語と比較して,C言語のdo-while文は簡潔でわかりやすいのが特徴です.

do-while文を利用するコード

do-while文を利用するコードは以下になります.

このコードはwhile.cのwhile文をdo-while文に書き換えたものです.

実行結果は以下になります.

iに0を入力した時は,while文と同様の結果です(3~14行目).

iに100を入力した時は,「i = 100」と表示した後に「Out of the do-while loop. i = 101」と表示します(16~18行目).

while文の時とは異なり,iの値が101にインクリメントされていることに注意して下さい.

do-while文とwhile文を比較するコード

do-while文とwhile文を比較するコードは以下になります.

実行結果は以下になります.

while文では条件が偽だったので,printf関数は実行しません.

これに対して,do-while文ではprintf関数を実行してThis is the do-while loop.」を表示した後に条件を判定して偽となり,ループから抜け出ます.

do-while文を利用する時は,1回目のループは必ず実行されるので,注意して下さい.

for文

for文は,while文と良く似た繰り返しを表す制御文です.

for文は,おそらくC言語エンジニアが最も利用するループでしょう.

for文の書式

for文の書式は以下のようになります.

最初に式aを実行します.

次に式bを判定し,真の場合に文cを実行します.

その後,式dを実行して,式bの判定に戻ります.

これを式bが偽になるまで繰り返します.

for文がなぜ繰り返し制御文の中で最も良く利用されるのかというと,ループの制御 (式a; 式b; 式d)を1行でコンパクトに記述できるからです.

for文の式は主に以下のように利用します.

  • 式a:制御変数の初期化
  • 式b:条件式
  • 式d:制御変数の更新

for文を利用するコード

for文を利用するコードは以下になります.

まず,9行目でint型の制御変数iを定義しています.

11行目のfor文の式aでは,ループの変数iを1に初期化しています.

この部分は,for文に入る時に1回だけ実行します.

そして,式bではi<=100が真かどうかの判定をしています.

最初はi==1で真なので文cを実行します.

12行目のprintf関数で変数iを出力します.

14~16行目のif文で,変数iが10で割り切れるなら改行します.

その後,式dを実行し変数iがインクリメントされます.

そして,再び式bの判定に戻り,変数iが100になるまで繰り返します.

変数iが101になるとループから抜け出ます.

実行結果は以下になります.

for文とwhile文の無限ループ

for文のカッコ()の中には必ずしも式を書く必要はありませんが,2つのセミコロン;は必ず書かなければなりません.

しかし,式aで制御変数を初期化したり,または式bが制御変数を利用した条件式であったりする必要はありません.

これらの式は,文法上の式なら何でも可能です.

式aがない場合は,すぐに式bの判定をします.

それ以外は普通のfor文と同じです.

式bがない場合は,式aを実行した後に,文cと式dを繰り返し実行する無限ループになります.

式dがない場合は式dの部分を何もしないだけで,それ以外は普通のfor文と同じです.

例えば,以下のように書くと無限ループになります.

条件判断の部分にも何も入っていないので,このループはループの抜け出る条件がありません.

for文の下の;というのは,空文といって何もしない文です.

つまり,このfor文を実行すると,何もしないことを延々と繰り返すプログラム(無限ループ)になります.

for文の無限ループをwhile文で書き換えると以下になります.条件式の場所に常に真になる0以外の値(例えば1)を入れます.

for文とwhile文の比較

一般的なfor文をwhile文に書き換えてみましょう.

上記のfor文は,以下のようなwhile文に書き換えることができます.

for文の式aは最初に1度だけ実行されるので,while文を実行する前に書きます.

ループを繰り返す条件は,for文とwhile文の両方とも同じなので,for文の式bはそのままwhile文の条件式になります.

for文では,文cを実行した後に式dを実行するので,while文の{}の中は,文c,式dの順番にします.

このようにすると,for文がwhile文に変換できます.

for文のコードをwhile文に書き換えたコード

上記のfor文のコードをwhile文に書き換えたコードは以下になります.

実行結果は以下になります.同じです.

for文とwhile文のどちらを利用するのかは好みの問題もあります.

for文で書ける繰り返しは,制御変数が一見して見やすく記述できるので,for文で書く方が好まれます.

少なくとも,回数が決まったループ等にはfor文を利用しましょう.

switch文

switch文は,ある1つの整数式を元に多方向に分岐する時に利用されます.

したがって,switch文で書けることはelse-if文で書くことができます.

switch文を利用すると,else-if文より簡潔にプログラムを書けます.

switch文の書式

switch文の書式は以下になります.

整数式aの値が定数c1に等しければ,文s1を実行します.

そして,文s2,文s3,文sdと順番に実行します.

式の値が定数c2に等しければ,文s2,文s3,文sdと順番に実行します.以下,同様です.

もし全ての定数と等しくなければdefault以下の文を実行します.

つまり,1度caseに飛ぶと,これ以降の文を順番に実行します.

switch文のカッコ()の中の条件式には,int型かchar型の整数式を入れます.

そして,caseの直後に式と等しいかどうかを比較する定数を書き,コロンを付けます.

定数はある確定値を持つ定数式であれば2+3とか’c’等でも構いません.

else-if文や他の制御文とは異なり,caseの直後は変数が利用できないことに注意して下さい.

コロンの後には,条件が真の時に実行する文を書きます.

また,defaultは,else-if文の最後のelseに相当するものです.

全てのcaseに当てはまらない場合はdefault以下の文を実行します.

else-if文の最後のelseと同様にdefaultは省略することができます.

switch文とbreak文をともに利用する書式

実際にはswitch文はbreak文とともに利用されることが多いです.

break文を実行すると,その時点でswitch文から抜け出ます.

switch文とbreak文をともに利用する書式は以下にようになり,else-if文と同様な制御構造になります.

整数式aが定数c1と等しい場合,文s1を実行します.

そして,break文でswitch文から抜け出ます.

整数式aが定数c2と等しい場合,文s2を実行してswitch文を抜け出ます.以下,同様です.

定数式aの値が,全ての定数と等しくなかった時に,default以下の文sdを実行します.

defaultのbreak文はなくても構いませんが,コーディングスタンダードとして入れることが多いので,基本的には入れるようにしましょう.

switch文を利用するコード

switch文を利用するコードは以下になります.

このコードは,数字を読み込み,その数字が0~9のいずれかであれば,その数字を英語で出力して終了します.

0から9までの数字でなければdefault以下の文が実行され,Errorと出力します.

実行結果は以下になります.

3行目の行末で3と入力したらThree,6行目の行末で10と入力したらErrorが表示されます.

switch文をelse-if文で書き換えたコード

switch文をelse-if文で書き換えたコードは以下になります.

switch.cのswitch文と良く見比べてみて下さい.

実行結果は以下になります.

switch文でbreak文がないコード

switch文でbreak文がないコードは以下になります.

このコードは,break文がある時とない時の動作の違いを比較するために,switch.cを元にbreak文がある場合とない場合に分けて書き直しました.

制御変数iを最初から1にして,どのように動くか見てみましょう.

実行結果は以下になります.

break文がない場合は,caseが真になったところから最後までの文が実行されていることが確認できました.

また,break文がある場合,caseが真になった部分の文だけを実行していることがわかりました.

break文とcontinue文

ループを制御する時に利用するbreak文とcontinue文を紹介します.

break文

break文は,switch文から抜け出る時に利用しましたが,もともとは最も内側のループから抜け出る時に利用します.

ネストした(入れ子になった)ループでは,break文を実行したループから抜け出るだけなので注意して下さい.

break文をfor文とif文で利用するコード

break文をfor文とif文で利用するコードは以下になります.

このコードは,0~10の数字を出力するものです.

このfor文は条件式がなく,このままでは無限ループになってしまいます.

しかし,for文の中のif文で制御変数iが10以上になった場合,printf関数を実行した後にbreak文を実行することで,このforループから抜け出ます.

実行結果は以下になります.

continue文

continue文を実行すると,その位置からループの最後までの文をスキップし,制御がループの先頭に戻ります.

ただし,continue文をfor文で利用する時は,式dを実行することに注意して下さい.

continue文をfor文とif文で利用するコード

continue文をfor文とif文で利用するコードは以下になります.

このコードは,1~100の数字を順番に画面に出力していき,数字が10の倍数の時に改行します.

10の倍数以外の時には直後にスペースを出力し,10の倍数の時には改行コードを出力した後にcontinue文を利用して,ループの先頭に戻ります.

実行結果は以下になります.

まとめ

C言語の制御文(if文,if-else文,else-if文,while文,do-while文,for文,switch文,break/continue文)を学びました.

また,制御文では複文を利用することで,防御的プログラミングができることがわかりました.

C言語の制御文には,一般的には禁じ手と呼ばれるgoto文があります.

goto文を学びたいあなたは,goto文が有用な3つの例外の記事を読みましょう.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

-C LANGUAGE, TECHNOLOGY
-, , , , , , , , , , , , ,