48

static、、および変数について少し混乱していautoます。globallocal

どこかで、static変数は関数内でのみアクセスできると読みましたが、関数が戻った後も変数はまだ存在しています(メモリに残っています)。

しかし、local変数も同じことをすることも知っているので、違いは何ですか?

4

6 に答える 6

91

ここには2つの別個の概念があります。

  • 名前にアクセスできる場所を決定するスコープ、および
  • 変数がいつ作成および破棄されるかを決定するストレージ期間。

ローカル変数(基本的には、ブロックスコープを持つ変数)は、宣言されているコードのブロック内でのみアクセスできます。

void f() {
    int i;
    i = 1; // OK: in scope
}
void g() {
    i = 2; // Error: not in scope
}

グローバル変数(基本的に、ファイルスコープ(Cの場合)または名前空間スコープ(C ++の場合)を持つ変数)は、宣言後の任意の時点でアクセスできます。

int i;
void f() {
    i = 1; // OK: in scope
}
void g() {
    i = 2; // OK: still in scope
}

(C ++では、名前空間を閉じて再度開くことができ、現在のスコープ以外のスコープにアクセスでき、名前にもクラススコープを含めることができるため、状況はより複雑になります。しかし、それは非常に話題から外れています。)

自動変数(通常、自動保存期間のある変数)は、実行がスコープを離れると存続期間が終了するローカル変数であり、スコープが再入力されると再作成されます。

for (int i = 0; i < 5; ++i) {
    int n = 0;
    printf("%d ", ++n);  // prints 1 1 1 1 1  - the previous value is lost
}

静的変数(厳密には、静的ストレージ期間を持つ変数)の有効期間は、プログラムが終了するまで続きます。それらがローカル変数である場合、実行がスコープを離れても、それらの値は保持されます。

for (int i = 0; i < 5; ++i) {
    static int n = 0;
    printf("%d ", ++n);  // prints 1 2 3 4 5  - the value persists
}

staticキーワードには、静的保存期間以外にもさまざまな意味があることに注意してください。グローバル変数または関数では、他の変換ユニットからアクセスできないように内部リンクを提供します。C ++クラスのメンバーでは、オブジェクトごとに1つではなく、クラスごとに1つのインスタンスがあることを意味します。また、C ++では、autoキーワードは自動保存期間を意味しなくなりました。これは、変数の初期化子から推定される自動型を意味するようになりました。

于 2012-11-16T11:26:35.477 に答える
12

まず第一に、これは多くの場所で詳細に定義されているため、グーグルで検索する必要があると言います。

ローカル
これらの変数は、それらを作成する特定の関数内にのみ存在します。それらは他の機能やメインプログラムには知られていません。そのため、通常はスタックを使用して実装されます。ローカル変数は、それらを作成した関数が完了すると存在しなくなります。これらは、関数が実行または呼び出されるたびに再作成されます。

グローバル
これらの変数は、プログラムを構成する任意の関数からアクセスできます(つまり、既知です)。これらは、メモリ位置を変数名に関連付けることによって実装されます。関数が呼び出されても、それらは再作成されません。

/* Demonstrating Global variables  */
    #include <stdio.h>
    int add_numbers( void );                /* ANSI function prototype */

    /* These are global variables and can be accessed by functions from this point on */
    int  value1, value2, value3;

    int add_numbers( void )
    {
        auto int result;
        result = value1 + value2 + value3;
        return result;
    }

    main()
    {
        auto int result;
        value1 = 10;
        value2 = 20;
        value3 = 30;        
        result = add_numbers();
        printf("The sum of %d + %d + %d is %d\n",
            value1, value2, value3, final_result);
    }


    Sample Program Output
    The sum of 10 + 20 + 30 is 60

グローバル変数の範囲は、宣言を注意深く配置することで制限できます。それらは、宣言から現在のソースファイルの終わりまで表示されます。

#include <stdio.h>
void no_access( void ); /* ANSI function prototype */
void all_access( void );

static int n2;      /* n2 is known from this point onwards */

void no_access( void )
{
    n1 = 10;        /* illegal, n1 not yet known */
    n2 = 5;         /* valid */
}

static int n1;      /* n1 is known from this point onwards */

void all_access( void )
{
    n1 = 10;        /* valid */
    n2 = 3;         /* valid */
}

