C/C++におけるexternキーワードの詳細

4015 ワード

一.extern修飾変数と関数
C言語では、修飾子externは、変数または関数の宣言の前に「この変数/関数は別の場所で定義されており、ここで参照する」ことを説明するために使用されます.extern宣言は定義ではなく、ストレージスペースを割り当てません.
まずコードを見てみましょう
/*  basic_stdy.h */
 
#ifndef_BASIC_STDY_H_
#define_BASIC_STDY_H_
 
//extern int a;                                  //       ,    extern,       
//void fun();                                    //   extern   
 
#endif
 
 
/*  basic_stdy.cpp */
#include"basic_stdy.h"
#include
using namespace std;
 
int a(2);
 
void fun(){
            cout << a <
#include "basic_stdy.h"
using namespace std;
 
extern int a;                                                                        //ok       ,         
extern void fun();                                                       //ok       ,         
 
int main(int argc,char **argv){
 
            cout << a << endl;
            fun();
 
            system("pause");
            return 0;
}

つまり、1つのファイルに変数と関数を定義し、他のファイルで使用するには2つの方法があります.
1.ヘッダファイルを使用して宣言し、他のファイルにヘッダファイルを含める
2.他のファイルで直接extern
二.extern「C」作用
たとえば、CでDLLライブラリを開発し、C++言語でもDLL出力(Export)の関数を呼び出すことができるようにするには、extern「C」でコンパイラに関数名を変更しないように強制する必要があります.
通常、C言語のヘッダファイルには、次のような形式のコードがよく見られます.
#ifdef __cplusplus  
extern "C" {  
#endif  
  
/**** some declaration or so *****/  
  
#ifdef __cplusplus  
}  
#endif

1.次に、後で使用するためのc言語のモジュールを作成します(以降の項目はcの場合もc++の場合もあります).ソースファイルは事前にコンパイルされており、.soまたは.oにコンパイルされても構いません.ヘッダファイルに関数を宣言する場合は、条件コンパイルで含めます.以下のようにします.
 
#ifdef __cpluscplus  
extern "C" {  
#endif  
  
//some code  
  
#ifdef __cplusplus  
}  
#endif  

すなわち,すべての関数宣言をsome codeの位置に置く.
2.もしこのモジュールがすでに存在するならば、会社の先辈が书いたのかもしれなくて、どうせすでに存在して、モジュールの.hファイルにextern“C”のキーワードがなく、このモジュールが変更されたくない場合、このようにして、あなたのc++ファイルの中で、このモジュールのヘッダファイルを含む時にextern“C”を加えて、以下のようにすることができます:
extern "C" {  
#include "test_extern_c.h"  
} 

3.上記の例では、モジュール内の1つの関数のみを使用し、モジュール全体をincludeする必要がない場合は、includeヘッダファイルを使用せずに、関数を個別に宣言することができます.
 
extern "C" {  
int ThisIsTest(int, int);            
} 

3つ目は、関数を単独で宣言する場合、ヘッダファイルを必要としないか、ヘッダファイルにextern intThisIsTest(int a,int b)を書くことができないことに注意してください.そうでなければerror C 2732:リンク仕様が「ThisIsTest」の初期仕様と衝突し、このエラーは、
モジュール内のこのThisIsTest関数を使用することができます.
あとは注意です.cファイルにextern"C"intThisIsTest(int x,int y)と書くことはできません.C言語のヘッダファイルでは、その外部関数はexternタイプとしてしか指定できません.C言語ではextern「C」宣言はサポートされていません.cファイルにextern「C」が含まれている場合、コンパイル構文エラーが発生します.
extern「C」の使い方のポイント
1.単一の文であってもよい
   extern "C" double sqrt(double);

2.複合文であってもよく、複合文の宣言にextern"C"を加えたものに相当する
   extern "C"
   {
     double sqrt(double);
     int min(int, int);
  }

3.ヘッダファイルを含めることができます.ヘッダファイルの宣言にextern"C"を付けることに相当します.
   extern"C"
  {
    #i nclude 
  }

4.extern「C」を関数に追加することはできません
5.関数に複数の宣言がある場合は、extern「C」を追加してもよいし、最初の宣言にのみ表示してもよいし、後の宣言は最初のリンクインジケータのルールを受け入れる.
6.extern「C」のほか、extern「FORTRAN」などがあります.
三.ナレッジポイントの宣言と定義
1.定義も宣言です.extern宣言は定義ではありません.つまり、ストレージスペースを割り当てません.externはコンパイラ変数が他の場所で定義されていることを示します.
eg:extern inti;//宣言、定義ではありません
       inti;//宣言、定義
2.初期化式が宣言された場合、externが先に追加されていても定義として扱われます.extern宣言が関数の外部にある場合にのみ初期化できます.
eg:externdouble pi=3.1416;//定義#テイギ#
3.関数の宣言と定義の違いは比較的簡単で、{}を持つのは定義であり、そうでない場合は宣言である.
eg:externdouble max(double d1,double d2);//宣言
doublemax(double d 1,double d 2){}//定義
4.externキーワードがない限り、変数の定義です.
eg:extern inti;//宣言
       inti;//定義#テイギ#
注意:basic_stdy.hにchar glob_がありますstr[];そしてbasic_stdy.cpp有char glob_str[]("123456");この場合、ヘッダファイルは定義されず、デフォルトはexternです.
プログラミングスタイル:
1.変数定義を入れるな.hファイルは、繰り返し定義エラーを招きやすい.
2.変数がグローバルに設計されない限り、staticキーワードを使用して変数定義をソースファイルの役割ドメインに制限します.
つまり
3.ヘッダファイルに変数を宣言することができ、使用するときにこのヘッダファイルを含めてこの変数を宣言します.