额外,说明
0,定义 相当于 声明+分配内存;
声明 就是 声明;
只要在文件里 声明 了 某个变量,, 就可以确保 ‘编译’ 能通过,若其他文件里有 定义,则也可以确保 ‘链接’ 可以通过,,,否则 链接 不过。。。
1、同一变量名,全局的和静态的可同时存在于不同的.c文件里。
如,int a = 1; 在 global.c 里;
static int a = 2; 在 static.c里; gcc -o main.o static.c global.c 可编译通过。
除在static.c文件里引用a的值为2之外,其他地方的文件引用a都是1(global)
2、int a=0; global.c
int a; global22.c
也可以编译通过(只能有一个初始化), 因为 他把第二个默认成声明,可链接 到第一个a;
3、在不同的C文件中可以,以static形式来声明同名全局变量;
如 static int a=1; global.c (在该文件内引用时 a 是1)
static int a=3; global22.c (在该文件内引用时 a 是3)
注意:若只有这两个a,没有 全局的a, 则在第三个文件中声明a时,链接会出 现错误,因为不知道应该链接到哪个文件里的a。
4, 当然,同一文件里,不能同时出现, int a = 1; static int a = 2;的;
5,同一文件里,全局变量和局部变量是可以同名存在的,强龙不压地头蛇,
如,局部变量(可以是静态局部变量)定义在 函数里,与全局同名。
5、static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一 次依据上一次结果值。
6、程序的局部变量存于栈中,全局变量存于静态区中,动态申请数据存在于堆中。
原链接 http://bbs.youkuaiyun.com/topics/310185558
extern较奇怪的问题,摘抄部分分析,留作备份,,正常用法附在最下边。。
// a.c
int i; // 0000000000000004 C i
// b.c
int i = 10; // 0000000000000000 D i
用gcc -o test a.c b.c 可以编译通过。
如果改为
// a.c
int i = 10;
// b.c
int i = 10;
则编译不过。。。 那就会出现重复定义的错误了。。
下面是牛逼人士的分析:
用nm可以帮助理解三种不同的形式的变量说明:
int x; /* C (Common) 声明(可能同时也定义)变量, 到了链接阶段, */
/* 1. 如果没在其他模块发现同名(D)符号,作为未初始化的全局变量, 放在BSS */
/* 2. 如果有在其他模块发现同名(D)符号,作为已初始化的全局变量, 放在数据段 */
int y = 1; /* D (Data) 定义变量,作为已初始化的全局变量, 放在数据段 */
extern int z; /* U (Undefined), 声明变量, 到了链接阶段 */
/* 1. 如果在其他模块有且仅有一个类型(D)的同名符号,将此符号解析到此 */
/* (D)符号,作为已初始化的全局变量, 放在数据段 */
/* 2. 如果在其他模块有两个或更多的类型(D)的同名符号,*/
/* 报告“重复定义”,链接失败 */
/* 3. 如果在其他模块未发现类型(D)的同名符号,但是至少有一个类型(C) */
/* 的同名符号, 将此符号解析到此(C)符号上,
/* 作为未初始化的全局变量, 放在BSS */
简单来说,
int x; 可以在多个模块,
int x = 1; 只能在一个模块
extern int x; 可以在多个模块, 且至少还需要在其他模块有一个 int x; 或 int x = 1;
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
以下是我的通俗理解,功能:《“引用前声明”》
一、extern 作用于变量:
就是a.c 和b.c一块gcc -o成一个test 的ELF,,a.c中定义了一个全局变量,,,现在你想在b.c里边用它,
呢么你就要在b.c里把该变量extern一下,然后就能用了。当然,一般包含在b.c 上边include的头文件里边。
所以,也就有了,只能有一处定义,可以在多处“引用前声明”。。
我(某.c)要是extern 了一个变量,,
一、我不一定用它。。二、我如果用了,我就是用extern来说明一下,我没有定义它,
在别处定义它,先让我编译过去,链接的时候再说。。。
另外,一、一个全局变量默认就是extern的,如:
int i = 5;//与extern i= 5;是一样的,
即(extern)int i = 5; //extern 省略了
int i //定义全局变量
int i= 5;//定义并初始化全局变量
extern int i;// 声明全局变量i
<pre name="code" class="html" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 24px; ">extern int i= 5;//定义并初始化全局变量
//二和四是一样的。二省了而已。。。
二、extern 作用于函数。
与作用于变量很类似,默认int func(){}; 就是extern int func(){},
呢么别的 *.c 文件不需要做什么就可以用这个函数了。还是呢句话,我没有定义实现这个函数,
但我声明一下,它在别的文件里定义实现了,,你先让我编译过,链接的时候我再给你说它在哪个文件里定义的
链接的时候我没有明确告诉你,你再给我报链接出错!!
另外: extern int func()声明;与 int func ();声明。是一样的。。
待续。。。。。