[C]リンクと寿命

リンクとの違いのライフサイクル:

  • リンクプロパティの識別子です。
  • ライフサイクルは、オブジェクトのプロパティです。
  • リンクは、内部(内部)、(外部の)外部またはなし(なし)であってもよいです。
  • ライフサイクルは、静的自動、また​​は(割り当て)を割り当てることができます。

リンク:

識別子は、翻訳単位、または識別子が同じ翻訳単位で宣言され、より複数回内で宣言され、それぞれが同じオブジェクトまたは関数を指してもよいです。以下のように、実施例4、外部結合を持つ変数は、同じオブジェクトが参照されます。

識別子がリンクを有する場合、それは言って、他のリンクは、共有オブジェクトまたは関数と同じ識別子を有します。

唯一のオブジェクトと関数識別子は、外部または内部リンクすることができます!いくつかの命令は、アクセス間プリコード部にはできませんので。

 

コンセプト コンセプト  状態を宣言するに属します 例外 隠すについて
 外部リンク  全体の手順を示す外部結合を持つ識別子は、同じ機能またはオブジェクトです。コンパイラにこのような識別子は、コネクタ(リンカ)、この識別子のリンカー(解決)することで解決し、同じ識別子の翻訳単位とリンクライブラリがリンクさ。

修飾語なしで格納されたオブジェクト識別子を使用して、機能と外部機能。

EXTERN変更関数とオブジェクト識別子を使用して、外部ストレージ機能(あなたが外部基準になるこの変数ニーズをクリアした場合、実際に、それは、非標準的な文言でそうする必要があれば、最高のは、任意のストレージ修飾子なしですあなたはこの記述する必要がある例3)。

オブジェクトとEXTERN内部関数は、このオブジェクトは、外側の外部リンクを有します。

識別子は、ドメインの役割の最初の文の2番目の文を作り、内部リンクとして宣言されており、この識別子は翻訳単位でケース内の翻訳単位の外部リンク、となってとリンクすることができない場合パフォーマンスの外に異なるがあります。

  • 異なる翻訳単位では、リンクは、(与えられている実施例2)。
  • 同じ翻訳単位で内部リンク(以下の実施例1)。

 

他の翻訳単位は、外部リンクを定義する場合は、本機では、その後、そうでない場合、コンパイラは、リンクユニットのステージに文句を言うだろう、外部リンクを定義することはできません。
 内部リンク

「内部リンク識別子は、」翻訳単位の代表は、この中で「同じオブジェクトまたは関数。」この識別子は、リンカー(リンカー)プロセスではありません。そのため、あなたは同じオブジェクトまたは関数を指すように、別の翻訳単位でこの識別子を使用することはできません。

識別子は内部リンクを有し、等は、識別子変換部(と競合しない実施例5)。しかし、翻訳単位内の外部結合を持つ識別子ならば、あなたは内部リンクの識別子の翻訳単位でこれを宣言することはできません。あなたは翻訳単位内の識別子を宣言した場合の内部リンクであるか、言い換えれば、我々は外部識別子「の名前で、」別の翻訳単位を宣言して使用することはできません。

 非機能内蔵、使用または関数オブジェクトは静的記憶修飾子を宣言しました。

 エクスターナル内部オブジェクトと機能、及び目的は、内部リンク(外部基準有する実施例1変数eの)を、

  翻訳手段(このユニットで内部リンクを使用して、ステートメント内部リンク、外部リンクユニットの皮内の外部リンクユニットを有する場合に実施例6
 リンクなし リンク識別子は内部リンク、外部のではないではない場合、それはリンクではありません。この文は、各識別子を表示され、より多くのコンパイラはこれだけの識別子を使用してメモリ内の別のオブジェクトを作成する必要がある、ある新しいエンティティ(実体)、のだろう。

 変数名ではなく、関数名は、ボリューム名(ラベル名)、小さなラベル(タグ)の構造とのtypedef名などの識別子ではない、です。

 関数のパラメータ。

 関数で宣言され、そしてEXTERN修飾子(識別子が静的と宣言される含む)識別子ないオブジェクトが存在していません。

   

例1:

int func1(void);                 // func1具有外部链接。
int a;                           // a具有外部链接。
extern int b = 1;                // b具有外部链接。
static int c;                    // c具有内部链接。
static int e;                    // e具有内部链接。
static void func2(int d)         // func2 具有内部链接; d具有无链接。 { extern int a;    // 此a和上面一样,具有外部链接。 int b = 2;  // 此b具有无链接,并且将上面声明的b隐藏起来 extern int c;   // 此c和上面一样,维持内部链接。 static int e; // e具有无链接,并且将上面声明的e隐藏起来。

  int f;                         // f具有无链接
}

示例2:

//翻译单元A
static int foo = 1024;
//翻译单元B
#include <stdio.h>

extern int foo;
void main(void)
{
    printf("%s:foo:%d\n", __func__, foo);
}

在链接两个编译单元的时候,编译器会抛出错误:

undefined reference to `foo'

 示例3:

//直接初始化带extern的对象,编译器会发出警告
extern int foo = 1024;
//this is recommend.
extern int foo;
int foo = 1024;

 示例4:

//翻译单元A声明变量foo
int foo = 1024;
//翻译单元B定义一个修改foo的函数
void func1(void)
{
    extern int foo;
    foo = 2048;
}
//翻译单元C调用函数修改了foo,并且输出
#include <stdio.h>

extern void func1(void);

void main(void)
{
    func1();
    extern int foo;
    printf("%s:foo:%d\n", __func__, foo);//输出2048
}

 示例5:

//翻译单元A声明一个具有内部链接的foo
static int foo = 1024;
//翻译单元B声明一个具有外部链接的foo,并且让翻译单元C修改这个foo
#include <stdio.h>

extern void func1(void);
int foo = 1;

void main(void)
{
    func1();
    printf("%s:foo:%d\n", __func__, foo);//输出2048
}
//翻译单元C声明一个修改外部foo的函数
void func1(void)
{
    extern int foo;
    foo = 2048;
}

示例6:

//翻译单元A声明一个外部链接
int foo = 1024;
//翻译单元B
#include <stdio.h> void func1(void); void func2(void); static int foo = 1; void main(void) { printf("%s:foo:%d\n", __func__, foo); //输出1 func1(); printf("%s:foo:%d\n", __func__, foo); //输出2048 func2(); //函数内输出1024,即单元以外的foo还是沿用外部链接那个foo } void func1(void) { extern int foo; //foo具有翻译单元作用域,所以就算这里省略掉extern int foo;声明,也可以正常访问到foo foo = 2048; }
//翻译单元C
#include <stdio.h>

void func2(void)
{
    extern int foo;
    printf("%d\n", foo);
}

 

生存周期:

对于理解对象生存周期则简单许多,只需要记住以下几点:

生存周期 描述 情况
进程生存期 对象会一直存在,直至进程结束

函数外声明的对象;

函数内带static关键字的变量;

函数内带内/外部链接的变量;

栈生存期 对象会存在到栈退出 函数自变量;
永久生存期 对象会一直存在 通过brk()划分的内存空间,例如malloc()、calloc()、realloc()

你需要注意的是,“永久生存期”的对象必须要手动释放(通过调用free()),否则即使进程被终止,内存空间也不会返还;

 

おすすめ

転載: www.cnblogs.com/yiyide266/p/11944429.html