extern宣言ヘッダーファイルが定義します&

 https://www.cnblogs.com/tshua/p/5741009.html

#includeヘッダファイルと他の変数、関数宣言、なぜにexternキーワードを含めることができますか?

       私はグローバル変数や関数を参照する場合、私は、ソースファイルの#includeに直接含まれる<xxx.h>(xxx.hは、宣言を含む)なぜ、なぜそれをexternで使用することはできませんか?

       この問題は、実践を通して、私は長い間、逆説的で悩ま情報、次の要約を見つけるされています:

まず、ヘッダファイル

        まず、私は文書をうなずくせ、実際には、コンピュータのためのヘッダファイルの面では効果は、彼女がちょうど瞬間を#include事前コンパイル時に開始され、他の意味は、実際には、参照するには他の人のための主要なヘッダファイルではありません。

        私はそれまでに所定の位置にヘッダファイルを参照し、xxx.txtに実験、接尾辞ヘッダファイルをしました

   #include "xxx.txt"

        非常によく渡されたリンクのコンパイルは、コードの役割を読み取るためにのみヘッダファイルは、他の役割を見ることができます!

        CまたはC ++のいずれかが、あなたは.Cまたは.cppファイルに何があるかのように、あなたの関数、変数、または構造を置きます。OBJ | | DLL |その後のlib、その上のdllファイル、OBJ、.oのと、その後、人々は最も基本的なGCC hisfile.cppのyourfile.oを使用するにコンパイル LIB のように。
        しかし、私たちのプログラマのため、彼らは最終的にどのようにあなたのlibに、DLL ...これ知っていますか?あなたのヘッダファイルに依存します。あなたの最初の文書には、ユーザーに説明することです。関数のパラメータ、インターフェイスの説明の様々な。
        それは、その後、ヘッダファイル内に置く説明は天然関数、変数、クラス「宣言」程度であるため(関数、関数プロトタイプも呼ばれる)を。、「文」を忘れないでください、ではない「を定義します。」

      宣言と定義の違い。

コードをコピー
    :変数を宣言し、2例がある

    1、1、ストレージスペースを作成する必要があることであるが。たとえば、次のように一度に文をint型は、すでにストレージスペースを確立していました。

    2、他のストレージスペースを確立する必要があります。たとえば、次の変数が別のファイルに定義されているのextern int型A。

    識別子-声明では、コンパイラの名前に導入することです。それは、「それはどのようなものか、この関数や変数がどこかに見つけることができます。」コンパイラに指示します 

    定義は言う:「ここでは、変数の確立」や「機能ここに設立しました。」これは、名前のストレージを割り当てます。関数や変数として定義されているかどうか、コンパイラがポイントの定義にそれらのためのストレージスペースを割り当てる必要があります。変数の場合、コンパイラは変数のサイズを決定し、機能のためにそのデータを格納するメモリ内のスペースを開き、コンパイラは、最終的には、いくつかのメモリを取らなければならないコードを生成します。

    とにかく:スペースの設立の宣言は、ストレージスペースを確立する必要はありません、「定義」になる「声明を。」

    宣言と同時に生成される変数(初期化)の基本的なタイプを定義し、オブジェクトの宣言と定義が分離されているため。

    例:クラスA 

    場合;クラスAのオブジェクトがある変数にコンパイラに指示しますが、初期化されていない文です

    =新しいAは、()の後にあれば、これは、初期化、割り当てられた空間です。

    (私たちの究極の目的は、定義が以前に使用していることは、ステートメントの使用を進めることであるあなたは、事前に別の文を使用しない場合は不要であり、その変数、関数である、あまりにも、その文は、ストレージスペースを割り当てていない、唯一の定義意志。)ストレージ・スペースを割り当てる

    変数静的役割は二つある宣言するために使用される:

    (1)静的なローカル変数宣言に対して、空間変数に割り当てられる全体のプログラムの実行中に常に存在します。

    (2)静的と宣言された外部変数は、変数モジュールの効果は、本文書に制限されます。


    追加:

    定義は何ですか?声明は何ですか?それらの違いは何ですか?

    オブジェクトを作成するために、(コンパイラ)で定義された、いわゆるは、オブジェクトのメモリのブロックを割り当てて、それを私たちは、多くの場合、変数名またはオブジェクト名を呼んで名前を与えます。

    2再意味の文があります:

    (1)名前は、メモリの一部を一致させるために持っているコンパイラに指示します、次のコードは、変数やオブジェクトが他の場所で定義されている使用しています。声明では、複数回出現することができます。

    (2)名前が予定されていない、と他の場所でもはや変数名やオブジェクト名として使用することができ、コンパイラに指示します。

    定義と宣言間の最も重要な違いは、することです:

    このオブジェクトに割り当てられたメモリへのオブジェクトを定義し、作成し、ステートメントがメモリを割り当てることができませんでした。
コードをコピー

 

 

