ストレージタイプ

5188 ワード

きそ


ストレージタイプは、自動変数、レジスタ変数、外部接続を有する静的ストレージ変数、内部リンクを有する静的ストレージ変数、空リンクを有する静的ストレージ変数に分けられます.
異なるストレージタイプは、変数の役割ドメイン、リンク、およびストレージ期間の異なる組合せを提供します.ストレージ期間は、メモリ内の変数の保持時間です.役割ドメインとリンクは、変数プログラムのどの部分が変数名で使用できるかを示します.

アクティブドメイン


プログラム内で1つの識別子にアクセスできる複数の領域を記述します.主に、コードブロックの役割ドメイン、関数プロトタイプの役割ドメイン、ファイルの役割ドメインに分けられます.

コードブロックスコープ


Javaのローカル変数と似ています.コードブロックは、開始カッコと終了カッコに含まれるコードです.たとえば、関数全体、または複合文です.あるコードブロックで宣言された変数は、そのコードブロックにのみ表示され、その変数が定義された場所からコードブロックの最後まで変数が表示され、その範囲を超えると表示されません.
    while(1){
        int a = 0;// while , 
    }
    printf("%d
",a);

c 99では、コードブロックの概念をif,for,whileおよびdo whileサイクルに拡張し、これらのコードがカッコで囲まれていなくても.次のようになります.
    for (int x  = 0; x<3; x++)
        printf("%d",x);

このループでは、xはforループコードブロックの一部とみなされるため、ループ全体においてxは可視であり、ループが出た後はxは使用できない.

関数プロトタイプスコープ


関数プロトタイプでのみ使用できる変数名.関数のプロトタイプを宣言する場合、変数名を指定する必要はありません.また、コンパイラは変数名が何であるかに関心を持っていません.関数プロトタイプで名前が機能する場合の1つは、関数に変長配列が使用されていることです.

ファイルの役割ドメイン


グローバル変数とも呼ばれ、すべての関数の外で定義された変数です.ファイルの役割ドメインを持つ変数は、その定義から定義を含むファイルの最後まで表示されます.関数が文を定義する前に表示されると、変数は使用できません.

リンク


リンクは空のリンク、外部接続、内部リンクに分けられます.
≪空のリンク|Null Links|emdw≫:コード・ブロックの役割ドメインまたは関数プロトタイプの役割ドメインを持つ変数に空のリンクがあります.これは、定義されたコード・ブロックまたは関数プロトタイプによってプライベートであることを意味します.
内部リンク:内部リンクを持つ変数は、定義されたファイルのどこでも使用できます.
外部リンク:外部リンクを持つ変数は、1つ以上のファイルで使用できます.
ファイルの役割ドメインを持つ変数は、内部リンクを持つ可能性も外部リンクを持つ可能性もあります.staticによって修飾されているかどうかが重要です.修飾された変数には内部リンクがあります.
まとめ:役割ドメインは、変数がローカル変数であるかグローバル変数であるかを決定し、リンクは、Javaのprivateタイプとpublicタイプのグローバル変数のような他のファイルにアクセスできるかどうかを決定します.

きおくじかん


ストレージ期間は、静的ストレージと自動ストレージの2つに分けられます.
静的ストレージ:プログラムの実行中に常に存在します.ファイルの役割ドメインを持つすべての変数は静的ストレージ期間です.
自動ストレージ:コードブロックをドメインとする変数(static修飾を除く)は、一般的に自動ストレージです.プログラムがこれらの変数を定義するコードブロックに入ると、これらの変数にメモリが割り当てられます.このコードブロックを終了すると、割り当てられたメモリが解放されます. 

じどうへんすう


自動ストレージ、コードブロックの役割ドメイン、および空のリンクを持つauto修飾ローカル変数(このキーワードは省略可能)を使用します.デフォルトでは、ローカル変数は自動変数であり、自動的に初期化されません.
空のリンクとコードブロックの役割ドメインは、変数定義が存在するコードブロックのみが名前で変数にアクセスできることを意味します.
内層コードブロックに外層コードブロックと同じ変数名が使用されている場合、内層コードブロックで使用されるのは内層コードブロック定義変数であり、内層コードブロックを離れるまで外層定義変数は使用されません.

レジスタ変数


自動変数と同様にregisterを用いて宣言するが、レジスタ変数がレジスタに格納される可能性があり(レジスタの速度はメモリよりはるかに大きいため、レジスタ変数は自動変数よりも速くアクセスされ、操作される)、レジスタ変数はアドレスできない.
1つのレジスタ変数が1つのリクエストにすぎないと宣言し、変数がレジスタに格納されない可能性があります.この場合、この変数は通常の自動変数ですが、アドレスを取得できません.

コードブロックの役割ドメインを持つ静的変数


静的:変数の格納位置が固定されていることを示し、変数が変更できないことを示すわけではありません.
static修飾を使用するローカル変数は、コードブロックの役割ドメイン、空のリンク、および静的記憶を持つ変数になります.自動変数とは異なり、この変数はコードブロックの実行が完了した後も回収されず、デフォルトでは0に初期化され、1回の関数呼び出しから次の関数呼び出しまで、システムはその値を記録している.次のようになります.
char* string_in(char* p1, char* src){
    static int a = 10;
    printf("%d
",a++);// , 10; 11 return NULL; }

aはstatic修飾を使用するためstring_in関数終了後もa変数の値は保存されている.次回string_への再アクセスinの場合,aの値は11である.
上のコードブロックも説明しています:静的変数はコードブロックに属していませんが、その役割ドメインは依然としてこのコードブロックの中にあり、プログラムがメモリに呼び出されたときにすでに位置しています.この変数を関数の中に置いて、この関数だけがこの変数を見ることができることを説明します.

外部リンクを持つ静的変数


このタイプには、ファイルの役割ドメイン、静的ストレージ、および外部リンクがあります.このタイプの変数を外部変数と呼び、変数の宣言をすべての関数の外に置くと外部変数が作成され、自動的に0に初期化されます.外部変数は、プログラムの実行時間と同様であり、1つの関数に限定されず、特定の関数が返されると消えません.
別のファイルに定義された外部リンクを持つグローバル変数を使用するには、使用する前にexternを使用して宣言する必要があります.変数がこのファイルで定義されている場合、この変数を使用する関数でexternを使用して再宣言できます.外部定義の変数が使用されていることを示しますが、宣言する必要はありません.次のように
extern int a;// a
char* string_in( char*, char*);
int main(int argc, const char * argv[]) {
string_in(NULL,NULL);
}
char* string_in(char* p1, char* src){
    printf("%d
",a); return NULL; }

上記のコードでは、externを使用してグローバル変数aを宣言します.これは、aが他のファイルで宣言されているためであり、本ファイルを使用するにはexternを使用して再宣言する必要があり、変数aを自分で定義することもできますが、内部リンクのグローバル変数またはローカル変数として宣言する必要があります.もちろん、宣言文(externint a;)string_に置くinメソッドで.
externを使用して変数を修飾すると、メモリの割り当ては発生しません.すなわち、externは、別の場所で定義された外部変数を参照するだけで、初期化できないことを示します.
extern int a = 10;// , extern a , 。
はaを付与できないというわけではありませんが、他の場所でもa=11という付与文は使用できますが、宣言時に付与することはできません.なぜなら
externは、すでに別の場所で宣言された変数を参照することを示すだけです.

変数の共有


1つのファイルで変数を定義し、他のファイルで宣言(externを使用)という変数を参照することで共有を実現します.すなわち、1つの定義宣言を除いて、他のすべての宣言はexternキーワードを使用する必要があり、定義宣言でのみ変数を初期化できます.
注:2番目のファイルでexternを使用して変数を宣言しない限り、1つのファイルで定義された外部変数は2番目のファイルでは使用できません.つまり、別のファイルで定義した外部変数を使用するには、externを再使用して宣言する必要があります.宣言時に再初期化することはできません.そうしないと使用できません.

内部リンクを持つ静的変数


このタイプには、静的ストレージ、ファイルの役割ドメイン、および内部リンクがあります.staticを使用してすべての関数の外部で定義します.このタイプの変数は、同じファイル内の関数でのみ使用できます.Javaのprivateタイプに似たグローバル変数.

まとめ


ローカル変数


1、auto宣言またはキーワードを使用しない宣言:通常のローカル変数.
2,register宣言を用いる:レジスタに格納される可能性があり,アドレスを取得できない.
3、static宣言を使用:静的ストレージ:プログラムの実行中(変数を含むコードブロックが実行されていない場合でも)、変数が存在し、その値が保持されます.関数の実行が完了しても回収されず、次回の関数の実行時も変数の値は前回の値となります.
4,extern宣言を使用:このファイルのグローバル変数を使用し、なければ別のファイルの外部リンクを持つグローバル変数を使用します.

グローバル変数


1、extern宣言を使用:別のファイルで定義された外部変数を参照します.
2,キーワード修飾を使用しない:プログラムに含まれる任意のファイルに含まれる関数で使用できる外部変数を定義します.
3、static宣言を使用:内部リンクを持つグローバル変数を定義します.同じファイル内の関数でのみ使用できます.