extern int i;// is a declaration
int j; //definition
著者は、最初のステートメントは宣言であり、2 番目のステートメントは定義であると述べています。2 番目のステートメントは宣言であり、最初のステートメントは定義であると思います。
Herbert Schildt による完全なリファレンス C を調べました
extern int i
...は変数宣言です。これは、コンパイラに「 という変数が存在しますがi
、別の場所で定義されている」ことを伝えるだけだからです。
int i
...実際の変数を作成するようにコンパイラに指示するため、変数定義です。
まず、最初も2番目も「ステートメント」ではありません。C 言語では、宣言はステートメントではありません。宣言は宣言であり、ステートメントはステートメントです。C では、これらは交差しない 2 つの独立した世界です。
第二に、すべての定義は同時に宣言でもあります。定義は、特定の種類の宣言にすぎません。したがって、宣言と定義を対置することは正しくありません。相互に排他的な方法です。
第三に、コメントが言っていることは正しく、あなたは間違っています。1 つ目は、非定義宣言です。2 つ目は定義です。
第 4 に、2 番目の定義はいわゆる暫定的な定義であり、C 固有の機能です。それはいくつかの独特な特性を持っています。通常、外部リンケージを持つ変数を定義するとは限りません。それが定義する変数のリンケージは、コンテキストに依存する場合があります。あなたの具体的な例では、文字通り、外部リンケージを持つ変数を実際に定義しています。暫定的な定義という用語を検索して、それについて詳しく知ることができます。
第 5 に、Shildt の本には大量の用語の誤りがたくさんあります (用語の誤りだけではありません)。これは実際、彼らが最もよく知られていることです。
宣言 : 宣言されたばかりの変数
Ex: int i;
定義 : 値declaration+its initialization
を持つ変数。
Ex: int i=10;
あなたの場合
extern int i;// is a declaration
//because you did not initialize value to i here.
j がグローバル変数であると仮定します。その後、宣言時に ZERO で初期化されます。
ここdeclaration+initialization =definition
int j; //definition
j がローカルの場合、それは宣言のみです。