C和C++中的静态和外部全局变量

Cri*_*sti 26 c c++ static global-variables extern

我做了2个项目,第一个用C语言,第二个用C++编写,两个项目都有相同的行为.

C项目:

header.h

int varGlobal=7;
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

C++项目:

header.h

int varGlobal=7;
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

我读到默认情况下全局变量是extern,在C++中默认是C和static ; 那么为什么C++代码有效呢?

我的意思是int varGlobal = 7; static int varGlobal = 7相同; 如果它是静态的,那么它只能在它声明的文件中使用,对吧?

fba*_*ipe 77

C和C++上的全局变量extern也不static是默认值.将变量声明为时static,将其限制为当前源文件.如果你声明它extern,你说这个变量存在,但是在其他地方声明,如果你没有在其他地方声明它(没有extern关键字),你会得到一个链接错误(找不到符号).

当您有更多源文件(包括该标题)时,您的代码将中断,在链接时您将有多个引用varGlobal.如果你声明它static,那么它将使用多个源(我的意思是,它将编译和链接),但每个源将有自己的varGlobal.

您在C++中可以做的就是在C中不能将变量声明为const如下所示:

const int varGlobal = 7;
Run Code Online (Sandbox Code Playgroud)

并且包含多个来源,而不会在链接时破坏事物.我们的想法是#define为常量替换旧的C风格.

如果你需要一个全局变量上的多个来源和不可见的const,其声明为extern在头部,并再次声明,这个时候没有的extern keywork,对源文件:

多个文件包含的标题:

extern int varGlobal;
Run Code Online (Sandbox Code Playgroud)

在您的一个源文件中:

int varGlobal = 7;
Run Code Online (Sandbox Code Playgroud)

  • 正如我刚刚发现的那样,*和C++之间存在差异,但它仅适用于**const**对象:http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic =%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fconst_cv_qualifier.htm (3认同)
  • @lmiguelvargasf 如果你想用一个值初始化,在 c/cpp 文件中初始化,而不是在头文件中。所以在头文件中有 `extern int x;`,在源文件中有 `int x = 10;` (3认同)
  • 从 C++11 开始,您通常使用 `constexpr int constGlobal = 7;` 来替换旧样式的 `#define constGlobal = 7`。它保证是一个编译时常量(并且可以用作模板参数等),但仍然是类型安全的。 (2认同)

Mar*_*som 6

当您#include使用标题时,就像将代码放入源文件本身一样.在这两种情况下,varGlobal变量都在源中定义,因此无论它如何声明它都可以工作.

同样如注释中所指出的,文件范围内的C++变量在范围内不是静态的,即使它们将被分配给静态存储.例如,如果变量是类成员,则默认情况下它需要可以被程序中的其他编译单元访问,而非类成员也没有区别.

  • 此外,假设全局声明的变量在C++中默认为静态,则OP是不正确的.它们具有外部*连接*,就像在C中一样.全局变量在C和C++中具有静态*持续时间*,因此这很容易让人困惑. (3认同)