externとstaticの使用
4630 ワード
1.宣言と定義
変数を定義すると、その変数を宣言するプロセスが含まれ、メモリシートにメモリ領域が申請されます.複数のファイルで同じ変数を使用する場合は、繰り返し定義を避けるために宣言と定義を分離する必要があります.定義は、名前に関連付けられたエンティティを作成することです.宣言は、名前をプログラムに知らせることです.ファイルが他のファイルで定義された変数を使用する場合は、そのファイルに対する宣言を含める必要があります.
関数と変数の宣言にはメモリは割り当てられませんが、定義には対応するメモリ領域が割り当てられます.
関数と変数の宣言は何度もできますが、定義は最大回しかできません.
関数の宣言および定義のデフォルトはexternです.すなわち、関数のデフォルトはグローバルのです.
変数の宣言および定義のデフォルトはローカルであり、現在のコンパイルユニットまたはファイル内でを使用できます.
宣言と定義がstaticとexternの理解に役立つことを理解します.たとえばexternは1つの場所で定義され、他のファイルは宣言するだけで、繰り返し定義できません.
2. static& extern
2.1 static
一般的にローカル変数はスタック領域に格納され、ローカル変数のライフサイクルは、その存在する文ブロックの実行が終了すると終了します.しかしstaticでローカル変数を修飾すると、この変数はスタック領域に格納されずに静的データ領域に配置され、そのライフサイクルはプログラム全体が終了するまで続き、この変数は初回実行時にのみ初期化され、一度しか行われませんが、その役割ドメインは関数の中で以下のようにしかできません.
ローカル静的変数zは、このファイルのprint関数でのみアクセスでき、役割ドメインの範囲を超えるとアクセスできません.
static修飾のグローバル変数であり、実装された関数がヘッダファイル(h)に書かれている場合、他のファイルにもアクセスできます.以下のようにします.
staticグローバル変数をヘッダファイルに書き込むと、すべてのファイルのヘッダファイルの操作がこの変数を共有することがわかります.
ただし、この静的グローバル変数をソースファイル(cpp)で操作する場合、この静的グローバル変数は現在のファイルでのみ有効ですが、別のファイルでこの静的変数にアクセスすると、変数の初期のデフォルト値となり、他のファイルで変更された値ではありません.同じ初期内容ですが、格納されている物理アドレスは異なります.次のようになります.
a.hのヘッダファイルには静的グローバル変数xが定義されており、異なるファイルの関数fun 1およびfun 3は、ヘッダファイルを含むcppごとにグローバル変数を作成するが、それらは独立しており、cppファイルでのみ変数を共有する.したがって、staticグローバル変数を一般的に定義する場合は、ヘッダファイルではなく元のファイルに配置し、複数のソースファイルの共有を回避し、他のモジュールに不要な情報汚染をもたらすことはありません.同じグローバル変数を異なるファイルで共有する場合はexternを使用します.
2.2 extern
あるファイルでグローバル変数が定義されている場合、別のファイルで変数を使用する場合、再び定義すると重複定義の問題が発生します.この場合、宣言を使用して、他の文書で定義されている変数をコンパイラに伝え、ここで参照する必要があります.上記のコードは以下の形式に変更されました.
参考資料
C/C++のstaticとexternの詳細
C/C++におけるexternキーワードの詳細
変数を定義すると、その変数を宣言するプロセスが含まれ、メモリシートにメモリ領域が申請されます.複数のファイルで同じ変数を使用する場合は、繰り返し定義を避けるために宣言と定義を分離する必要があります.定義は、名前に関連付けられたエンティティを作成することです.宣言は、名前をプログラムに知らせることです.ファイルが他のファイルで定義された変数を使用する場合は、そのファイルに対する宣言を含める必要があります.
関数と変数の宣言にはメモリは割り当てられませんが、定義には対応するメモリ領域が割り当てられます.
関数と変数の宣言は何度もできますが、定義は最大回しかできません.
関数の宣言および定義のデフォルトはexternです.すなわち、関数のデフォルトはグローバルのです.
変数の宣言および定義のデフォルトはローカルであり、現在のコンパイルユニットまたはファイル内でを使用できます.
宣言と定義がstaticとexternの理解に役立つことを理解します.たとえばexternは1つの場所で定義され、他のファイルは宣言するだけで、繰り返し定義できません.
2. static& extern
2.1 static
一般的にローカル変数はスタック領域に格納され、ローカル変数のライフサイクルは、その存在する文ブロックの実行が終了すると終了します.しかしstaticでローカル変数を修飾すると、この変数はスタック領域に格納されずに静的データ領域に配置され、そのライフサイクルはプログラム全体が終了するまで続き、この変数は初回実行時にのみ初期化され、一度しか行われませんが、その役割ドメインは関数の中で以下のようにしかできません.
void print(){
static int z = 100;
z++;
cout << z <
ローカル静的変数zは、このファイルのprint関数でのみアクセスでき、役割ドメインの範囲を超えるとアクセスできません.
static修飾のグローバル変数であり、実装された関数がヘッダファイル(h)に書かれている場合、他のファイルにもアクセスできます.以下のようにします.
// a.h
#ifndef A_H
#define A_H
#include
using namespace std;
static char str[] = "hello";
namespace sextern {
void print1();
void Fun1();
void Fun1(){
str[0] = 'l';
}
void print1(){
cout << "value " << str < ...
*/
staticグローバル変数をヘッダファイルに書き込むと、すべてのファイルのヘッダファイルの操作がこの変数を共有することがわかります.
ただし、この静的グローバル変数をソースファイル(cpp)で操作する場合、この静的グローバル変数は現在のファイルでのみ有効ですが、別のファイルでこの静的変数にアクセスすると、変数の初期のデフォルト値となり、他のファイルで変更された値ではありません.同じ初期内容ですが、格納されている物理アドレスは異なります.次のようになります.
//a.h
#ifndef A_H
#define A_H
#include
using namespace std;
static char str[] = "hello";
namespace sextern {
void Fun1();
void print1();
}
#endif // A_H
//a.cpp
#include "a.h"
namespace sextern {
void Fun1(){
str[0] = 'l';
}
void print1(){
cout << "value " << str << endl;
cout << "address " << &str <
using namespace std;
namespace sextern {
void Fun3();
void print3();
}
#endif // C_H
//c.cpp
#include "c.h"
#include "a.h"
namespace sextern {
void Fun3(){
str[0] = 'o';
}
void print3(){
cout << "value " << str < ...
*/
a.hのヘッダファイルには静的グローバル変数xが定義されており、異なるファイルの関数fun 1およびfun 3は、ヘッダファイルを含むcppごとにグローバル変数を作成するが、それらは独立しており、cppファイルでのみ変数を共有する.したがって、staticグローバル変数を一般的に定義する場合は、ヘッダファイルではなく元のファイルに配置し、複数のソースファイルの共有を回避し、他のモジュールに不要な情報汚染をもたらすことはありません.同じグローバル変数を異なるファイルで共有する場合はexternを使用します.
2.2 extern
あるファイルでグローバル変数が定義されている場合、別のファイルで変数を使用する場合、再び定義すると重複定義の問題が発生します.この場合、宣言を使用して、他の文書で定義されている変数をコンパイラに伝え、ここで参照する必要があります.上記のコードは以下の形式に変更されました.
//b.h
#ifndef B_H
#define B_H
char str[] = "hello"; //
#endif // B_H
//a.h
#ifndef A_H
#define A_H
#include
using namespace std;
extern char str[];
namespace sextern {
void Fun1();
void print1();
}
#endif // A_H
//a.cpp
#include "a.h"
namespace sextern {
void Fun1(){
str[0] = 'l';
}
void print1(){
cout << "value " << str << endl;
cout << "address " << &str <
using namespace std;
extern char str[];
namespace sextern {
void Fun3();
void print3();
}
#endif // C_H
//c.cpp
#include "c.h"
namespace sextern {
void Fun3(){
str[0] = 'o';
}
void print3(){
cout << "value " << str < ...
*/
参考資料
C/C++のstaticとexternの詳細
C/C++におけるexternキーワードの詳細