C言語変数格納カテゴリとメモリ四領域

4580 ワード

変数格納カテゴリ
変数宣言/定義の一般的な形式:
         

ストレージカテゴリとは、データをメモリに格納する方法です.ストレージ方法は静的ストレージと動的ストレージの2つに分類される.標準C言語では、変数、定数、関数の4つのストレージタイプが定義されています.extern、auto、static、registerです.変数の格納カテゴリによって、変数の役割ドメインと格納期間がわかります.この4つのストレージタイプは、永続的(プログラム実行期間全体に存在する)と一時的(スタックとレジスタに一時的に保存される)の2つの生存期間に分けることができます.externおよびstaticは、永続的な生存期間を識別する「変数および関数」に使用され、antoおよびregisterは、一時的な生存期間を識別する「変数」に使用されます.変数だけが一時的な生存期間を持つ.1つの変数と関数には、1つのストレージタイプと1つの生存期間しかありません.
ユーザーが使用できるメモリの容量は、次の3つです.
  • プログラム領域:プログラムの実行可能コードを格納する.
  • 静的記憶領域:静的変数(グローバル変数と静的ローカル変数)を格納する.
  • 動的記憶領域:関数呼び出し時に呼び出される関数のフィールド保護と戻りアドレス、関数パラメータ、自動ローカル変数を格納する.

  • 変数の宣言は「定義的宣言」(int aなどのストレージスペースを確立する必要がある)に分けられます.および「参照宣言」(extern aなどのストレージスペースを確立する必要はありません).広義には、宣言には定義が含まれており、一般的には記述が便利であるため、記憶空間を構築する宣言を定義と呼び、記憶空間を構築する必要がない宣言を宣言と呼ぶ.
    auto
    関数のローカル変数は、キーワードstaticで宣言されない場合、コンパイルシステムがストレージスペースを動的に割り当てます.関数のパラメータと、複合文で定義された変数を含む関数で定義された変数は、このようなものです.この関数を呼び出すと、システムはパラメータと関数で定義された変数に記憶領域を割り当て、データは動的記憶領域に格納されます.これらのスペースは、関数呼び出しが終了すると自動的に解放されます.複合文で定義された変数の場合、変数定義時に記憶領域が割り当てられ、複合文の終了時に自動的に領域が解放されます.従って、このような局所変数を自動変数(auto variable)と呼ぶ.自動変数はキーワードautoを格納カテゴリの宣言として使用します.
    自動変数に初期値を割り当てるのは、コンパイル時に行われるのではなく、関数呼び出し時に行われます.自動変数では、初期値を割り当てないと、その値は不確定な値になります.
    int Fun(int a)
    
    {
    
        auto int b, c=3; // b c ,auto 
    
        b = c + a;
    
        return b;
    
    }

    register
    一般に、変数の値はメモリに格納されます.プログラムでどの変数の値を使用するかは、コントローラからCPUの演算子にメモリの値を送るよう指示されます.オペレータを介して演算を行い、必要に応じて数を格納し、オペレータからメモリにデータを格納します.実行効率を向上させるため、C++はローカル変数の値をCPUのレジスタに置くことを許可し、メモリにアクセスする必要がなく、レジスタから直接参加演算を取り出す必要がある.この変数をレジスタ変数と呼び,キーワードregisterで宣言する.レジスタ変数の割り当て方式は動的に割り当てられる.
    CPUにおける汎用レジスタの数は限られているため,通常は少数の頻繁に使用される変数のみをレジスタ変数として定義する.レジスタ数を超えたレジスタ変数に対して一般自動変数処理を行う.
    ローカル自動変数と形式パラメータのみがレジスタ変数として使用でき、その他(グローバル変数、ローカル静的変数など)はできません.プログラムでレジスタ変数を定義することは、コンパイルシステムに対して推奨的であり(強制的ではない).現在の最適化コンパイルシステムは、頻繁に使用される変数を識別し、これらの変数をレジスタに自動的に配置することができる.
    extern
    グローバル変数(外部変数)は、関数の外部で定義され、その役割ドメインは変数の定義から、このプログラムファイルの最後までです.この役割ドメインでは、グローバル変数は、このファイルの各関数に参照できます.コンパイル時にグローバル変数を静的ストレージ領域に割り当てます.グローバル変数をexternで宣言して、グローバル変数の役割ドメインを拡張する必要がある場合があります.
    1)グローバル変数を1つのファイルに宣言
    外部変数がファイルの先頭で定義されていない場合、その有効な作用範囲は定義からファイル終了までに限られます.ポイントを定義する前の関数がグローバル変数を参照したい場合は、参照する前にキーワードexternで変数を外部変数として宣言し、変数が以下で定義されるグローバル変数であることを示します.この宣言があれば、宣言からグローバル変数を合法的に参照できます.この宣言は、事前参照宣言と呼ばれます.
    外部変数をexternで宣言する場合、タイプ名は書き込み可能か書き込み不可かです.例えば、「extern int A,B;」「extern A,B;」と書くこともできます.
    2)複数ファイルのプログラムで外部変数を宣言する
    1つのプログラムに2つのファイルが含まれている場合、2つのファイルで同じ外部変数numを使用する必要があります.2つのファイルでそれぞれ1つの外部変数numをカスタマイズすることはできません.正しい方法は、いずれかのファイルで外部変数numを定義し、別のファイルではexternでnumを外部変数として宣言します.すなわち、「extern int num」または「extern num」です.コンパイルシステムはnumが他の場所で定義されている外部変数であることを知っています.まず、このファイルで外部変数numの有無を探し、ある場合はその役割ドメインを本行に拡張し、このファイルに外部変数がない場合は、プログラム接続時に他のファイルから外部変数numの有無を探し、ある場合は別のファイルで定義された外部変数numの役割ドメインを本ファイルに拡張します.この外部変数numは、このファイルで合法的に参照できます.
    static
    すべてのグローバル変数とキーワードstaticを格納タイプとして説明するローカル変数を静的変数と呼ぶ.静的変数は静的記憶領域に格納され、記憶部が割り当てられると、プログラム実行中にこれらの記憶部が固定的に占有される.必要でない場合は、静的ローカル変数を多く使用しないでください.
    グローバル変数に対してstaticはローカル化(ローカルは本ファイル)され、静的グローバル変数は本ソースファイルの各関数でのみ使用でき、本ソースファイル以外の他のソースファイルでは使用できません.
    ローカル変数の場合、staticはダイナミックストレージから静的ストレージに変更され、静的ローカル変数は本関数でのみ使用でき、他の関数では使用できず、影響しません.静的ローカル変数は、コンパイル時に初期値を付与し、一度だけ初期値を付与します.ローカル変数を定義するときに初期値を付与しない場合、静的ローカル変数では、コンパイル時に0(数値型変数)または空の文字(文字変数)が自動的に付与されます.
    注意:
    内部関数は静的関数とも呼ばれ、他のファイルの関数では使用できません.内部関数を定義する場合は、関数名と関数タイプの前にstaticを付けます.
    C言語では、関数の前にキーワードexternがない場合は、外部関数として隠します.この外部関数を他のファイルの関数で呼び出すには、呼び出されたファイルでexternで宣言するだけです.
    メモリ4
    スタック領域(stack)はコンパイラによって自動的に割り当てられて解放され、関数のパラメータ値、局所変数の値などが格納される.その動作は、データ構造内のスタックに似ています.
    スタック領域(heap)は一般的にプログラマによって解放(ダイナミックメモリ申請と解放)が割り当てられ、プログラマが解放されない場合、プログラム終了時にオペレーティングシステムによって回収される可能性がある.データ構造のスタックとは異なることに注意してください.割り当て方法はチェーンテーブルに似ています.
    グローバル領域/静的領域(static)グローバル変数と静的変数の記憶は一緒に置かれ、初期化されたグローバル変数と静的変数は、プログラムが終了した後にオペレーティングシステムによって解放される、初期化されていないグローバル変数と初期化されていない静的変数とが隣接する別の領域に配置される.定数領域:文字列定数およびその他の定数の格納場所.プログラムが終了するとオペレーティングシステムによって解放されます.
    プログラムコード領域(code)は、関数のバイナリコードを格納する.
    関数呼び出しモデルは、プログラムの4つのメモリ領域と統合して考慮する必要があります.
  • プライマリコール関数に割り当てられたメモリ(スタック領域、スタック領域、グローバル領域)は、呼び出された関数で使用できます.
  • 呼び出された関数に割り当てられたメモリは、スタック領域に割り当てられたメモリは、プライマリコール関数では使用できません.