Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語のsetjmp()とlongjmp()を徹底解説!例外処理と非ループ処理の実装方法

この記事では、C言語におけるsetjmp()longjmp()について詳しく解説します。これら2つの関数はsetjmp.hヘッダーファイルに定義されており、それぞれ以下のような構文で使用します。

setjmp(jmp_buf buf) : 現在の実行位置をbufに保存し、最初の呼び出し時には0を返す。
longjmp(jmp_buf buf, i) : bufが指し示す位置へ制御を戻し、iを返す。

これらの関数は、C言語で例外処理を実現するために活用されます。JavaやC++などの言語にあるtry-catch構文と同様の役割を果たし、setjmp()はtryブロックのように、longjmp()はthrow文のように動作します。longjmp()が呼び出されると、プログラムの制御はsetjmp()が記録した位置へ一気に移ります。

ループや再帰を使わずに数字を100回表示する

それでは実際の例として、「再帰・ループ・マクロ展開を一切使わずに、ある数字を100回表示する」という課題を考えてみましょう。これはsetjmp()longjmp()を組み合わせることで実現できます。

サンプルコード

#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
main() {
    int x = 1;
    setjmp(buf); // bufを使ってジャンプ位置を設定
    printf("5"); // 数字を表示
    x++;
    if (x <= 100)
        longjmp(buf, 1); // setjmpが記録した位置へジャンプ
}

実行結果

555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555

※「5」が合計100個連続して出力されます。

プログラムの仕組み

このコードの動作を順を追って見ていきましょう。

  1. setjmp(buf):まず最初に呼び出された時点で、現在の実行位置がbufに保存されます。この時の戻り値は0です。
  2. printf("5"):数字「5」を標準出力に表示します。
  3. x++:カウンタ変数xの値を1つ増やします。
  4. longjmp(buf, 1)xがまだ100以下であれば、bufに保存された位置(setjmp()の呼び出し箇所)へ制御がジャンプします。この時、setjmp()の戻り値は1になります。

この流れがxが100になるまで繰り返されるため、結果として「5」がちょうど100回表示される仕組みです。通常、繰り返し処理にはfor文やwhile文などのループ構文が必要ですが、setjmp()/longjmp()による制御のジャンプを利用すれば、ループ構文を使わずに同等の処理を実装できるのです。

まとめ

setjmp()longjmp()は、C言語において関数をまたいだ制御のジャンプを可能にする強力な機能です。例外処理的な挙動を実現したり、本記事のように特殊な繰り返し処理を実装したりすることができます。ただし、可読性や保守性の観点から乱用は避け、用途を理解した上で適切な場面で使用することが重要です。

  1. UEFIとは?Windows 8におけるUEFIのメリットと設定画面へのアクセス方法を解説

    本記事では、UEFIの基本概念と、Windows 8におけるこの技術の活用方法について詳しく解説します。 UEFIとは何か? UEFIは「Unified Extensible Firmware Interface(統一拡張ファームウェアインターフェース)」の略称です。この技術は従来のコンピューターのブートシステムを刷新するために設計され、旧式化したBIOSシステムに取って代わるものです。しかし、単なる旧技術の近代化ではなく、OSやコンピューターの起動技術に対する根本的に新しいアプローチと言えます。実際、UEFIはPCのBIOSシステムとはほとんど共通点がありません。 BIOSがシステム基板上の

  2. Pythonで3の倍数と7の倍数の組み合わせで数値nを作れるか判定する方法

    ある正の整数 n が与えられたとき、その n を「3の非負の倍数」と「7の非負の倍数」の合計として表すことができるかどうかを判定する問題を考えてみましょう。例えば、入力が 13 の場合、出力は True になります。なぜなら、13 = 1×7 + 2×3 と表せるからです。解法のアプローチこの問題は、次の手順で解くことができます。i を 0 から n+1 まで、7 ずつ増やしながら繰り返します。各 i について、(n − i) が 3 で割り切れるかどうかを確認します。割り切れる場合は True を返します。ループを最後まで回っても条件を満たさなかった場合は、False を返します。このアルゴ