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);
}

当我运行该项目时,我发现outputabc is 1 and 1. 但是当我将其更改为int abcin 时t.h。的输出abc = 1 and 2。为什么当控件到达test.c文件时静态不保留该值。如果它不保留,那么为什么不提供static variable can not be shared between/among文件错误?

4

4 回答 4

9

static变量具有内部链接,这意味着每个翻译单元都有自己的副本。

因此,在您的程序中,每个.cpp包含的文件t.h都有自己的静态变量副本,这反过来意味着内存中有两个 对象。您可以尝试打印他们的地址以确认这一点,因为它们会有所不同。

这使情况变得非常简单:如果您更改其中的对象.cpp,它不会反映在另一个.cpp文件中,因为另一个.cpp文件中的对象是不同的对象。为什么要改变?

但是当您将其更改为int abc(即不做static)时,每个翻译单元都有相同的对象。如果您在一个文件中更改它,它也会如预期的那样反映在其他文件中。


至于共享,那么是的,static对象可以在同一个翻译单元中的两个功能之间共享,但不能在两个翻译单元之间共享。

在这个网站上搜索翻译单元,你会得到很多关于它的话题。阅读它们,然后您将完全理解它。

于 2012-06-27T05:47:34.723 回答
4

当您在头文件中声明变量时,会在包含头文件的每个翻译单元static中创建静态变量的副本。因此,您的程序中涉及的每个翻译单元都有自己的now 副本,因此您会得到观察到的行为。行为不是您所期望的,而是定义明确的行为。abc

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,其他文件无法访问。

一种解决方案是将 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();
}

你可以这样想:现在int abc你的程序中只有一个,在 main.c 但 test.c 知道它的存在,因为它extern int abc告诉 test.c 在项目的其他地方有一个整数abc,它可以在链接时找到。

于 2012-06-27T05:59:14.490 回答
1

在 C 中,static有两种用法:

1、使用static关键字限制var在翻译单元中的作用域。为了简单起见,如果您有两个文件:a.cb.c并且您写道:

static int varA;

in a.c,那么这个意思varA只能用 in a.c,如果要使用varAin b.c,你应该去掉static关键字,然后加上extern int varA;in b.c,人们通常做的就是我们创建另一个名为 :的文件a.h,然后写入extern int varA;in a.h,我们简单地include "a.h"in b.c,所以我们可以编写我们想要外部的每个变量a.h并使用单个include "a.h"变量使这些变量或函数在其他.c文件(即源文件)中合法

2、用于在函数static中定义a local variable,例如:

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

因为你static在局部变量上使用了关键字,所以这个变量在返回var时不会丢失。TheFunction()

第一次打电话TheFunction()会收到1,第二次打电话TheFunction()会收到2,以此类推。

接下来,让我们看看静态在 C++ 中的用法。

因为任何 C++ 编译器都可以编译 C 代码,所以上面的 2 个用法也在 C++ 中。

另外两种用法是: 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是类的对象,Test它们具有相同m_nStaticVar的和相同的m_nConstStaticVar,但它们有自己的m_nNormalVarthis 是一个静态成员变量。

#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的用法我都知道了,如果还有其他用法,请帮忙编辑本帖,thx:)

编辑:

添加静态全局函数

1、使用static关键字限制函数在翻译单元中的作用域。为了简单起见,如果您有两个文件:a.cb.c并且您写道:

static void StaticFunction();

in a.c,所以你只能调用StaticFunction()in a.c,如果你想调用这个函数,b.c你应该删除static关键字,然后在使用前删除它。或者只是在里面声明a.hinclude "a.h"b.c

于 2012-06-27T06:11:00.200 回答