だから、それはヘッダファイルであるかの愚かな喜喜定義最善ではありません。例えば、グローバル変数:
  / * XXヘッダファイル* /
  #ifndefの_XX_ヘッダファイル.H
  の#define _XX_ヘッダファイル.H
  のint A;
  #endifの

        それは悪いことで、ここではグローバル変数int型の定義は、そうですヘッダファイルが複数回参照されている場合は、あなたの定義は明らかに間違った構文に、繰り返されます。このちょうど#ifndefの条件コンパイルでは、ので、あなたのヘッダファイルは一度しか参照されている保証することができますが、おそらくまだ間違って行くことはありませんが、複数のCファイルには、ヘッダファイルが含まれている場合は意志のマクロ名が有効であるので、まだ間違っこのCソースファイルの範囲内で、複数のファイルのCコンパイラが間違っていないですが、リンク時にエラーになることを、多くの人があなたが同じ変数を定義すると言うので、唯一の

  リンク...
  incl2.obj:エラーLNK2005: "int型GLB"(?GLB @@ 3HAは)すでにincl1.objで定義された
  デバッグ/ incl.exe:致命的なエラーLNK1169:見つかった一個の以上の乗算定義されたシンボルを

  注意してください!

二、EXTERN

        このキーワードは、定義変数に本当に多くの憎しみで、実際には(デフォルトの定義を省略している)を省略することができるのextern;あなたは変数を宣言するとき、これは外部変数の前に追加する必要がありますが、その時々あなたはしないでください最終的には明確に宣言または定義されています。そこに必然のextern変数の前の文ではなく、というか、何のextern変数は唯一の前に定義することはできません。変数に割り当てられたメモリ空間を定義するには、そのステートメントは、変数のためのメモリ空間を割り当てる必要はありません。注意してください。

     変数と関数のために、以下のサブカテゴリー:

(1)変数

  特に、変数のため、。
  EXTERN INT; //グローバル変数を宣言
  //グローバル変数を定義し、int型

  のextern int型のA = 0; //グローバル変数及び所定の初期値を定義します。
  int型A = 0; //グローバル変数を定義し、初期値には、

       第四の外部と初期値に使用することができる、グローバル変数が定義されている第三に等しいです。
       それ混乱、彼らは本当にのように見えます。しかし、定義は一つだけの場所に表示することができます。換言すれば、INTかどうか;またはEXTERN int型A = 0;一度だけ発生する可能性があり、それは多くの時間をint型をexternでき、又は= 0 int型。

       あなたはグローバル変数を参照したい場合は、あなたは、int型にexternを宣言しなければならない。省略し、それがintなるので、この時点ではexternは、省略することはできません。これは、定義ではなく、文です。注:INTのextern; intは即ちEXTERN A、タイプに省略されてもよい;しかし、他のタイプを省略することができません。

 

(2)関数は、ある
       関数の関数も、定義と宣言、EXTERNを使用する際の定義である、それはこの文であることを述べたのexternで宣言されたときに、この機能は、それが外部に参照することができます説明されています。しかし、関数の定義と宣言とは異なる、定義された関数は、関数本体を持っている、関数は(もセミコロンで終わる)の体を機能しません宣言にextern関数定義や宣言、とにかく、他の文書でもあるとき、それは省略することができます私たちは、この機能が他の場所で定義されていることを知っているので、私はのexternが必要とされる追加しないでください。どちらもあまり変わらなので省略全く問題externをはありません。
   例えば:
  / * cppのファイル* /
  int型ファン(無効)
  {
        0を返す;
  }

  だけでなく、私たちはグローバル関数を定義
  / *他のcppファイル* /
  int型ファン(ボイド);
  我々はそれについて声明を発表しました、あなたが使用することができますし、後で
  すべて同じにexternなしでプラスを
  、我々はまた、ヘッダファイルでの楽しみの上で声明を置くことができ、最終的にはそのようになった
  /*fun.h*/の
  int型の楽しい(無効); //関数宣言ので、 extern省略し、いくつかは完全なint型ファンのextern(無効)です;
  / *ファイル対応fun.cpp * /
  int型ファン(無効)
  {
       0を返す;
  } //完全なグローバル関数を定義し、関数本体ので、同じにexternをそれは省略されています。
       そして、クライアント、クライアントを使用するのも楽しい、このヘッダファイルには、世界的な声明、[OK]を、に含まれています。問題ありません。
それがある場合は、対応は、顧客が特定のextern変数に、グローバル変数を使用したい、それ以外の場合は、定義されたなり。

        要約:

        変数、あなたは(そのようなファイル名Aなど)のソースファイルの変数に(そのようなファイル名Bなど)別のソースを使用したい場合は、2つの方法があります:(1)AにファイルB内でexternを宣言する必要がありますこのファイル(もちろん、グローバル変数)で定義された変数、(2)ヘッダファイルファイルに対応するファイルBを追加し、もちろん、ヘッダ、すなわち、変数宣言のBファイルを含むヘッダファイルで宣言のexternしなければなりません変数は、それ以外の変数は一度定義されています。

       (1)のextern文でファイルBを持つファイル:ソースファイル(例えば、ファイル名A)内の別のソースファイル(例えば、ファイル名のB)を使用する場合の機能については、機能である、方法の2種類があります(2)Bは、ファイルに対応するヘッダファイルに加え、もちろん、ヘッダファイルBが含まれ、定義された関数(実際には、Bファイルは、関数プロトタイプは、ファイルAに発生する可能性が定義され、EXTERNを省略してもよいです)ヘッダファイル関数の関数プロトタイプはにextern追加することはできません。

