C 静态变量文件作用域

C 静态变量文件作用域,c,C,我有三个文件来演示如何在文件范围内使用静态变量。变量在file2.h中声明为extern,在file2.c中初始化。我在main.c中将另一个同名变量声明为static,以测试静态全局范围。但是我得到了错误消息“main.c | 6 | error:var1的静态声明跟在非静态声明之后。 有人能给我解释一下静态文件作用域的用法吗? 如果我没有在main.c中包含file2.h,我不会遇到任何问题。但是如果我需要在main.c中使用其他文件的一些函数,但仍然希望只保留此文件的变量范围,该怎么办 m

我有三个文件来演示如何在文件范围内使用静态变量。变量在file2.h中声明为extern,在file2.c中初始化。我在main.c中将另一个同名变量声明为static,以测试静态全局范围。但是我得到了错误消息“main.c | 6 | error:var1的静态声明跟在非静态声明之后。 有人能给我解释一下静态文件作用域的用法吗? 如果我没有在main.c中包含file2.h,我不会遇到任何问题。但是如果我需要在main.c中使用其他文件的一些函数,但仍然希望只保留此文件的变量范围,该怎么办

main.c

#include <stdio.h>
#include "file2.h"


static int var1;

    int main()
    {
        printf("value of staticVar1 = %d\n",var1);
        func1();
        printf("value of staticVar1 after function call= %d\n",var1);
        return 0;
    }
#include <stdio.h>
#include "file2.h"

int var1=3;

int func1(void)
{
    printf("value of staticVar1 inside the function = %d\n",var1);
    return(0);
}
#包括
#包括“file2.h”
静态int-var1;
int main()
{
printf(“staticVar1的值=%d\n”,var1);
func1();
printf(“函数调用后staticVar1的值=%d\n”,var1);
返回0;
}
file2.h

#ifndef _FILE2_H
#define _FILE2_H
#include <stdio.h>

extern int var1;

int func1(void);

#endif // _FILE2_H
\ifndef\u文件2\u H
#定义_文件2_H
#包括
外部内部变量1;
int func1(无效);
#endif/\u文件2\u H
file2.c

#include <stdio.h>
#include "file2.h"


static int var1;

    int main()
    {
        printf("value of staticVar1 = %d\n",var1);
        func1();
        printf("value of staticVar1 after function call= %d\n",var1);
        return 0;
    }
#include <stdio.h>
#include "file2.h"

int var1=3;

int func1(void)
{
    printf("value of staticVar1 inside the function = %d\n",var1);
    return(0);
}
#包括
#包括“file2.h”
int var1=3;
int func1(void)
{
printf(“函数中staticVar1的值=%d\n”,var1);
返回(0);
}

将外部声明放在头上,并将定义放在一个源文件上即可。删除

static int var1;
您应该很好。您正在使用两个正交属性限定变量:
static
extern
。前者表示它仅在内部可见,后者表示它将在外部引用。这就是您看到错误的原因

有人能给我解释一下静态文件作用域的用法吗

这意味着无论什么是
静态的
都将具有内部链接。除您定义的符号外,其他任何符号都无法看到此符号

如果我需要使用main.c中其他文件的一些函数,但仍然希望只保留该文件的变量范围,该怎么办


从标头中删除
extern
声明,并将变量仅保留在main.c中。

在文件范围中声明的对象既有外部链接也有内部链接,不能同时具有两个链接:

extern int var1;  // declare var1 an int with external linkage
int var1 = 3;     // declare and define var1 with external linkage
static int var1;  // declare and define var1 an int with internal linkage
                  // -> ERROR var1 is redeclared with different linkage
如果希望对象的可见性仅限于声明它的源文件,可以使用
静态
说明符。

\include
从字面上包括其参数的文本。如果包含“
file2.h”
,则
main.c
的顶部将同时包含这两个参数

  • extern int var1;

  • static int var1;

编译器无法判断您是否希望
var1

  • extern
    (=将其作为尚未解决的引用,引用在某些其他编译单元中定义的全局范围变量)

  • static
    (=将符号放在此处,但对其他编译单元隐藏它)

如果在main.c中声明var1 static,则表示该变量只能在该文件的编译单元中使用。 它还允许声明

static int var1
在每个.c文件中没有冲突,因为该变量未导出或对其他编译单元/c文件可见

extern int var1 
有点与静态声明相反。它表示var1变量不是在这里声明的,而是在其他地方声明的。 例如,如果有一个example.c文件在其中声明

int var1
和其他一些.c文件,您还需要在这些文件中设置和读取example.c中该变量的值。 然后在这些.c文件中声明变量

extern int var1
告诉编译器变量var1存在,但未在此处声明。
如果您忘记在example.c中真正声明变量,而在其他.c文件中与extern一起使用它,那么您应该会得到一个未定义的引用错误,我认为,因为在这种情况下,变量existance在链接时被检查

,这意味着我们不能包含一个头文件,该头文件的变量名称可能与我们打算作为静态变量的名称相同换句话说,如果您希望任何变量位于文件范围内,则不应在可能包含的头文件中定义相同的变量。因此,这意味着C的此访问控制功能具有此限制。但是,如果我们在局部范围内使用变量,则它非常干净,我们不存在此问题,并且如果它是在其他地方定义的,我们也不必担心根据各种注释,我可以说“文件范围”是静态变量吗“在C?中没有任何意义?。如果我们删除static关键字,它在文件的其余部分都会变成全局变量。那么使用静态这个词的附加值是什么呢?如果我们不包括其他头文件,无论如何也不会有任何冲突。但若包含头文件,我们就不能对头文件中的变量使用static。我看不出文件范围全局变量和文件范围静态变量之间有什么区别。或者我的理解是错误的?假设在全局范围内,您有
static int x。静态的要点是,在每个翻译单元中可以有
static int x
,这些x不会相互冲突。对于非静态全局变量,您只能执行
intx和所有其他要使用它的文件必须执行
extern int x。您可以链接具有
intx与具有
静态int x的文件但不能同时使用这两个,因为。如果要使用全局
intx,则需要为静态变量选择不同的名称extern int var1;静态int var1
编译器就像“嘿,你刚才告诉我var1是一个外部全局变量,现在你告诉我它是一个静态全局变量。这是怎么回事?”。解决方案是:为静态变量选择一个不同的名称,或者不要引用
extern