関数の外で静的変数を宣言することと、関数内で静的変数を宣言することの間に違いはありますか?
また、変数を static として宣言することと、単に extern 変数を宣言することの違いは何ですか?
違いは、関数内の静的変数は関数内でのみ可視であるのに対し、外部の静的変数は宣言のポイントから翻訳単位の最後まで、どの関数からも参照できることです。
それ以外の場合は、同じように動作します。
キーワードなしで関数の外部で変数を宣言するstatic
ということは、それが定義されているファイル (翻訳単位) の外部 (および定義の時点から翻訳単位の最後まで) に見える (アクセスできる) ことを意味します。変数を として宣言する場合extern
、それは別の場所に定義があることを意味します。おそらく同じ翻訳単位にありますが、別の翻訳単位にある可能性が高くなります。関数内で extern 変数を宣言することは可能ですが、関数の外でしか定義できないことに注意してください。
最初の例:
class SoTest
{
public:
SoTest(const char *name)
{
printf("C'tor called of %s\t(%#x) object\n",name,this);
}
static SoTest ClassStaticObj;
};
static SoTest CStaticObj("CStaticObj");
SoTest SoTest::ClassStaticObj("ClassStaticObj");
void function()
{
for (int i = 0; i < 2;i++)
{
static SoTest FunctionStaticObj("FunctionStaticObj");
SoTest FunctionObj("FunctionObj");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("enter main\n");
function();
function();
getchar();;
return 0;
}
生成:
C'tor called of CStaticObj (0x419168) object
C'tor called of ClassStaticObj (0x419169) object
enter main
C'tor called of FunctionStaticObj (0x419160) object
C'tor called of FunctionObj (0x12fe77) object
C'tor called of FunctionObj (0x12fe77) object
C'tor called of FunctionObj (0x12fe77) object
C'tor called of FunctionObj (0x12fe77) object
今あなたの質問
関数の外で静的変数を宣言することと、関数内で静的変数を宣言することの間に違いはありますか?
これらは完全に異なる問題であり、関数外の静的変数/関数はコンパイル単位の外では見えません。
関数内の static 変数はグローバル データに割り当てられ、最初の発生時に 1 回だけ初期化されます (FunctionStaticObj が他のオブジェクトと矛盾して main の後に初期化されたことを確認してください。
また、変数を static として宣言することと、単に extern 変数を宣言することの違いは何ですか?
ここでも静的とは、コンパイル単位の外では見えないことを意味します。
extern は、「ここでは定義されていませんが、別のコンパイル ユニットとリンカで管理されます」を意味するため、必要な数の extern 宣言を作成できますが、非 extern 定義は 1 つだけです。