************************************************** ************************************************** **************************************************

       上記の概要は、別の言い方をすれば:

         グローバル変数は、通常は原稿.Cで定義されているため、(A)グローバル変数は、他のファイルへのファイルの呼び出し、我々は唯一の#includeファイルが含まれていてもよいソースファイルのヘッダーを含めることはできませんので、一般的に使用される方法は、にextern int型Aを使用することです外部変数を宣言します。別のアプローチは、あなたが他のソースファイルが外部変数で宣言することができるように、対応するヘッダファイルint型global_numああ内でexternを書くああ、彼女はそれの上にある含めることができる交流ファイル内のグローバル変数のint型のglobal_numを定義することです。

      (B)は、異なる関数および変数の例があります

          int型の楽しい();とのextern int型の楽しみ();すべての文(定義は身体を達成しています)。extern int型の楽しみで()が、より明示的に宣言することが示されました。

         そして、int型、定義されています      

               extern int型;声明。

 

(3)また、EXTERN改質剤は、C ++プログラムの標準C言語の関数呼び出しで使用することができます。

 例えば、C ++でのCライブラリ関数を呼び出すには、C ++を使用してプログラムで参照するにextern「C」ステートメントを機能させる必要があります。これは、Cの関数の仕様リンクで、リンク時にリンカに伝えるために使用したリンクです。主な理由は、オブジェクトコードに異なる命名コンパイルC ++およびCプログラムです。

コンパイル時にC ++言語は、多状態の問題を解決するために、パラメータ名はミドルネームを生成するために結合します、とC言語は、それは状況が対応するリンクを見つけることができない原因になりますしない、あなたはCを使用する必要がありますコンパイラに指示リンクを、指定されたEXTERN「C」は、リンクのために私の世代のミドルネームを与えていない、私の名前を保管してください。

 

第三に、ヘッダファイルとリンクexternを
        このリンクはまた、最初に提案した二つの問題を解決します。

  (A)は、他のヘッダはの#include、なぜにexternキーワードと変数、関数宣言がファイルを含むことができますか?

       私はグローバル変数や関数を参照したい場合は(B)は、私は、ソースファイルの#includeに直接含まれる<xxx.h>(xxx.hは、宣言を含む)なぜ、なぜにexternを使用することはできませんそれは?

         解答:ヘッダファイルに定義されている(ファイル名Bを仮定して)別の変数または関数を参照する多数のファイルのためのファイルを(ファイル名Aを想定)より効率的に使用される場合、より標準化されたプログラム構造。ファイル名Bで定義された変数の参照のために(例えばファイル名C、Dなど)他のファイルは、単に、ヘッダファイル(変数または関数宣言のもちろん、ヘッダのみに対応するファイルBを#includeそこに定義されてはならない)ことができます。

************************************************** ************************************************** ****************************************

       これは、コンパイラのみ.C(または.CPP)ファイルを知っているとき、忘れ時代だった、.hのか分からない問題だものです。
       人々は.C(または.CPP)ファイルの多くを書くとき、徐々に、それは多くの.c(または.CPP)に変数や関数のプロトタイプを宣言したファイルが同じであることを発見し、彼らは言葉を持っていました。各コンテンツごとに繰り返される単語は.C(または.CPP)ファイルをノック。しかし、さらに恐ろしいの文がする変更があったとき、あなたはすべての.c(または.CPP)ファイルをチェックして、その、ああ〜、単に世界の終わりを来ている!宣言を変更する必要がある、ということである
       かもしれない(最後に、誰か一部の人々は)もはやこの拷問に耐えることができない、彼(彼らは)繰り返される部分は、新しいファイルに配置し、その後.C(または.CPP)ファイルを必要としているこの文の#include XXXXを入力して、抽出されます。変更が声明を起こるようにしても、また、もはや見つけるととても美しい、まだ世界中に---変更する必要はありません!
       多くの場合、ヘッド.C(または.CPP)ファイルにこの新しいファイル、なぜなら、それは「ヘッダファイル」と呼ばれる名前の与える、拡張子が.hのである。
       (実際にはプリプロセッサである)。それ以来、コンパイラファイルを.C(ファイルまたは.cpp)に加えて、世界を知るために、そこに.hファイルがある、との#includeコマンドと呼ばれます。

おすすめ

転載: www.cnblogs.com/wllwqdeai/p/10972209.html