「C言語/制御文」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
→‎無限ループ: scanf/scanf_sの戻り値は EOF の可能性があり、無視すると無限ループに陥る。
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
463 行
 
== 繰り返し文 ==
繰り返し文( ''iteration statement'' ; より一般的には反復文)は、制御式( ''controlling expression'' )の0との比較が一致するまで、ループ本体( ''loop body'' )と呼ばれる文を繰り返し実行します<ref name="jtc1-sc22-wg14-n2596-6.8.5">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 125, §6.8.5 ''Iteration statements''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref>。
繰り返し文はブロックで、そのスコープは、そのブロックを囲むブロックのスコープの狭義の部分集合( ''strict subset'' )です。
ループ本体もまた、繰り返し文のスコープの狭義の部分集合をスコープとするブロックです。
繰り返し文は、その制御式が定数式ではなく、本体、制御式、(for文の場合)式-3で以下の操作が行われていない場合、実装上は終了するとみなすことができます。
 
構文
iteration-statement:
[[#while文|while]] ( expression ) statement
[[#do-while文|do]] statement while ( expression ) ;
[[#for|for]] ( expression<sub>opt</sub> ; expression<sub>opt</sub> ; expression<sub>opt</sub> ) statement
[[#for|for]] ( declaration expression<sub>opt</sub> ; expression<sub>opt</sub> ) statement
※最後のfor文の構文は ; が不足しているように見えますが、declaration(宣言)は文で末尾に ; を含むので不足してはいません。
 
=== while文 ===
while文( while statment )では、制御式の評価は、ループ本体の各実行前に行われます<ref name="jtc1-sc22-wg14-n2596-6.8.5.1">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 125, §6.8.5.1 ''The while statement''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref>。
<!-- C99 の 6.8.5.1 The while statement には The evaluation of the controlling expression takes place before each execution of the loop body.としか書かれていない。
<ref>『JISX3010:2003』p.102「6.8.5.1 while文」</ref>
while文とは、繰り返し文の内の1つであり、式(制御式)の論理値が真である間、指定する文(ループ本体)の実行を繰り返す。
469 ⟶ 492行目:
while文では、制御式の論理値の評価は、ループ本体の各実行の前に行われる。
while文では、制御式の論理値があらかじめ偽であれば、ループ本体は1度も実行されない。
-->
;形式:<syntaxhighlight lang="C">
while ( 式 )
</syntaxhighlight>
 
;while文の記述は次のようになっている。使用例:<syntaxhighlight lang="C">
#include <stdio.h>
*while文
 
<syntaxhighlight lang="C">
int main(void) {
while(式)
int i = 0;
while (i < 5) {
printf("%d ", i);
i++;
}
//「0 1 2 3 4 」と表示される。
}
</syntaxhighlight>
 
=== do-while文 ===
{{Anchor|do文}}( do statement )では、制御式の評価は、ループ本体の各実行後に行われます<ref name="jtc1-sc22-wg14-n2596-6.8.5.2">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 125, §6.8.5.2 ''The do statement''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref>。
<!--
<ref>『JISX3010:2003』p.102「6.8.5.2 do文」</ref>
do-while文とは、繰り返し文の内の1つであり、式(制御式)の論理値が真である間、指定する文(ループ本体)の実行を繰り返す。
do-while文には、制御式と、ループ本体が含まれる。
do-while文では制御式の論理値の評価は、ループ本体の各実行の後に行われる。
do-while文では、制御式の論理値にかかわらず、ループ本体は少なくとも1度は実行される。
-->
;形式:<syntaxhighlight lang="C">
do
while ( 式 ) ;
</syntaxhighlight>
 
;do文の使用例:<syntaxhighlight lang="C">
#include <stdio.h>
//例 while文の使用例
#include<stdio.h>
 
int main(void) {
int i = 0;
{
do {
int i=0;
printf("%d ", i);
while(i<5){
i++;
printf("%d ",i);
} while (i < 5);
++i;
//「0 1 2 3 4 」と表示される。
}
}
//「0 1 2 3 4」と表示される。
</syntaxhighlight>
 
=== for文 ===
for文( ''for statement'' )
 
;文:<syntaxhighlight lang="text">
for (句-1; 式-2; 式-3) 文
</syntaxhighlight>
は次のように動作します<ref name="jtc1-sc22-wg14-n2596-6.8.5.3">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 125, §6.8.5.3 ''The for statement''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref><ref>『JISX3010:2003』p.102「6.8.5.3 for文」</ref>。
: 式-2は、ループ本体の各実行前に評価される制御式です。
: 式-3は、ループ本体の各実行後にvoid式として評価されます。
: 句-1が宣言の場合、宣言で宣言された識別子のスコープは、宣言の残りの部分と、他の2つの式を含むループ全体で、制御式の最初の評価の前に実行順に到達します<ref>句-1で、宣言が行えるようになったのはC99からです。</ref>。
: 句-1が式の場合、制御する式の最初の評価の前にvoid式として評価されます。
: 句-1と式-3の両方が省略可能です。
; 省略された式-2は、非ゼロの定数によって置き換えます。
 
;for文の使用例:<syntaxhighlight lang="C">
#include <stdio.h>
 
int main(void) {
for (int i = 0; i < 5; i++)
printf("%d ", i);
//「0 1 2 3 4 」と表示される。
}
</syntaxhighlight>
 
==== for文のネスト ====
for文の中にfor文を入れることを、ネストまたは入れ子という。
;for文のネストの使用例。九九を表示する。:<syntaxhighlight lang="C">
#include <stdio.h>
 
int main(void) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
printf("%2d ", i * j);
}
printf("\n");
}
return 0;
}
</syntaxhighlight>
 
==== 無限ループ ====
無限ループとは、文の実行が無限に繰り返されることです。
{| class="wikitable"
573 ⟶ 668行目:
 
なお、文字変数の中身を示す「'y'」のように、文字リテラルは ' (シングルクォーテーションマーク)で囲みます。文字列リテラルを囲む " (ダブルクォーテーションマーク)と間違えないうようにしましょう<ref>生徒に教えていると、" であるべきところを '' と書いているパターンのほうが多く、また発見が遅れます。</ref>。
 
=== do-while文 ===
<ref>『JISX3010:2003』p.102「6.8.5.2 do文」</ref>
do-while文とは、繰り返し文の内の1つであり、式(制御式)の論理値が真である間、指定する文(ループ本体)の実行を繰り返す。
do-while文には、制御式と、ループ本体が含まれる。
do-while文では制御式の論理値の評価は、ループ本体の各実行の後に行われる。
do-while文では、制御式の論理値にかかわらず、ループ本体は少なくとも1度は実行される。
 
do-while文の記述は次のようになっている。
*do-while文
<syntaxhighlight lang="C">
do
while(式);
</syntaxhighlight>
 
<syntaxhighlight lang="C">
//例 do-while文の使用例
#include<stdio.h>
 
int main(void)
{
int i=0;
do{
printf("%d ",i);
++i;
}while(i<5);
//「0 1 2 3 4」と表示される。
}
</syntaxhighlight>
 
=== for文 ===
<ref>『JISX3010:2003』p.102「6.8.5.3 for文」</ref>
for文(フォアぶん)とは、繰り返し文の内の1つであり、始めに初期化式を実行し、前実行式の論理値が真である間、「前実行式、文、後実行式」の順に繰り返す。
 
英語における「for」は、英語の前置詞(ぜんちし)というものの一つです。中学校でまだ前置詞を習ってない人は、わからなくても気にしないでください。
 
さてプログラミングにおけるfor文は、「;(セミコロン)」で区切られた、初期化式、前実行式(制御式、継続条件式とも呼ばれる)、後実行式、及びループ本体と呼ばれる文からなる。
 
初期化式では宣言を行ってもよい。
 
3つの式はいずれとも省略してもよい。前実行式を省略した場合、0でない定数(真)によって置き換えられる。
for文は、初期化及び後実行を形式的に記述する点でwhile文と異なっている。
一般に、初期化式では変数の初期化を、前実行式では変数に対する継続条件を、後実行では変数の増分または減分を、それぞれ行う。
 
for文の記述は次のようになっている。
* for文
<syntaxhighlight lang="C">
for(初期化式; 前実行式; 後実行式)
</syntaxhighlight>
 
<syntaxhighlight lang="C">
//例 for文の使用例
#include<stdio.h>
 
int main(void)
{
int i;
for (i = 0; i < 5; i++)
printf("%d ",i);
//「0 1 2 3 4」と表示される。
}
</syntaxhighlight>
 
==== for文のネスト ====
for文の中にfor文を入れることを、ネストまたは入れ子という。
<syntaxhighlight lang="C">
// 例 for文のネストの使用例。九九を表示する。
#include<stdio.h>
 
int main(void)
{
int i, j;
for (i = 1; i <= 9; i++) {
for(j = 1; j <= 9; j++) {
printf("%2d ", i*j);
}
printf("\n");
}
return 0;
}
</syntaxhighlight>
 
 
== 分岐文 ==