C++変数の役割ドメインと宣言周期

7116 ワード

C++変数には、2つのプロパティが重要です.2つの異なる次元から1つの変数-時間と空間を記述する役割ドメインとライフサイクルです.名前の通り、役割ドメインは変数が参照できる範囲です.例えば、グローバル役割ドメイン、ファイル役割ドメイン、ローカル役割ドメインなどです.ライフサイクルは、この変数が参照できる期間です.異なるライフサイクルの変数では、プログラムメモリ内の分布位置が異なります.1つのプログラムのメモリは、コード領域、グローバルデータ領域、スタック領域、スタック領域に分けられ、異なるメモリ領域は、異なるライフサイクルに対応します.変数の役割ドメインとライフサイクルを指定する方法はたくさんあります.最も一般的なのは、{}、static修飾子などです.次は、役割ドメインとライフサイクルに基づいて変数を分類します.
1.グローバル変数役割ドメイン:グローバル役割ドメイン(グローバル変数は1つのソースファイルで定義するだけで、すべてのソースファイルに適用されます.)ライフサイクル:プログラムの実行中に参照メソッドが常に存在します.他のファイルでは、参照するグローバル変数をexternキーで宣言する必要があります.メモリ分散:グローバルデータ領域注意:両方のファイルで同じ名前のグローバル変数が定義されている場合、接続エラー:変数再定義グローバル静的変数役割ドメイン:ファイル役割ドメイン(定義されたファイルにのみ表示されます.)ライフサイクル:プログラム実行期間にはメモリ分布が常に存在します.グローバルデータ領域定義方法:staticキーワード、constキーワード注意:ファイルが互いに含まれていない限り、2つの異なるファイルでは完全に同じ2つの静的変数を定義できます.これらは2つの完全に異なる変数の静的ローカル変数です.役割ドメイン:ローカル役割ドメイン(ローカル役割ドメインでのみ表示)ライフサイクル:プログラム実行期間にメモリ分布が常に存在する:グローバルデータ領域定義方法:ローカル役割ドメイン用中用static定義注意:一度だけ初期化され、マルチスレッドでローカル変数役割ドメインをロックして保護する必要がある:ローカル役割ドメイン(ローカル役割ドメインのみで表示される)ライフサイクル:プログラムがローカル役割ドメインを実行するとメモリ分布が破棄されます.スタック領域注意:autoインジケータ表示には、staticキーワードの使用を把握する上で重要な点があります.以下は、他の人の経験を引用した話です.Tips:グローバル変数が単一のCファイルにのみアクセスされている場合は、この変数をモジュール間の結合度を低減するために静的グローバル変数;グローバル変数が単一の関数のみからアクセスされる場合、この変数を関数の静的ローカル変数に変更して、モジュール間の結合度を低減することができる.動的グローバル変数、静的グローバル変数、静的ローカル変数にアクセスする関数を設計および使用する場合は、静的データストレージ領域に配置され、グローバルに表示されるため、リダイレクトの問題を考慮する必要があります.再入力可能な関数が必要な場合は、関数でstatic変数(このような関数は「内部メモリ」機能付きの関数と呼ばれる)関数でstatic変数を使用する必要があることを避けなければなりません.たとえば、関数の戻り値がポインタタイプの場合、autoタイプの場合、staticのローカル変数のアドレスを戻り値としなければなりません.エラーポインタとして返されます.
2.変数のタイプ:1.ローカル変数とグローバル変数ローカル変数は、内部変数とも呼ばれます.ローカル変数は、関数内で定義されます.その役割ドメインは関数内に限られており,その関数を離れてからこの変数を使用するのは違法である.
           ,            。         ,          。 
         。          ,          。               
     。          extern。               ,           
   。

変数の役割ドメイン(グローバル役割ドメイン、ローカル役割ドメイン、ファイル役割ドメイン)(すなわち空間)の観点から、グローバル変数(静的グローバル変数の役割ドメインは、このファイル範囲(ファイル役割ドメイン)のローカル変数である.
別の角度から、変数値が存在する作時間(すなわち生存期間)の観点から、静的記憶方式と動的記憶方式に分けることができる.生存周期は変数記憶の位置にのみ関連していることがわかる.
auto  :
            ,        static     ,            , 
             。                (            
    ),    ,                   ,            
          。            。         auto         。
       auto    ,auto        “      ”,        。

ローカル変数をstaticで宣言する:関数内のローカル変数の値が関数呼び出し終了後に消えずに元の値を保持したい場合があります.この場合、ローカル変数を「静的ローカル変数」と指定し、キーワードstaticで[転載]C言語内の変数の役割ドメインとライフサイクルを宣言する必要があります.
  register  :
          ,C               CPU       ,     “     ”, 
        register    。
    1)                        ;
    2)                  ,             ;
    3)                  


   extern      :
        (     )          ,              , 
           。               ,               
       。                   ,             extern
        “      ”。                 。     ,  
     “  ”  ,          。

