2

私が書いた

// In file t.h

#ifndef __t_h__
#define __t_h__
static int abc;
#endif

--

//In   main.c
    #include <stdio.h>
    #include "t.h"
    int main()
    {
        abc++;printf("%d \n", abc);
        test();
    }

- -

//In test.c

#include <stdio.h>
#include "t.h"

void test()
{
    abc++;
    printf("%d \n", abc);
}

プロジェクトを実行すると、outputof が見つかりましたabc is 1 and 1。しかし、それをint abcinに変更するとt.h. の出力abc = 1 and 2test.cコントロールがファイルに到達したときに static が値を保持しないのはなぜですか。保持されない場合static variable can not be shared between/among、ファイルとしてエラーを提供しないのはなぜですか?

4

4 に答える 4

9

static変数には内部リンケージがあります。これは、各翻訳単位が独自のコピーを取得することを意味します。

したがって、プログラムでは、インクルードする各.cppファイルにt.h静的変数の独自のコピーがあり、メモリ内に2 つの オブジェクトがあることになります。住所が異なるため、これを確認するために住所を印刷してみてください。

これにより、状況は非常に単純になります。一方のオブジェクトを変更しても、他方のファイルのオブジェクトはのオブジェクトであるため、.cpp他方のファイルには反映されません。なぜ変更する必要があるのですか?.cpp.cpp

しかし、それを に変更するとint abc(つまり、 にしないでくださいstatic)、各翻訳単位は同じオブジェクトを持ちます。1 つのファイルで変更すると、別のファイルにも反映されます。


共有に関しては、はい、staticオブジェクトは同じ翻訳単位内の 2 つの関数間で共有できますが、2 つの翻訳単位間で共有することはできません。

このサイトで翻訳単位を検索すると、多くのトピックが表示されます。それらを読んでください、そうすればあなたはそれを完全に理解するでしょう。

于 2012-06-27T05:47:34.723 に答える
4

ヘッダー ファイルで変数を宣言するstaticと、静的変数のコピーが、ヘッダーが含まれる各変換単位に作成されます。したがって、プログラムに含まれる各翻訳単位には独自のabcnow のコピーがあるため、観察された動作が得られます。動作は期待したものではありませんが、明確に定義されています。

static変数はファイル間で共有できませんか?

いいえ、できません!それこそがそれらを作る目的ですstatic

static変数には内部リンケージがあります。それらのスコープは、それらが宣言されている翻訳単位に制限されています。TU を超えてアクセスすることはできません。異なる翻訳単位間で同じ変数を共有する場合は、 を削除してstaticを使用する必要がありますextern。これにより、変数に外部リンケージが与えられ、異なる翻訳単位間で可視性が得られます。

よく読んでください:
extern を使用してソース ファイル間で変数を共有するにはどうすればよいですか?

于 2012-06-27T05:47:43.353 に答える
4

コードでプリプロセッサが完了すると、main.c は次のようになります。

// omitted stuff from stdio
static int abc;
int main()
{
    abc++;printf("%d \n", abc);
    test();
}

そしてtest.cは次のようになります

// omitted stuff from stdio
static int abc;
void test()
{
    abc++;
    printf("%d \n", abc);
}

abcしたがって、各ファイルには、他のファイルからアクセスできない独自の変数が含まれています。

1 つの解決策は、th を次のように変更することです。

#ifndef __t_h__
#define __t_h__
extern int abc;
#endif

次に、main.c を次のように変更します。

#include <stdio.h>
#include "t.h"
int abc;
int main()
{
    abc++;printf("%d \n", abc);
    test();
}

次のように考えることができます: プログラムには main.c に 1 つしかありませんが、test.c はint abcその存在を知っています。リンク時に見つけます。extern int abcabc

于 2012-06-27T05:59:14.490 に答える
1

C では、static次の 2 つの用途があります。

1、staticキーワードを使用して、翻訳単位内の var のスコープを制限します。これを簡単にするために、次の 2 つのファイルがありa.c、次のb.cように記述したとします。

static int varA;

ina.cの場合、これはin でvarAのみ使用できることを意味します。 ina.cを使用する場合は、キーワードを削除してinを追加する必要があります。人々が通常行うことは、: という別のファイルを作成し、 inを書き込み、単純に inにすることです。外部化したいすべての変数を記述し、単一のものを使用して、これらの変数または関数を他のファイル (つまり、ソース ファイル)で有効にすることができます。varAb.cstaticextern int varA;b.ca.hextern int varA;a.hinclude "a.h"b.ca.hinclude "a.h".c

2、関数で astaticを定義するために使用しlocal variableます。たとえば、次のようになります。

int TheFunction()
{
  static int var = 0;
  return ++var;
}

staticローカル変数でキーワードを使用したためvar、この変数は が返されても失われませんTheFunction()

最初に電話TheFunction()すると1、2 回目に電話TheFunction()すると、というように続きます2

次に、C++ での static の使用法を見てみましょう。

どの C++ コンパイラも C コードをコンパイルできるため、上記の 2 つの使用法は C++ にも当てはまります。

別の 2 つの使用法は次のとおりです。1、静的メンバー変数。2、静的メンバー関数。

コードを直接見てみましょう:

#include <iostream>

using namespace std;


class Test
{
public:
    Test() : m_nNormalVar(0)
    {

    }
public:
    // You need to init this static var outside the class
    // using the scope operator:
    // int Test::m_nStaticVar = 0;
    static int m_nStaticVar;

    // You can init this const static var in the class.
    const static int m_nConstStaticVar = 10;

    // This is just a normal member var
    int m_nNormalVar;
};
int Test::m_nStaticVar = 0;

int main(int argc, char *argv[])
{
    Test a;
    Test b;
    a.m_nStaticVar++;
    a.m_nNormalVar++;
    cout << b.m_nStaticVar << endl;
    cout << b.m_nNormalVar << endl;

    return 0;
}

aと同じbクラスのオブジェクトですが、独自のこれは静的メンバー変数です。Testm_nStaticVarm_nConstStaticVarm_nNormalVar

#include <iostream>

using namespace std;


class Utility
{
public:
    // This is a static member function, you don't
    // need to have a concrete object of this class
    // to call this function.
    static int SelectMax(int a, int b)
    {
        return a > b ? a : b;
    }
};

int main(int argc, char *argv[])
{
    // No objects of class Utility
    cout << Utility::SelectMax(2, 1) << endl;

    return 0;
}

したがって、これは C++ のクラスの静的メンバー関数です。

static のこれらの 4 つの使用方法は、私が知っているすべてです。他の使用法がまだある場合は、この投稿の編集を手伝ってください thx:)

編集:

静的グローバル関数を追加

1、staticキーワードを使用して、翻訳単位内の関数の範囲を制限します。これを簡単にするために、次の 2 つのファイルがありa.c、次のb.cように記述したとします。

static void StaticFunction();

inであるため、 ina.cのみを呼び出すことができます。この関数を in で呼び出したい場合は、キーワードを削除してから、使用前にそれを削除する必要があります。または、それを宣言するだけですStaticFunction()a.cb.cstatica.hinclude "a.h"b.c

于 2012-06-27T06:11:00.200 に答える