Do-while文

do-while文 () は、C言語および類似のプログラミング言語において繰り返し（ループ）の制御構造を記述するための文 (statement) のひとつである。C言語の規格では「do文」と呼ばれるJIS X 3010:2003「プログラム言語C」§6.8.5.2「do文」。ループ本体 (loop body) JIS X 3010:2003「プログラム言語C」§6.8.5「繰返し文」の処理を一度実行した後、さらに継続条件として指定された式（制御式）を評価した値が真である間、ループ本体を繰り返し実行する。while文との違いは、ループに入る前の条件の評価が無く最初に必ず1回はループ本体が実行されることである。

なお、C言語およびC++ではゼロに等しい値を偽、ゼロ以外を真とみなす。したがって、整数型だけでなく、任意のポインタ型や浮動小数点数型の式も制御式として記述可能である。C/C++以外のブーリアン型をサポートするほとんどの言語では通例、制御式にはブーリアン型の式のみを記述できる。

 構文 
C言語および類似の言語では以下のような構文である。
do
    文 /* ここの部分を「ループ本体」と呼ぶ */
while (条件);
このループの実行は、次のような手順となる。
 「文」を実行する。
 「条件」を評価する。
 「条件」が真ならば、手順の最初に戻る。「条件」が偽ならば、ループを終了する。
「条件」がはじめから偽の場合も、「文」は一度実行される。

ループ本体が複数の文からなる場合、ブロック（複文）を使う。
do {
    ...
} while (条件);

C言語のプログラム例:
int x = 0;
do {
    x += 1;
} while (x < 3);

この例では、最初に x += 1 を実行し x == 1 となる。次に条件の x < 3 をチェックする。条件は真であり、コードブロックを再度実行する。変数 x がループ脱出条件に合致する（x >= 3 になる）まで、コードの実行と条件のチェックを繰り返す。

C言語に似ていない言語では、異なった構文で同様の機能を持つものもある（while文の記事も参照）。例えばPascalでは、"repeat-until" 文である。ただし、制御式として継続条件ではなく終了条件（真のときループを終了）を記述する。

なお、Fortran (Fortran 90以降) にもdo-while文はあるが、これはC言語のwhile文と同等であり、制御式を前置する。以下の例では、ループ本体は一度も実行されない。
program TEST
    integer x
    data x /0/
    do while (x > 0)
        print *, x
        x = x - 1
    end do
    print "('Finished. x = ', i0)", x
end

 分岐文 
while文と同様、do-while文においてもbreak文などの分岐文を使用できる。なお、continue文はループの途中から、ループ本体の最後に飛びJIS X 3010:2003「プログラム言語C」§6.8.6.2「continue文」、do-while文の場合には条件の評価となる。

 例 
以下の、各言語によるdo-while文あるいは同様の制御を利用したプログラムは、与えられた数の階乗を計算する。

 Ada 
Adaの例。
with Ada.Integer_Text_IO;

procedure Factorial is
   Counter   : Integer := 5;
   Factorial : Integer := 1;
begin
   loop
      Factorial := Factorial * Counter;
      Counter   := Counter - 1;
      exit when Counter = 0;
   end loop;

   Ada.Integer_Text_IO.Put(Factorial);
end Main;

 Visual Basic .NET 
Visual Basic .NETの例。
Dim counter As UInteger = 5
Dim factorial as ULong = 1
Do
  factorial *= counter ' multiply
  counter -= 1 ' decrement
Loop While counter > 0
System.Console.WriteLine(factorial)

 C言語とC++ 
C言語とC++の例。
unsigned int counter = 5;
unsigned long factorial = 1;
do {
  factorial *= counter--; /* Multiply, then decrement. */
} while (counter > 0);
printf("%lu\n", factorial);

 C# 
C#の例。
uint counter = 5;
ulong factorial = 1;
do
{
    factorial *= counter--;
}
while (counter > 0);
System.Console.WriteLine(factorial);

 D言語 
D言語の例。
uint counter = 5;
ulong factorial = 1;
do {
    factorial *= counter--;
} while (counter > 0);
writeln(factorial);

 Java 
Javaの例。
int counter = 5;
long factorial = 1;
do {
  factorial *= counter--; // Multiply, then decrement.
} while (counter > 0);
System.out.println(factorial);

 Pascal 
Pascalの例。
program FactorialProgram;
var
  counter, factorial: Integer;
begin
  counter := 5;
  factorial := 1;

  repeat
    factorial := factorial * counter;
    counter := counter - 1;
  until counter = 0;

  Write(factorial);
end.

 C/C++のマクロにおける利用 
C/C++におけるdo-while文の特殊な用法に、最後にセミコロンが付く構文であることを利用し、展開結果にブロックを含むマクロの呼び出しを関数のように見えるものにする、というイディオムがある。
/* 2つの値 x, y を入れ替えるマクロ。 */
#define SWAP(x, y, tmp) do { (tmp) = (x); (x) = (y); (y) = (tmp); } while (0)

/* 以下のように書いてしまうと、セミコロンを付けた場合にコンパイルが通らなくなるケースがある。 */
/*
#define SWAP(x, y, tmp) { (tmp) = (x); (x) = (y); (y) = (tmp); }
*/

void some_function()
{
    int x, y, tmp;
...
    if (x > y)
        SWAP(x, y, tmp);
    else
        puts("Not swapped.");
...
}

これを利用することで、「セミコロンを付けてはいけないマクロ」という、扱いが面倒なものを作らずにすむPRE10-C. 複数の文からなるマクロは do-while ループで包む。

 脚注 

 注釈 

 出典 

 関連項目 
 while文
 for文

 外部リンク 


Category:コンピュータ言語の文
Category:制御構造