staticとexternの違いを詳しく解く


私たちは知っていなければなりません.
C/C++宣言変数のデフォルトは内部リンク、関数のデフォルトは外部リンクです.
キーワードexternおよびstaticは、宣言で識別子のリンク属性を変更するために使用されます(リンクタイプは識別子の可視性を示します).
ここでは,主に両者がリンク属性に及ぼす影響を比較する.
static(変数または関数エンティティのリンク属性への影響のみを議論)
1、ある宣言が正常にexternalリンク属性を持っている場合、その前にstaticキーワードを付けると、彼のリンク属性をinternalに変えることができます.
例:
int main()
{
    int a;//a     external    
    return 0;
}
変数aの宣言にstaticを追加します
static int a;//static  a     
では、変数aはこのファイルにプライベート化され、他のソースファイルでもaという変数にリンクされている場合、別の異なる変数が参照されます.
2、同様に、関数をstaticと宣言することもできます.
static int fun();
は、関数funをデフォルトの外部リンクから内部リンクに変更し、他のソースファイルによって呼び出されることを防止することができる.
,3,staticはデフォルトのリンク属性がexternalであるという宣言に対してのみリンク属性を変更する効果があることに注目すべきである.
たとえば、関数fun()で
fun()
{
	int b = 0;
}
bは関数体内にあり、作用ドメインは関数内であり、関数体内でのみ有効であり、そのリンク属性はinternalであり、externalではない.
したがって、staticを追加するかどうかは、リンクプロパティにあまり影響しません.(もちろん、bのストレージタイプとライフサイクルに影響します.)
extern
1.externは、変数または関数の前に配置して、変数または関数の定義が別のファイルにあることを示し、コンパイラにこの変数または関数に遭遇したときに、他のモジュールで定義を探すように促すことができます.
例:
void fun()
{
	char a = 10;//a      internal
	extern int b;//     extern,  b      external
}

bをexternリンクプロパティとして指定すると、関数は別のソースファイルの外部変数にアクセスできます.
2.extern変数については、定義ではなくメモリ領域が割り当てられない変数の宣言にすぎません.
変数または関数の指定externリンクプロパティは、外部にエンティティがある場合に作成されます.そうしないと、リンク時にエンティティが見つかりません.
externキーワードを使用して変数名を定義せずに宣言します.
int a;//a     
extern int b;//b     

変数を初期化すると、externの有無にかかわらず定義とみなされます.
extern int c = 10;//cは定義です
3,C++においてexternは、CまたはC++関数の呼び出し仕様を示す別の役割を果たす.たとえばC++でCライブラリ関数を呼び出すには,C++プログラムでextern"C"で参照する関数を宣言する必要がある.これはリンクに使うもので、リンクにリンクするときにC関数仕様でリンクするように伝えます.主な理由は,C++とCプログラムのコンパイルが完了すると,ターゲットコードにネーミングルールが異なり,名前マッチングの問題を解決するためである.
例:
(1)リンク仕様は、1つのタイプ、関数、変数または定数に対してのみ指定する
extern “C” void Fun1();//            
extern "C" const constnumber;//    
extern "C" struct Student{...};//        
(2)は、extern"C"{}に含まれるコードのセグメントにリンク仕様を指定する.
#ifdef __cplusplus
extern "C" {
#endif
//      

#ifdef __cplusplus
}
#endif

まとめ
詳細な解析をまとめると,staticとexternでは,識別子のリンク属性への影響の違いを主に論じた.肝心な点をつかんで、利器をつかんで、いくつかの霧を破ることができて、私たちの考えをもっとはっきりさせます.