web-dev-qa-db-ja.com

CおよびC ++の静的および外部グローバル変数

私は2つのプロジェクトを作成しました。最初のプロジェクトはCで、2番目のプロジェクトはC++で、どちらも同じ動作をします。

Cプロジェクト:

header.h

int varGlobal=7;

main.c

#include <stdio.h>
#include <stdlib.h>
#include "header.h"

void function(int i)
{
    static int a=0;
    a++;
    int t=i;
    i=varGlobal;
    varGlobal=t;
    printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t);
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

C++プロジェクト:

header.h

int varGlobal=7;

main.cpp

#include <iostream>
#include "header.h"
using namespace std;

void function(int i)
{
    static int a=0;
    int t=i;
    a++;
    i=varGlobal;
    varGlobal=t;
    cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl; 
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

グローバル変数は、デフォルトではCでexternであり、C++ではデフォルトでstaticであると読みました。では、なぜC++コードが機能するのでしょうか?

つまり、int varGlobal = 7;static int varGlobal = 7;と同じで、静的な場合にのみ使用できますファイル内で宣言されましたよね?

26
Cristi

グローバル変数は、CおよびC++ではデフォルトでexternでもstaticでもありません。変数をstaticとして宣言すると、現在のソースファイルに制限されます。 externとして宣言すると、変数は存在するが別の場所で宣言されていると言っており、他の場所で(externキーワードなしで)宣言していない場合は、リンクエラー(シンボルが見つかりません)。

そのヘッダーを含むソースファイルがさらにあると、コードは壊れます。リンク時に、varGlobalへの複数の参照があります。 staticとして宣言すると、複数のソースで動作します(つまり、コンパイルしてリンクします)が、各ソースには独自のvarGlobalがあります。

Cではできない、C++でできることは、次のようにヘッダーで変数をconstとして宣言することです。

const int varGlobal = 7;

リンク時に物事を壊すことなく、複数のソースに含めます。考え方は、古いCスタイル#define定数用。

constではなく複数のソースで表示できるグローバル変数が必要な場合は、ヘッダーでexternとして宣言し、今回はソースファイルでexternキーワークなしで再度宣言します。

複数のファイルに含まれるヘッダー:

extern int varGlobal;

ソースファイルのいずれか:

int varGlobal = 7;
76
fbafelipe

#includeヘッダー。ソースファイル自体にコードを挿入した場合とまったく同じです。どちらの場合も、varGlobal変数はソースで定義されているため、どのように宣言されていても機能します。

また、コメントで指摘されているように、ファイルスコープのC++変数は、静的ストレージに割り当てられますが、スコープ内で静的ではありません。たとえば、変数がクラスメンバである場合、デフォルトでプログラム内の他のコンパイルユニットにアクセスできる必要があり、非クラスメンバも同じです。

6
Mark Ransom