我正在尝试一个小例子来了解静态外部变量及其用途。静态变量是局部范围的,外部变量是全局范围的。
静态5.c
#include<stdio.h>
#include "static5.h"
static int m = 25;
int main(){
func(10);
return 0;
}
静态5.h
#include<stdio.h>
int func(val){
extern int m;
m = m + val;
printf("\n value is : %d \n",m);
}
gcc static5.c static5.h
o/p :
static5.c:3: error: static declaration of m follows non-static declaration
static5.h:3: note: previous declaration of m was here
EDITED
正确的程序:
a.c:
#include<stdio.h>
#include "a1_1.h"
int main(){
func(20);
return 0;
}
a1.h:
static int i = 20;
a1_1.h:
#include "a1.h"
int func(val){
extern int i;
i = i + val;
printf("\n i : %d \n",i);
}
这工作得很好,非常好。但这被编译成单个编译单元。因此能够访问静态变量。在整个编译单元中,我们不能通过使用 extern 变量来使用静态变量。
static
有一个非常简单的逻辑。如果一个变量是static
,这意味着它是一个全局变量,但它的范围仅限于它定义的位置(即仅在那里可见)。例如:
- 函数外部:全局变量,但仅在文件内可见(实际上是编译单元)
- 函数内部:全局变量,但仅在函数内部可见
- (C++) 在类内部:全局变量,但仅对该类可见
现在让我们看看 C11 标准是如何规定的static
and extern
(强调我的):
6.2.2.3
如果对象或函数的文件范围标识符的声明包含存储类说明符static
,标识符具有内部链接。
6.2.2.4
对于使用存储类说明符声明的标识符extern
在该标识符的先前声明可见的范围内,如果先前的声明指定了内部或外部链接,则后面的声明中标识符的链接与先前声明中指定的链接相同。如果没有可见的先前声明,或者如果先前声明未指定链接,则该标识符具有外部链接。
6.2.2.7
如果在翻译单元内,相同的标识符同时出现在内部和外部链接中,则行为未定义。
因此,标准首先规定,如果您有:
static int m;
extern int m;
然后是第二个声明(extern
)会考虑第一个,最后m
仍然会是static
.
但是,在任何其他情况下,如果存在同时具有内部和外部链接的声明,则行为是未定义的。这实际上给我们留下了一个选择:
extern int m;
static int m;
i.e., extern
之前声明static
宣言。 gcc 足够好,在这种情况下会给你错误未定义的行为.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)