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

C++のexternストレージクラスとは?使い方と注意点を解説

externストレージクラスとは

externストレージクラス指定子は、複数のソースファイルから利用できるオブジェクトを宣言するための機能です。extern宣言を行うと、その変数は現在のソースファイルの以降の部分で使用可能になります。ただし、この宣言は定義を置き換えるものではありません。extern宣言は、別の場所(外部)で定義されている変数を記述するために使われます。

extern宣言の記述位置と省略ルール

extern宣言は、関数の外側またはブロックの先頭に記述できます。宣言が関数を表す場合や、関数の外側にあって外部リンケージを持つオブジェクトを表す場合は、externキーワードを省略することも可能です。

また、同じ識別子に対する宣言がすでにファイルスコープに存在する場合、ブロック内で見つかった同じ識別子のextern宣言は、その同一オブジェクトを参照します。逆に、ファイルスコープに他の宣言が存在しない場合は、その識別子は外部リンケージを持つことになります。

C++におけるexternの制限

C++では、externストレージクラス指定子の使用はオブジェクト名または関数名に限定されています。型宣言にextern指定子を付けることは不正であり、コンパイルエラーとなります。さらに、extern宣言をクラススコープ内に記述することもできません。

externを使った変数の共有例

externキーワードを活用すると、次のように複数のファイル間で変数を共有できます。

file3.h

extern int global_variable; /* 変数の宣言 */

file1.c

#include "file3.h"  /* ここで宣言が利用可能になる */
#include "prog1.h"  /* 関数の宣言 */

/* 変数はここで定義される */
int global_variable = 37;  /* 定義が宣言と照合される */

int increment(void) {
    return global_variable++;
}

file2.c

#include "file3.h"
#include "prog1.h"
#include <stdio.h>

void use_it(void)
{
    printf("Global variable: %d\n", global_variable++);
}

この例では、ヘッダーファイル「file3.h」でextern宣言を行い、各ソースファイルからそのヘッダーをインクルードすることで、同一のグローバル変数を共有しています。実際の定義は「file1.c」内で一度だけ行われ、宣言との整合性がチェックされます。

externキーワードの本質を的確に捉えたStack Overflowの質問が以下にありますので、より深く理解したい方は参考にしてください。
https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files

  1. C++で解く「迷路 II」問題 ― 壁に当たるまで転がるボールの最短距離をBFSで求める

    問題概要 空きマスと壁からなる迷路の中にボールがあります。ボールは上・下・左・右のいずれかの方向に転がって空きマスを進むことができますが、壁にぶつかるまで止まることはできません。ボールが停止したときに、初めて次の方向を選ぶことができます。 ボールのスタート位置、目的地、そして迷路そのものが与えられるので、ボールが目的地で停止するまでの最短距離を求めてください。ここでの距離とは、ボールが転がって通過した空きマスの数のことです(スタート位置は含まず、目的地は含みます)。どうしても目的地で停止できない場合は -1 を返します。 迷路は2次元配列で表現されます。1 が壁、0 が空きスペースを意味し、迷

  2. C++で解く迷路問題:転がるボールが目的地に止まれるかをBFSで判定する方法

    迷路の中にボールがあるとします。迷路には空きスペース(通路)と壁があります。ボールは上下左右のいずれかの方向に転がって空き通路を進むことができますが、壁にぶつかるまで止まりません。ボールが停止したときに、次の方向を選べます。この問題では、ボールの開始位置、目的地、そして迷路そのものが与えられ、「ボールが目的地の位置で停止できるかどうか」を判定する必要があります。迷路は2次元配列で表現され、1は壁、0は空きスペースを意味します。迷路の外周はすべて壁になっています。開始位置と目的地は行・列のインデックス(座標)で与えられます。問題例たとえば、次のような2次元配列で表される迷路を考えてみましょう。0