112-C言語での外部使用の分析

外部

C言語では、変数または関数の宣言の前に修飾子externを使用して、「この変数/関数は他の場所で定義されているため、ここで引用する必要があります」を示します。さらに、externはリンク指定にも使用できます。

1.extern変更変数の宣言。
たとえば、ファイルacがbcの変数int pを参照する必要がある場合、acのextern int pを宣言してから、変数pを参照できます。extern修飾子を使用して他のモジュールから参照できる変数は、通常、グローバル変数です。もう1つの重要な点は、extern int pはacのどこにでも配置できることです。たとえば、acの関数fun定義の先頭でextern int pを宣言すると、変数pを参照できますが、このPは関数funのスコープ内で参照されます

2.extern変更された関数宣言。
本質的に、変数と関数の間に違いはありません。関数名は、関数のバイナリブロックの先頭へのポインタです。たとえば、ファイルacがbcの関数を参照する必要がある場合、bcのプロトタイプはint fun(int m)であり、acでextern int fun(int m)を宣言すると、funを使用して実行できます。何でも。変数の宣言と同様に、extern int fun(int m)はacのどこにでも配置できますが、必ずしもacのファイルスコープのスコープ内に配置する必要はありません。他のモジュールの関数を参照する場合、最も一般的な方法は、これらの関数宣言のヘッダーファイルをインクルードすることです。

externを使用することと、関数を参照するためにヘッダーファイルを含めることの違いは何ですか?
Externの引用方法は、ヘッダーファイルを含めるよりもはるかにクリーンです。externの使用方法は簡単です。externを使用して、参照する関数を宣言します。これの明らかな利点は、プログラムの前処理を高速化し、時間を節約できることです。大規模なCプログラムをコンパイルする過程で、この違いは非常に明白です。

一般的な問題

質問1配列は1つのソースファイルで定義されています:char a [6];別のファイルでは、次のステートメントで宣言されています:extern char * a;すみません、これは可能ですか?

いいえ、プログラムの実行中に不正アクセスが通知されます。その理由は、T型へのポインタがT型の配列と同等ではないためです。extern char aは、文字配列の代わりにポインタ変数を宣言するため、実際の定義とは異なり、実行時に不正なアクセスが発生します。宣言はexternchar a []に変更する必要があります。
分析例は次のとおりです。a[] = "abcd"の場合、外部変数a = 0x61626364(abcdのASCIIコード値)、aは明らかに無意味です。明らかに、(0x61626364)が指すスペースは無意味であり、不正なメモリアクセスのように見えるのは簡単です。
これは、externを使用する場合、宣言形式に厳密に対応する必要があることを思い出させます。実際のプログラミングでは、このようなエラーは珍しいことではありません。
Externは、変数宣言でよく使用されます。
グローバル変数.cファイル宣言します。このグローバル変数を参照する場合は、
.hに入れて、 externで宣言します。

質問2関数プロバイダーが一方的に関数プロトタイプを変更する場合、ユーザーが知らないうちに元のextern宣言を使用し続けると、コンパイラーはコンパイル中にエラーを報告しません。ただし、操作の過程で、入力パラメータが少ない、または多いため、システムエラーになることがよくあります。この状況をどのように解決する必要がありますか?

プロバイダーは独自のxxx_pub.hで外部インターフェイスの宣言を提供し、呼び出し元はヘッダーファイルをインクルードすることで、externステップを排除します。この種のエラーを回避するため。

質問3externが関数の前に置かれ、関数宣言の一部になることはよくあることですが、C言語のキーワードexternは関数宣言でどのような役割を果たしますか?

キーワードexternが関数の宣言に含まれている場合、それは関数が他のソースファイルで定義されている可能性があることを意味するだけであり、他の効果はありません。つまり、次の2つの関数宣言の間に明らかな違いはありません
。externintf();とint f();
  もちろん、そのような有用性はまだあります。これは、次の「* .h」を置き換えることです。関数を宣言するプログラム。一部の複雑なプロジェクトでは、すべての関数宣言の前にextern変更を追加することに慣れています。

質問 4C ++環境でC関数を使用すると、コンパイラがobjモジュールでC関数定義を見つけられないことがよくあり、リンク障害が発生します。この状況を解決するにはどうすればよいですか。

C ++言語のコンパイル時の関数のポリモーフィズムの問題を解決するために、関数名とパラメーターを組み合わせて中間関数名を生成しますが、C言語では生成しません。したがって、リンク時に対応する関数が見つかりません。C関数はextern "C"でリンクする必要があります。これにより、コンパイラに、私の名前を保持し、リンク用の中間関数名を生成しないように指示します。

#ifdef __cplusplus
#if __cplusplus
extern "C"{
    
    
 #endif
 #endif /* __cplusplus */ 
	 …
		  …
		   //.h文件结束的地方
 #ifdef __cplusplus
 #if __cplusplus
}
#endif
#endif /* __cplusplus */ 

おすすめ

転載: blog.csdn.net/LINZEYU666/article/details/111588170