Variable storage

4725 ワード

変数には、役割ドメインのほかにストレージ期間(storage duration)があります.ストレージ期間とは、メモリに変数が存在する期間を指します.ストレージ期間は、静的ストレージ期間と動的ストレージ期間に分けられます.

Static storage duration


静的記憶方式とは,プログラム実行中にシステムが変数に固定した記憶空間を割り当てることである.

Dynamic storage duration


動的記憶方式は,プログラム実行中に変数に対して動的に記憶空間を割り当てる.ダイナミックストレージに次のデータを格納します.
  • 関数形式パラメータ.関数を呼び出すと、パラメータにストレージ領域が割り当てられます.
  • 関数の自動変数(static宣言なしのローカル変数)
  • 関数呼び出し時のフィールド保護や戻りアドレスなど.

  • 同じ関数を1つのプログラムで2回呼び出すと、2回の割り当てと解放が行われ、この関数に2回割り当てられたローカル変数の記憶領域アドレスが異なる場合があります.記憶方法は静的と動的の2種類に分けられ,具体的には自動(auto),静的(static),レジスタ(register),外部のexternの4種類に分けられる.

    じどうへんすう


    関数のローカル変数では、キーワードstaticで宣言しない場合、コンパイルシステムはそれらに空間を動的に割り当てます.関数のパラメータと関数で定義された変数は、このようなものです.これらのスペースは、関数呼び出しの終了時に自動的に解放されます(複合文で定義されている変数の場合、複合文の終了時に自動的に解放されます).したがって,このような局所変数を自動変数と呼ぶ.のように
    int f(int a) {
        auto int b, c = 3; // a ,b, c  int  
    }
    //f  , a, b, c  
    

    静的ローカル変数


    関数内のローカル変数の値は、関数呼び出しが終了した後も消えずに元の値を保持したい場合があります.すなわち、使用されたメモリセルは解放されず、次の関数呼び出し時に前回の関数呼び出しが終了したときの値が保持されます.この場合、このローカル変数を静的ローカル変数(static local variable)と指定する必要があります.
    #include 
    using namespace std;
    int f(int a) {
        auto int b = 0;
        static int c = 3;
        b = b + 1;
        c = c + 1;
        return a + b + c;
    }
    int main(){
        int a = 2, i;
            for (int i = 0; i < 3; i++) {
               cout << f(a);
            }
            cout<

    説明
  • 静的局所変数は、静的記憶領域内に記憶ユニットを割り当てる.
  • 静的ローカル変数の初期値の割り当ては、コンパイル時に行われます.すなわち、プログラムの実行時に初期値が1回のみ割り当てられます.以降、関数を呼び出すたびに初期値は再割り当てされず、最後の関数呼び出しの終了時の値だけが保持されます.自動変数に初期値を割り当てるのは、コンパイル時に行われるのではなく、関数呼び出し時に行われ、呼び出しのたびに初期値が再与えられます.
  • ローカル変数を定義するときに初期値を付与しない場合、静的ローカル変数ではコンパイル時に初期値0(数値型変数)または空文字(文字型変数)が自動的に付与されます.自動変数では、初期値が付与されていない場合、その値は不確定です.
  • 静的局所変数は、関数呼び出しが終了した後も存在するが、他の関数は参照できない.

  • に注意
    静的ストレージはメモリを多く占め、プログラムの可読性を低下させ、呼び出し回数が多い場合、静的ローカル変数の現在の値が何であるかが不明になることが多い.必要でない場合は、静的ローカル変数を多く使用しないでください.

    レジスターでレジスタ変数を宣言する


    一般的には、変数の値はメモリに格納されます.メモリの変数をCPUのオペレータに送るには、必要に応じてください.一部の変数が頻繁に使用される場合(1つの関数で10000回のループが実行され、毎回ローカル変数が参照される)、変数へのアクセスに多くの時間がかかります.実行効率を向上させるため、C++はローカル変数の値をCPUのレジスタに置くことを許可し、必要に応じてレジスタから直接取り出して演算に参加し、メモリから取り出す必要はありません.この変数をレジスタ変数と呼ぶ.次のようになります.
    int fac(int n) {
        register int i, f = 1; // define two register variables
        for (int i = 1; i <= n; i++) {
            f = f * i;
        }
        return f;
    }
    

    注意:プログラムでレジスタ変数を定義することは、コンパイルシステムに対して推奨的であり、強制的ではない.現在の最適化コンパイルシステムでは、プログラマの指定を必要とせずに、頻繁に使用される変数を識別することができ、これらの変数をレジスタに自動的に配置することができます.

    外部変数をexternで宣言する

  • グローバル変数を1つのファイルに宣言します.外部変数がファイルの先頭に定義されていない場合、その有効な範囲は定義された場所からファイルが終了するまでのみです.定義ポイントの前の関数がグローバル変数を参照したい場合は、参照する前にキーワードexternで変数を外部変数として宣言し、その変数が以下で定義するグローバル変数であることを示します.この宣言は、事前参照宣言と呼ばれます.したがって、一般的にグローバル変数の定義は、そのすべての関数を参照する前に配置され、関数にextern宣言を追加することを避けることができます.
  • #include 
    using namespace std;
    int max(int, int); 
    
    int main(){
            extern int a, b;
           cout << max(a, b)<< endl;
        return 0;
    }
    
    int a = 15, b = -7;
    int max(int x, int y) {
            int z;
            z = x > y ? x : y;
            return z;
    }
    //  15
    
  • 外部変数を宣言する1つのC++プログラムは、1つ以上のソースプログラムファイルから構成され得る.プログラムが1つのソースファイルのみで構成されている場合、外部変数を使用する方法は前述したとおりです.もしプログラムが複数のファイルで構成されていたら?1つのプログラムに2つのファイルが含まれている場合、両方のファイルで同じ外部変数numが使用され、2つのファイルでそれぞれ1つの外部変数numをカスタマイズすることはできません.そうしないと、「繰り返し定義」とエラーが発生します.正しい方法は、いずれかのファイルで外部変数numを定義し、別のファイルでexternでnumを外部変数として宣言します.すなわち
  • extern int num;
    

    コンパイルシステムはnumが他の場所で定義された外部変数であることを知っています.まず、このファイルで外部変数numの有無を探します.もしあれば、その役割ドメインは本行に拡張され、このファイルに外部変数がなければ、プログラム接続時に他のファイルから外部変数numの有無を探します.もしあれば、別のファイルで定義された外部変数numの役割ドメインを本ファイルに拡張します.この外部変数numは、このファイルで合法的に参照できます.説明:externは、定義された外部変数のみを宣言し、変数の定義には使用できません.externが表示されると、変数を定義する文ではなく変数宣言であると判定できます.例:
    file1.cpp
    extern int a, b;
    int main() {
        cout<

    出力aは3,bは4である.

    staticで静的外部変数を宣言する


    プログラム設計では、一部の外部変数が本ファイルで参照されることに限られ、他のファイルで参照されないことが望ましい場合があります.外部変数を定義するときにstatic宣言を追加できます.例:
    file1.cpp
    static int a = 3;
    int main() {
    ...
    }
    
    
    file2.cpp
    extern int a;
    int fun(int n){
    ...
        a = a * n;
    ...
    }
    
    

    file 1.cppにはグローバル変数aが定義されていますが、staticで宣言されているため、file 2でのみ使用できます.cppファイルにはextern int aが使用されていますがfile 2.cppファイルはfile 1を使用できません.cppのグローバル変数a.このようなstatic宣言を加えて、本ファイルにのみ使用できる外部変数(グローバル変数)は静的外部変数となる.
    プログラム設計では、複数の人がそれぞれ各モジュールを完成することが多く、各人は独立してその設計されたファイルの中で同じグローバル変数で互いに関係なく使用することができる.各ファイルのグローバル変数にstaticを付けるだけです.他のファイルが本ファイルのグローバル変数を参照する必要がないことがわかっている場合は、他のファイルに誤用されないように、本ファイルのグローバル変数にstaticを加えて静的外部変数にすることができます.
    注意:外部変数は、staticを追加するかどうかにかかわらず静的ストレージ方式を採用していますが、作用範囲が異なるだけで、コンパイル時にメモリを割り当てます.