まとめ:
役割ドメインから次のように分類されます.
             -       auto,       (    ,   )
         -         static(    ,    )
             -          register(    ,   )
             -                  register  

             -        (          ,     )
         -      (       ,    ,         )

変数の生存周期から分ける:-自動変数auto動的記憶-レジスタ変数register-形式パラメータ
            -        
        -        
            -      (    )

変数値から格納される場所:
                                    -        
         (     )      -        
                                    -      (    )


                          -      auto
         ( )    -      


CPU        -      register

局所静的(static)変数で、役割ドメインは局所的であり、ライフサイクルは全行程である.静的局所変数は静的記憶方式に属し、(1)静的局所変数は関数内で定義されるが、自動変数のように呼び出し時に存在し、関数を終了すると消失するという特徴がある.静的局所変数は常に存在し,すなわちその生存期間はソースプログラム全体である.(2)静的局所変数の生存期間はソースプログラム全体であるが,その役割ドメインは自動変数と同様であり,すなわち変数を定義する関数内でのみ使用できる.この関数を終了すると、変数はまだ存在しますが、使用できません.3.C++の変数名上書き問題C++言語学習において古典的なコードプログラムは以下の通りである.
////警告:この例のコードは、プレゼンテーションC++の変数名にのみ問題を上書きします.実際の符号化では使用しないでください.//同じ名前の空間で同じ名前の変数を宣言しないで、良い符号化スタイルに従ってください.
#include 

float demo_var = 2.0;   // declaration of global variable named as 'demo_var'

float foo();

int main(int argc, char **argv)
{
    printf("Global demo_var = %f.
"
, demo_var); float demo_var = 888888.8; // local variable in main() name as 'demo_var' also. float ret = foo(); printf("The return value for foo() is : %f.
"
, ret); printf("in main(): demo_var = %f, ::demo_var = %f.
"
, demo_var, ::demo_var); return 0; } float foo() { float demo_var = 99.99; // auto variable in foo() with the name 'demo_var' too. printf("Local demo_var = %f, global demo_var = %f.
"
, demo_var, ::demo_var); return demo_var; }

デモという名前を見てみましょうvarの変数は前後3回宣言され、青色のフォントで表示されます.1.demo_というグローバル変数を定義します.var、初期値は2.0である.プログラムが実行されると、この変数のメモリアドレスはグローバルdataセグメントにあります.2.main関数にdemo_という自動変数を宣言します.var、初期値は888888.8です.この変数メモリアドレスはmain関数スタックにあります.3.foo関数でdemo_という自動変数を宣言var、初期値は99.99です.この変数メモリアドレスはfoo関数スタックにあります.
もう一度見てみましょう.この3つの同名変数は、プログラムの実行中にいつ作成されましたか.コードを実行可能プログラムにコンパイルし、コマンドライン(または他の方法)でプログラムを起動し、オペレーティングシステムがプロセスを作成し、まず実行環境を設定すると、グローバル変数(1回目の定義)がdataメモリセグメントで作成されます.オペレーティングシステムはmain()関数を呼び出し、印刷文を出力します(main関数のdemo_var定義文がまだ実行されていないため、この行はグローバル変数値を出力します).main()関数はdemo_varというローカル自動変数(他の変数名を取ることもできます)を定義します.この変数はmain関数スタックでmain関数が終了すると自動的に解放されます.
main関数はfoo関数を呼び出し、foo関数スタックは作成されます.foo関数スタックにdemo_という変数を作成します.var(同様に別の名前を取るべきでもある)、印刷文はdemo_varがfoo関数スタックで定義された変数である(怠け者であるため、遠くのdataメモリセグメントに走ってグローバルのdemo_varを読みたくないが、main関数スタック空間はそれに対して見えない)と考え、グローバルのdemo_varにアクセスしたい場合、C++はグローバル空間オペレータを提供する::foo関数の終了時にdemo_varに戻る(foo関数でローカルに定義された)値は呼び出し元に与えられます.
main関数は、foo戻り値を出力する印刷文を実行し、main関数定義の変数demo_を出力します.var,同様にグローバルなdemo_を出力するvarは、C++言語がネーミング(関数名、変数名、クラス名など)の競合の問題を解決するためにネーミング空間を提供していることを見ることができます.異なる空間には同じ名前の変数がありますが、同じエンティティではありません.コンピュータプログラムでは、同じエンティティは同じメモリアドレスに存在し、同じタイプを有しています.
このコードをC++コンパイラでコンパイルしてください.ほとんどのCコンパイラは認識できません.演算子(C++のグローバル空間演算子)プログラムコンパイルの実行結果は以下の通りです.Global demo_var=2.00000.Local demo_var=99.99998、global demo_var=2.00000.The return value for foo()is:99.99998.in main(): demo_var = 888888.812500,::demo_var = 2.000000.