静的:
静的オブジェクトは、作成されてからプログラムが終了するまで存続するオブジェクトです。したがって、スタックオブジェクトとヒープオブジェクトは除外されます。ただし、グローバルオブジェクト、名前空間スコープのオブジェクト、クラス/関数内で静的に宣言されたオブジェクト、およびファイルスコープで宣言されたオブジェクトは静的オブジェクトに含まれます。プログラムの実行が停止すると、静的オブジェクトは破棄されます。このチュートリアルリスト
をご覧になることをお勧めしますAUTO: C、C ++


(自動変数と呼ばれます。)

コードブロック内で宣言されたすべての変数はデフォルトで自動ですが、これはautoキーワードで明示的にすることができます。[注1]初期化されていない自動変数は、そのタイプの有効な値が割り当てられるまで未定義の値になります。[1]

autoの代わりにストレージクラスレジスタを使用することは、変数をプロセッサレジスタにキャッシュするためのコンパイラへのヒントです。参照演算子(&)を変数またはそのサブコンポーネントで使用できないようにする以外は、コンパイラーはヒントを自由に無視できます。

C ++では、実行が宣言の場所に到達すると、自動変数のコンストラクターが呼び出されます。デストラクタは、指定されたプログラムブロックの最後に到達したときに呼び出されます(プログラムブロックは中括弧で囲まれています)。この機能は、ファイルを開いて自動的に閉じたり、メモリを解放したりするなど、リソースの割り当てと割り当て解除を管理するためによく使用されます。ウィキペディアを見る

于 2012-11-16T11:11:23.753 に答える
4

違いは、静的変数はそれらの変数です。これにより、関数の1つの呼び出しから別の呼び出しまで値を保持できます。ただし、ローカル変数の場合、スコープはブロック/関数の有効期間までです。

例えば:

#include <stdio.h>

void func() {
    static int x = 0; // x is initialized only once across three calls of func()
    printf("%d\n", x); // outputs the value of x
    x = x + 1;
}

int main(int argc, char * const argv[]) {
    func(); // prints 0
    func(); // prints 1
    func(); // prints 2
    return 0;
}
于 2012-11-16T11:18:33.803 に答える
3

関数の終了後、ローカル変数はメモリに存在しません。
ただし、static変数は、関数に関係なく、プログラムの存続期間を通じてメモリに割り当てられたままになります。

さらに、あなたの質問から、static変数はローカルclassまたは関数スコープで宣言でき、グローバルにnamespaceまたはファイルスコープで宣言できます。それらには最初から最後までメモリが割り当てられます。遅かれ早かれ起こるのは初期化だけです。

于 2012-11-16T11:09:21.780 に答える
3

staticCおよびC++では非常にオーバーロードされた単語です。static関数のコンテキスト内の変数は、呼び出し間で値を保持する変数です。それらはプログラムの期間中存在します。

ローカル変数は、関数の存続期間中、またはそれらを囲むスコープが何であれ、存続します。例えば:

void foo()
{
    int i, j, k;
    //initialize, do stuff
} //i, j, k fall out of scope, no longer exist

このスコープは、{ }ブロックで意図的に使用される場合があります。

{ 
   int i, j, k;
   //...
} //i, j, k now out of scope

プログラムの期間中、グローバル変数が存在します。

autoCとC++では異なります。autoCでは、ローカル変数を指定する(不要な)方法でした。C ++ 11ではauto、値/式のタイプを自動的に導出するために使用されるようになりました。

于 2012-11-16T11:14:29.273 に答える
2

変数がクラス内で静的であると宣言されると、その変数はそのクラスのすべてのオブジェクトの共有変数になります。つまり、変数は任意のオブジェクトに固有のものではなくなります。例えば: -

#include<iostream.h>
#include<conio.h>
class test
{
    void fun()
    {
        static int a=0;
        a++;
        cout<<"Value of a = "<<a<<"\n";
    }
};
void main()
{
    clrscr();
    test obj1;
    test obj2;
    test obj3;
    obj1.fun();
    obj2.fun();
    obj3.fun();
    getch();
}

このプログラムは、次の出力を生成します。

Value of a = 1
Value of a = 2
Value of a = 3

グローバルに宣言された静的変数についても同じことが言えます。上記のコードは、変数を外部関数void fun()として宣言した場合、同じ出力を生成します。

一方、uがキーワードstaticを削除し、aを非静的ローカル/グローバル変数として宣言すると、出力は次のようになります。

Value of a = 1
Value of a = 1
Value of a = 1
于 2016-11-25T15:10:34.970 に答える