C言語におけるstatic修飾子の基本
staticとは何か?
static
はC言語において変数や関数のスコープや寿命を制御するための修飾子です。
通常の変数と異なり、static
を付けることで以下の特性を持ちます:
- ローカル変数:関数内で宣言された場合、その関数内でのみ有効だが、関数が終了しても値が保持される。
- グローバル変数:ファイル内でのみ有効となり、他のファイルからアクセスできなくなる(内部リンケージ)。
- 関数:そのファイル内でのみ使用可能になる(内部リンケージ)。
以下のコードで基本的な static
の動作を確認できます。
#include <stdio.h>
void counter() {
static int count = 0; // 値が保持される
count++;
printf("Count: %d\n", count);
}
int main() {
counter();
counter();
counter();
return 0;
}
実行結果:
Count: 1
Count: 2
Count: 3
このように、関数が終了しても static
変数の値は保持され続けます。
static修飾子の重要性
static
を使用することで、以下のメリットがあります:
- データの保持:関数を呼び出すたびにデータがリセットされるのを防ぐ。
- スコープの制限:関数や変数をファイル内でのみ使用可能にし、名前の衝突を防ぐ。
- メモリ管理:グローバル変数の使用を減らし、コードの可読性を向上させる。
C言語におけるstaticの役割
C言語で static
は以下の3つの使い方があります:
- 関数内でのstatic変数(ローカル変数の値を保持)
void func() {
static int x = 0;
x++;
printf("%d\n", x);
}
- ファイルスコープのstatic変数(他のファイルからアクセス不可)
static int globalVar = 100;
- static関数(関数をそのファイル内でのみ有効にする)
static void helperFunction() {
printf("This function is only accessible within this file.\n");
}
static変数とその性質
static変数の初期化と保持
C言語の static
変数は、プログラムの実行開始時に1度だけ初期化 され、その値はプログラムが終了するまで保持されます。
通常のローカル変数は関数が呼ばれるたびに新しく作られますが、static
変数は関数が終了しても値が失われません。
例:通常のローカル変数とstatic変数の比較
#include <stdio.h>
void normalVariable() {
int num = 0; // 毎回初期化される
num++;
printf("Normal Variable: %d\n", num);
}
void staticVariable() {
static int num = 0; // 一度だけ初期化され、値が保持される
num++;
printf("Static Variable: %d\n", num);
}
int main() {
for (int i = 0; i < 3; i++) {
normalVariable();
}
for (int i = 0; i < 3; i++) {
staticVariable();
}
return 0;
}
実行結果:
Normal Variable: 1
Normal Variable: 1
Normal Variable: 1
Static Variable: 1
Static Variable: 2
Static Variable: 3
通常のローカル変数は関数が呼ばれるたびにリセットされますが、static
変数は値を保持し続けることが分かります。
static変数のスコープと寿命
C言語における static
変数のスコープと寿命は次のようになります。
種類 | スコープ | 初期化 | 値の保持 | 例 |
---|---|---|---|---|
ローカル変数 | 関数内のみ | 毎回 | 呼び出しのたびにリセット | int x = 0; |
staticローカル変数 | 関数内のみ | 1回だけ | プログラム終了まで | static int x = 0; |
staticグローバル変数 | ファイル内のみ | 1回だけ | プログラム終了まで | static int y = 100; |
ポイント:
- ローカルstatic変数 は関数内でしか使えませんが、値は関数が呼ばれるたびにリセットされません。
- グローバルstatic変数 は同じファイル内でのみアクセス可能で、他のファイルから参照できません(内部リンケージ)。
static変数の使用例
1. カウンタの保持(関数の呼び出し回数を記録)
#include <stdio.h>
void countCalls() {
static int count = 0; // 初回のみ0で初期化される
count++;
printf("Function called %d times\n", count);
}
int main() {
countCalls();
countCalls();
countCalls();
return 0;
}
実行結果:
Function called 1 times
Function called 2 times
Function called 3 times
static
変数を使うことで、関数が何回呼び出されたかを記録できます。
2. グローバルstatic変数(外部からのアクセスを制限)
// file1.c
#include <stdio.h>
static int counter = 0; // このファイル内でのみ有効
void incrementCounter() {
counter++;
printf("Counter: %d\n", counter);
}
// file2.c
#include <stdio.h>
// extern int counter; // staticなので外部からはアクセスできない
int main() {
// incrementCounter(); // 呼び出せるが、counter は file2.c から直接参照できない
return 0;
}
ポイント:
static
付きのグローバル変数は、そのファイル内でのみアクセス可能。file2.c
からcounter
にアクセスできないため、意図しない変更を防げる。
static関数について
static関数の定義と使い方
static
修飾子を関数につけると、その関数は**定義されたファイル内でのみ使用可能(内部リンケージ)**になります。
通常の関数は別のファイルから extern
を使って呼び出せますが、static
関数は外部ファイルから呼び出せません。
static関数の定義方法
cコピーする編集する#include <stdio.h>
static void sayHello() { // static関数
printf("Hello, Static Function!\n");
}
int main() {
sayHello(); // ファイル内で呼び出し可能
return 0;
}
ポイント:
static void sayHello()
のように関数の前にstatic
を付けることで、そのファイル内でのみ使用可能。- 同じ名前の関数を別のファイルで定義しても競合しない。
static関数のアクセス制限
static
関数の最大の特徴は、定義されたファイル内でしかアクセスできないことです。
以下の例で、static
関数が外部ファイルからアクセスできないことを確認できます。
file1.c(static関数を定義)
cコピーする編集する#include <stdio.h>
static void hiddenFunction() { // このファイル内でのみアクセス可能
printf("This is a static function.\n");
}
void callHiddenFunction() {
hiddenFunction(); // このファイル内なら呼び出せる
}
file2.c(外部ファイルからアクセス)
cコピーする編集する#include <stdio.h>
// void hiddenFunction(); // 宣言してもアクセス不可(staticのため)
int main() {
// hiddenFunction(); // コンパイルエラー(file1.c内でしか使えない)
return 0;
}
ポイント:
file2.c
からhiddenFunction()
を呼び出すとエラーになる。static
を付けることで、他のファイルから意図しない呼び出しを防げる。
static関数とグローバル関数の違い
static関数 | グローバル関数 | |
---|---|---|
アクセス範囲 | 定義されたファイル内のみ | どのファイルからでも呼び出し可能 |
外部リンケージ | なし(内部リンケージ) | あり(外部リンケージ) |
競合の可能性 | なし(ファイルごとに独立) | あり(同じ名前の関数が競合する可能性あり) |
グローバル関数の例
cコピーする編集する#include <stdio.h>
void globalFunction() { // どのファイルからもアクセス可能
printf("This is a global function.\n");
}
static関数の例
cコピーする編集する#include <stdio.h>
static void staticFunction() { // このファイル内でのみ有効
printf("This is a static function.\n");
}
結論:
- 他のファイルからアクセスさせたくない関数は
static
にする。 - グローバル関数は
extern
を使えば他のファイルから呼び出せるが、名前が競合するリスクがある。
ローカル変数 vs static変数
ローカル変数のメモリ管理
C言語のローカル変数は、関数が呼び出されるたびにスタック領域に確保され、関数の終了時に自動的に解放されます。
そのため、関数を再び呼び出すと変数の値はリセットされ、以前の値は保持されません。
ローカル変数の動作例
#include <stdio.h>
void localVariableTest() {
int num = 0; // 毎回新しい変数が作られる
num++;
printf("Local Variable: %d\n", num);
}
int main() {
localVariableTest();
localVariableTest();
localVariableTest();
return 0;
}
実行結果
Local Variable: 1
Local Variable: 1
Local Variable: 1
num
は毎回0
に初期化され、関数が終了するとメモリから消えるため、値は保持されません。- 短期間のデータ保存に適していますが、値を持続させたい場合には向いていません。
static変数の利点
static
修飾子を付けた変数は、データセグメント(静的メモリ領域)に確保され、プログラムが終了するまで保持されます。
そのため、関数を複数回呼び出しても static
変数の値はリセットされません。
static変数の動作例
#include <stdio.h>
void staticVariableTest() {
static int num = 0; // 一度だけ初期化され、値が保持される
num++;
printf("Static Variable: %d\n", num);
}
int main() {
staticVariableTest();
staticVariableTest();
staticVariableTest();
return 0;
}
実行結果
Static Variable: 1
Static Variable: 2
Static Variable: 3
static
変数は、関数が終了しても値を保持し続けるため、関数を呼び出すたびに値が増加する。- 状態を保持する必要がある場面に適している(例:カウンター、フラグ管理)。
ローカル変数とstatic変数の適切な使用法
ローカル変数 | static変数 | |
---|---|---|
メモリ領域 | スタック領域(自動割り当て・解放) | データ領域(プログラム終了まで保持) |
初期化のタイミング | 関数が呼ばれるたび | プログラム開始時に1回のみ |
値の保持 | 関数が終了するとリセットされる | 関数が終了しても保持される |
適用例 | 一時的な計算、短期間のデータ保存 | カウンター、状態管理、リソース共有 |
適切な使い分け
- 一時的な処理(関数内の計算結果を保存するなど)→ ローカル変数を使用
- 値を維持しながら処理を継続する(カウンターや設定フラグなど)→ static変数を使用
C言語におけるグローバル変数の利用
グローバル変数の初期化
C言語のグローバル変数は、関数の外で定義され、プログラム全体で共有されます。
データ領域(静的メモリ領域) に確保され、プログラムの実行中は値が保持され続けます。
グローバル変数の定義と初期化
#include <stdio.h>
int globalVar = 10; // グローバル変数
void printGlobalVar() {
printf("Global Variable: %d\n", globalVar);
}
int main() {
printGlobalVar(); // 10を出力
globalVar = 20; // 値を変更
printGlobalVar(); // 20を出力
return 0;
}
ポイント:
globalVar
はプログラム全体でアクセス可能。- 明示的に初期化しない場合、自動的に
0
で初期化される(ローカル変数とは異なる)。
グローバル変数の操作と制限
グローバル変数は便利ですが、無制限に使用するとコードの可読性や保守性が低下するため注意が必要です。
グローバル変数の問題点
- 予期しない変更のリスク
- どこからでも変更できるため、意図しない値の上書きが発生する可能性がある。
- 関数の独立性が低下
- 関数が外部の変数に依存することで、再利用性やデバッグの難易度が上がる。
- スコープの制限ができない
- すべてのファイルからアクセスできるため、モジュールごとのデータ分離が困難。
グローバル変数の制限方法
関数内での利用を制限し、変更を最小限に抑えるのがベストプラクティス。
#include <stdio.h>
int counter = 0; // グローバル変数
void incrementCounter() {
counter++; // 直接変更
}
int main() {
incrementCounter();
printf("Counter: %d\n", counter); // 1を出力
return 0;
}
- 変更を
incrementCounter()
関数のみに制限すると、意図しない変更を防ぎやすくなる。
static指定によるグローバル変数のスコープ制御
static
をグローバル変数に適用すると、その変数は定義されたファイル内でのみアクセス可能(内部リンケージ)になります。
staticグローバル変数の例
// file1.c
#include <stdio.h>
static int hiddenVar = 100; // このファイル内でのみアクセス可能
void printHiddenVar() {
printf("Hidden Variable: %d\n", hiddenVar);
}
// file2.c
#include <stdio.h>
// extern int hiddenVar; // staticのため外部からはアクセス不可
int main() {
// printHiddenVar(); // OK
// printf("%d\n", hiddenVar); // エラー:hiddenVarはfile1.c内でのみ有効
return 0;
}
ポイント:
static
を付けると、そのファイル内でのみアクセス可能になり、意図しない外部アクセスを防ぐ。- 他のファイルから
extern
で参照できなくなるため、モジュールのカプセル化が向上する。
グローバル変数の適切な使用法
方法 | メリット | デメリット |
---|---|---|
通常のグローバル変数 | どの関数からもアクセス可能 | 変更の影響範囲が広く、デバッグが難しい |
staticグローバル変数 | ファイル単位でアクセスを制限 | 他のファイルと共有できない |
getter/setter関数を用意 | 変更の管理が容易 | コード量が増える |
結論:
- できる限りローカル変数を使い、グローバル変数の使用は最小限に抑える。
- 外部からのアクセスを防ぎたい場合は
static
を活用する。
staticのメモリ管理
メモリ領域とstatic変数
C言語では、変数の種類によってメモリの割り当てられる領域が異なります。static
変数は データ領域(静的メモリ領域) に保存され、プログラムの実行開始時に確保され、終了まで保持されます。
メモリ領域の比較
変数の種類 | メモリ領域 | 初期化タイミング | 値の保持 | 例 |
---|---|---|---|---|
ローカル変数 | スタック領域 | 関数呼び出し時 | 関数終了時に破棄 | int x = 0; |
グローバル変数 | データ領域(BSS or Data) | プログラム開始時 | プログラム終了まで | int y = 10; |
static変数 | データ領域(BSS or Data) | プログラム開始時 | プログラム終了まで | static int z = 5; |
static変数のメモリ動作
#include <stdio.h>
void example() {
static int count = 0; // データ領域に保存
count++;
printf("Count: %d\n", count);
}
int main() {
example();
example();
example();
return 0;
}
実行結果
Count: 1
Count: 2
Count: 3
ポイント:
static
変数はデータ領域に確保されるため、関数をまたいでも値が保持される。- 一方、通常のローカル変数はスタック領域に格納され、関数終了時に破棄される。
メモリ効率を高める方法
静的変数を適切に管理し、メモリ効率を向上させるためのテクニックを紹介します。
1. 不要なグローバル変数を避ける
グローバル変数はプログラムのメモリを占有し続けるため、ローカルstatic変数を活用して必要な範囲のみ確保するのがベスト。
#include <stdio.h>
// 避けるべき例(グローバル変数)
int globalCounter = 0;
void incrementGlobal() {
globalCounter++;
printf("Global Counter: %d\n", globalCounter);
}
// こちらのほうが良い
void incrementStatic() {
static int localCounter = 0; // ファイルスコープのstatic変数
localCounter++;
printf("Static Counter: %d\n", localCounter);
}
2. メモリの競合を防ぐ
static
変数は スタックを圧迫しない ため、関数内で保持すべきデータ に適している。- ただし、大量の
static
変数を定義すると メモリ使用量が増大する ため、適切に制限することが重要。
3. 使用しない変数はNULLや0でリセット
static int* cache = NULL; // 使用しない場合はNULLで初期化
動的メモリ確保が必要な場合は、malloc()
で確保したメモリを解放 (free()
) することも重要。
staticによるメモリの保持
static
変数を使用することで、データの保持が容易になり、意図しないメモリ解放を防げます。
例:カウンタの値を保持
#include <stdio.h>
void counter() {
static int count = 0; // ここで一度だけ初期化
count++;
printf("Function called %d times\n", count);
}
int main() {
counter();
counter();
counter();
return 0;
}
実行結果
Function called 1 times
Function called 2 times
Function called 3 times
ポイント:
static
変数は プログラム実行中ずっとメモリに残る ため、頻繁に値をリセットする必要がない。- ただし、大きなデータを
static
で保持しすぎるとメモリ効率が悪化するため注意。
まとめ
static
変数は データ領域に確保され、プログラム終了までメモリに保持される。- グローバル変数の代わりに static 変数を使うとスコープが限定され、管理しやすくなる。
- メモリの競合を防ぐため、不必要な
static
変数の定義を避ける。
配列とstatic修飾子
static配列の初期化方法
static
修飾子を使用すると、配列のメモリ領域がデータ領域に確保され、プログラムが終了するまで値が保持されます。
通常のローカル配列はスタック領域に割り当てられ、関数が終了すると消滅しますが、static
配列は関数が終了してもデータを保持し続けます。
static配列の特徴
- プログラムの実行開始時に1度だけ初期化される
- 関数が呼び出されるたびに値がリセットされない
- メモリはデータ領域に確保され、解放されることはない
static配列の宣言と初期化
#include <stdio.h>
void example() {
static int arr[5] = {1, 2, 3, 4, 5}; // 一度だけ初期化される
arr[0]++; // 値を変更
printf("arr[0]: %d\n", arr[0]);
}
int main() {
example();
example();
example();
return 0;
}
実行結果
arr[0]: 2
arr[0]: 3
arr[0]: 4
ポイント:
- 最初の呼び出しで
arr[0]
は 1 だが、関数が終了しても値が保持されるため、次回の呼び出しでは 2、3 と増加する。 - 通常のローカル配列であれば、関数が呼ばれるたびに
arr[0]
は1
にリセットされる。
static配列の簡単なサンプルコード
1. 連続したデータの保存
以下のコードは、関数を複数回呼び出してもデータが保持される例です。
#include <stdio.h>
void storeValues(int num) {
static int values[3]; // プログラム終了まで値を保持
static int index = 0;
if (index < 3) {
values[index] = num;
index++;
}
printf("Stored values: ");
for (int i = 0; i < index; i++) {
printf("%d ", values[i]);
}
printf("\n");
}
int main() {
storeValues(10);
storeValues(20);
storeValues(30);
storeValues(40); // 追加されない(配列サイズ3のため)
return 0;
}
実行結果
Stored values: 10
Stored values: 10 20
Stored values: 10 20 30
Stored values: 10 20 30
ポイント:
static
配列values[3]
にデータを蓄積し、関数が終了してもデータが消えない。- 配列のサイズ
3
を超えると、新しいデータは追加されない。
static配列がもたらす効果
メリット | 説明 |
---|---|
値の永続性 | 関数が終了しても配列の値が保持される |
関数内でのデータ管理 | グローバル変数を使わずにデータを管理可能 |
メモリの最適化 | スタック領域ではなくデータ領域に配置されるため、大きな配列も効率的に管理可能 |
データの更新が容易 | 配列の値を関数の間で引き継げるため、状態管理がしやすい |
static配列の活用例
- センサーのデータログ(測定値を関数内に保存)
- 関数内でのキャッシュ管理(頻繁に使用する値を保持)
- カウンターや履歴の記録(過去のデータを関数ごとに管理)
結論:
static
配列を活用すると、関数をまたいでもデータを保持できるため、状態管理が容易になる。- 関数のスコープ内でデータを共有しつつ、外部からのアクセスを制限することができる。
C言語におけるstaticの使い方の注意点
エラーや問題のトラブルシューティング
static
修飾子を使うことでコードが簡潔になる一方、いくつかのエラーや予期せぬ問題が発生する可能性もあります。以下に代表的な問題とその解決方法を示します。
1. 変数の初期化に関する問題
static
変数はプログラム開始時に初期化されますが、初期化しない場合、デフォルト値(0)が設定されることを忘れがちです。
例えば、初期化しない場合、整数型の static
変数はゼロで初期化されるので、意図しない動作が発生することがあります。
cコピーする編集するstatic int x; // 初期化しないと0で初期化される
解決策としては、意図的に初期化して、予期しない動作を防ぎましょう。
cコピーする編集するstatic int x = 5; // 明示的に初期化する
2. メモリの過剰消費
static
変数はメモリ領域を占有し続けるため、使わない変数を static
として定義し続けるとメモリの浪費になります。
これを回避するには、不要な static
変数は定義しないように心掛け、必要なときにのみ static
を使用することが重要です。
3. スコープの混乱
static
変数は関数内部でも外部でも、そのスコープが限定されます。関数外で static
変数にアクセスしようとするとエラーが発生します。
// グローバルスコープで宣言した static 変数には main からアクセスできない
static int globalVar = 10;
int main() {
printf("%d", globalVar); // エラー: static 変数にはアクセスできない
return 0;
}
解決策としては、必要な範囲だけで static
を使い、範囲を越えて使用しないようにします。
static指定によるプログラミングの制限
static
の使用にはいくつかの制限があり、これを理解しないと効率的に使えません。
1. グローバルスコープでの制限
static
変数はファイルスコープに限定されるため、他のファイルからその変数にアクセスすることができません。これにより、異なるファイル間でのデータ共有に制限が生じます。
例えば、別ファイルの関数から static
変数をアクセスすることはできません。
// file1.c
static int value = 10; // 他のファイルからはアクセスできない
// file2.c
extern int value; // エラー: static 変数にアクセスできない
解決策は、ファイル間でデータを共有する必要がある場合、static
を使わずにextern
を使ってアクセスするか、関数を通じてデータを渡します。
2. 複雑な依存関係
static
変数は関数やファイル内に限定された状態で値を保持しますが、これが複雑な依存関係を生む場合があります。
複数の関数が同じ static
変数を参照する場合、どのタイミングで変数が変更されるのか把握しにくくなるため、デバッグが難しくなることがあります。
解決策として、static
変数の使用は可能な限り少なくし、関数間で必要なデータを引数として渡す方が理想的です。
最適なコードの書き方
static
の利点を最大限に活かしつつ、問題を避けるために以下のベストプラクティスを守りましょう。
1. 必要な範囲だけで使用
static
変数は関数やファイルスコープに限定されるため、できるだけその範囲内で使用し、過剰に使用しないことが重要です。関数が終了した時点で不要になる場合、static
変数を使うべきではありません。
2. 明示的な初期化
static
変数を使用する際は、初期値を明示的に設定しましょう。初期化しないとデフォルトで0になるため、意図しない結果を招く恐れがあります。
static int counter = 0; // 明示的に初期化
3. グローバル変数の代わりにstaticを使用
static
修飾子を使うことで、グローバル変数のような役割を果たしつつ、アクセス範囲を制限できるため、意図しない変更を防げます。
グローバル変数を使う場面では、可能な限り static
を使用して制限する方が望ましいです。
4. デバッグを容易にする
static
変数を使う場合、関数の間でデータを共有するため、どの変数がどの関数で変更されているか追跡するのが難しくなる場合があります。デバッグの際には、ログやコメントを活用して、どの関数がどのタイミングで変更しているのかを明確にすることが役立ちます。
まとめ
static
修飾子を使うことで、関数やファイル内でデータを保持することができますが、使用には制限があります。- 不要な
static
変数は使わず、スコープを意識して適切に使うことが重要です。 - 初期化の方法やデータ管理を適切に行い、バグや不具合を避けるように心掛けましょう。
static修飾子の使用例
実際のコード例
以下は、static
修飾子を使用した実際のコード例です。このコードでは、関数内でデータを保持し、複数回の呼び出しに渡って値を更新する方法を示しています。
#include <stdio.h>
void counter() {
static int count = 0; // static 変数でカウントを保持
count++;
printf("Current count: %d\n", count);
}
int main() {
counter(); // 1回目の呼び出し
counter(); // 2回目の呼び出し
counter(); // 3回目の呼び出し
return 0;
}
実行結果
Current count: 1
Current count: 2
Current count: 3
この例では、count
変数が static
として宣言されているため、counter
関数が呼ばれるたびにその値は保持され、更新されます。関数が終了しても、count
の値は次回の呼び出し時に引き継がれます。
動作を確認するためのテスト方法
static
変数の動作を確認するためには、次のようなテストを行うことができます。
- 関数を複数回呼び出して、変数の値が保持されているか確認
- 関数を数回呼び出し、そのたびに
static
変数の値がどのように変化するかを観察します。 - 例えば、カウント変数や履歴データなど、前回の呼び出し時の結果が保持されているかをチェックします。
- 関数を数回呼び出し、そのたびに
- 初期化の確認
static
変数がプログラム開始時に1回だけ初期化されることを確認するため、変数がリセットされずに動作しているかをテストします。
- メモリ管理の確認
static
変数がメモリ領域を解放しないことを意識して、メモリリークが発生しないように注意します。ツールを使ってメモリ消費を確認することも有効です。
- スコープとアクセス制限の確認
static
変数がそのスコープ内でのみアクセスできることを確認するために、他のファイルから変数を操作しようとしてみて、コンパイルエラーが発生するかをチェックします。
出力結果の分析
実行結果を分析することで、static
修飾子の動作を理解できます。
1. static 変数が保持されることの確認
前述のコード例では、static
変数 count
が関数の呼び出しごとに増加しています。このことから、static
変数は関数が終了しても値が保持され、次回呼び出し時にその値が引き継がれることが分かります。
2. 初期化が一度だけ行われること
static
変数はプログラムが開始されるときに1回だけ初期化され、その後、値は更新され続けます。再起動や関数の再実行時には、初期化されずに前回の値が引き継がれることを確認できます。
3. 他のファイルや関数からのアクセス制限
static
変数は関数内またはファイル内でのみアクセス可能であるため、他の場所からアクセスを試みると、コンパイル時にエラーが発生します。この性質は、プログラムのモジュール化とデータの隠蔽に役立ちます。
4. メモリ消費の最適化
static
変数はメモリ領域を確保し続けますが、解放されることはなく、メモリリークが発生する可能性は低いです。しかし、意図的に不要な変数を保持しないように注意することが大切です。
まとめ
static
修飾子を使用することで、変数の値を関数間で保持することができ、状態を管理するのに便利です。- テストを行い、
static
変数が正しく動作することを確認し、スコープやアクセス制限に問題がないことをチェックします。 - 出力結果を分析することで、
static
変数が保持され、初期化が一度だけ行われることを確認できます。
コメント