我在
写道// 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);
}
当我运行项目时,我找到了output
abc is 1 and 1
。
但是当我在int abc
中将其更改为t.h
时。 abc = 1 and 2
的输出。
当控件到达test.c
文件时,为什么static不保留该值。
如果它不会保留,那么为什么它不应该像static variable can not be shared between/among
文件那样提供错误?
答案 0 :(得分:9)
static
变量具有内部链接,这意味着每个翻译单元都有自己的副本。
因此,在您的程序中,包含.cpp
的每个t.h
文件都有自己的静态变量副本,而这又意味着两个 对象< / em>在记忆中。您可以尝试打印他们的地址以确认这一点,因为它们会有所不同。
这使得情况非常简单:如果您在一个.cpp
中更改对象,则它不会反映在另一个.cpp
文件中,因为另一个.cpp
文件中的对象是一个不同的对象。为什么要改变?
但是当您将其更改为int abc
(即不使其为static
)时,则每个翻译单元都具有相同的对象。如果您在一个文件中更改它,它也会按预期反映在其他文件中。
至于共享,是的,static
对象可以在相同翻译单元中的两个函数之间共享,但它们不能在两个翻译单元之间共享。
在本网站上搜索翻译单元,您将获得许多主题。阅读它们,然后你就会完全理解它。
答案 1 :(得分:4)
当您在标头文件中声明static
变量时,会在每个 Translation unit 中创建静态变量的副本,其中包含标头。因此,您的程序中涉及的每个翻译单元现在都有自己的abc
副本,因此您可以获得观察到的行为。行为不是您所期望的,但它定义得很好。
static
变量无法在文件之间共享?
不,他们不可能!这就是让他们static
static
个变量有 internal linkage 。它们的范围仅限于声明它们的翻译单位。如果您想在不同的翻译单元之间共享相同的变量,则应该删除static
并使用extern
,这会为变量提供 外部链接 ,因此可以看到不同的翻译单元。
好读:
How do I use extern to share variables between source files?
答案 2 :(得分: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
,而另一个变量#ifndef __t_h__
#define __t_h__
extern int abc;
#endif
无法访问。
一种解决方案是将t.h更改为
#include <stdio.h>
#include "t.h"
int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
然后将main.c更改为
int abc
你可以这样思考:现在你的程序中只有一个extern int abc
,在main.c中但是test.c知道它的存在,因为abc
告诉test.c在其他地方在项目中有一个名为{{1}}的整数,它可以在链接时找到。
答案 3 :(得分:1)
在C中,static
有两种用法:
1,使用static
关键字来限制翻译单元中var的范围。为简单起见,如果您有两个文件:a.c
,b.c
并且您写道:
static int varA;
在a.c
中,这意味着varA
只能在a.c
中使用,如果您想在varA
中使用b.c
,则应删除static
关键字,并在extern int varA;
中添加b.c
,人们通常会做的是创建另一个名为a.h
的文件,并在extern int varA;
中编写a.h
我们只是include "a.h"
中的b.c
,因此我们可以在a.h
中编写我们想要的所有变量,并使用单个include "a.h"
使这些变量或函数合法化其他.c
个文件(即源文件)
2,使用static
在函数中定义local variable
,例如:
int TheFunction()
{
static int var = 0;
return ++var;
}
由于您在本地变量static
上使用了var
关键字,因此在返回TheFunction()
时此变量不会丢失。
第一次拨打TheFunction()
时,您将获得1
,第二次拨打TheFunction()
时,您将获得2
,依此类推。
接下来,让我们看一下C ++中static的用法。
因为任何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_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 ++中类的静态成员函数。
这四种静态使用方式都是我所知道的,如果还有其他一些用法,请帮助编辑这篇文章,thx:)
修改强>
添加静态全局功能
1,使用static
关键字限制翻译单元中的功能范围。为简单起见,如果您有两个文件:a.c
,b.c
并且您写道:
static void StaticFunction();
<{1>}中的,因此您只能在a.c
中拨打StaticFunction()
,如果您想在a.c
中调用此功能,则应删除b.c
关键字然后在使用前进行delcare。或者只是在static
和a.h
include "a.h"
和b.c
中声明