读书人

extern 也与static同样可以保留值吗?为

发布时间: 2013-08-16 14:29:57 作者: rapoo

extern 也与static一样可以保留值吗?为什么这个程序保留了?
我在一个文件中定义了int b = 2;文件名为14.cpp, 如下:

#include "stdafx.h"
#include "stdio.h"

int b = 2;


然后在程序111.cpp中写程序如下:

#include "stdafx.h"
#include "stdio.h"

int f(void);

int main(void)
{
//extern int b;
//printf("%d\n", b);
printf("b = %d\n", f());
printf("b = %d\n", f());

return 0;
}

int f(void)
{

extern int b;
static int c = 5;
c++;
b++;
printf("c = %d\n", c);
return b;
}


得到的结果是
c = 6
b = 3
c = 7
b = 4
Press any key to continue

b有值也是被记住增加了.

extern与static一样函数退出,值会保留?

上面两个文件都是包含在同一个工程里.



[解决办法]
extern int b;表示b定义在别处,也就是上面的全局变量,所以值保留。
[解决办法]
关于下面的问题,extern表示这个变量在别处定义,但这个变量本身必须找的到
main里的a是局部变量,出了main就找不到了,外面根本就没有a的定义,这是作用域问题
[解决办法]
引用:
谢谢各位,另外我还想问,auto与register是不是很少用?什么时候用到它们?

auto是默认的变量布局修饰符,所以都省略。所有不加其他布局修饰符的变量都是auto的
register表示建议编译器将变量放入寄存器,注意“建议”!首先可能很多复杂类型不能放进寄存器,其次,即使可以放进,register只是建议而不是命令。因此现在的编译器大都忽略register。regsiter的存在有历史原因,在编译技术还不太发达的时候,编译器的寄存器分配策略有时难以做到合理,这时register在某些时候对手工优化是有意义的,但现在可以说没什么意义了。
要注意的就是register变量不能用&取地址,毕竟有可能放在寄存器里
[解决办法]
引用:
Quote: 引用:

extern 也是全局变量!static也是全局静态的

如果static是全局的,那还要这个关键词干吗。

多文件时使用,局部于本件。从而解决不同文件变量重名问题!而extern把本文件的全局导入到另一个文件中去,不知道这样解释能不能理解?!
[解决办法]
引用:
Quote: 引用:


Quote: 引用:

extern 也是全局变量!static也是全局静态的

如果static是全局的,那还要这个关键词干吗。

多文件时使用,局部于本件。从而解决不同文件变量重名问题!而extern把本文件的全局导入到另一个文件中去,不知道这样解释能不能理解?!

对此,我只想说四点
1. #12可算是个水帖,还是令人疑惑的那种(见2. )。
2. 在c中,static修饰词的作用,无非与作用域和生存期有关:(1)static+全局变量,生存期不变,作用域变为所在编译单元(源文件);
(2)static+局部变量,生存期变为整个程序运行期,作用域不变,函数第一次被调用才初始化;
(3)static+函数,作用域由默认的全局(因为函数声明时默认extern属性)变为所在编译单元。
其中第二个,静态的局部变量较为常见,lz的例子中就是这个。而一和三却有可选方案(见3. )。我不能理解「static 也是全局」,此话何解?
3. 如果全局变量不可避免,而且还非要重名(对看文档的同志说声辛苦了),对于cpp,使用namespace是自然之举。对于c,除非打算每个轮子都自己造(不用别人的库),那么 「模块名_重名」 之类的或 重命名 才是万金油之法。
4. extern+变量的声明,是告诉编译器,该变量已在别处定义,编译时地址先留白,待链接时补上。
#15中「extern 把本文件的全局导入另一个文件」的费解之处在于,「本文件」到底是哪个文件。因为有个「本」字,显然是指 extern 所在的文件,可这样方向就反了,正确的方向应是 extern 把别处定义的变量引入(链接至)本文件中。(这样还是觉得怪怪的)
不知道这样描述能不能明白。
[解决办法]

回答你的问题:
1.本-即static所在文件,你嚼字我也没辙,明白的人自明白
2.相对于绝对的问题,解释你的观点2.如果非要严谨的表达“全局”,有一个相对论的问题。或者说前提条件是作用域大小是多大范围更恰当。
3.c语言没有命名空间,说的是C怎么解决命名冲突,不是C++。虽然liunx2.6内核以后就逐渐借用C++的思想给内核加上了命名空间机制,但是c本身没有命名空间的机制,因此在解决命名冲突的时候,这两个关键字就起作用了。你莫非只以为要和库冲突嘛?自己的多个文件同名不加static限制的变量也是可以冲突(编译可以通过,但是链接肯定通不过)的。

------解决方案--------------------



回答你的问题:
1.本-即static所在文件,你嚼字我也没辙,明白的人自明白
2.相对于绝对的问题,解释你的观点2.如果非要严谨的表达“全局”,有一个相对论的问题。或者说前提条件是作用域大小是多大范围更恰当。
3.c语言没有命名空间,说的是C怎么解决命名冲突,不是C++。虽然liunx2.6内核以后就逐渐借用C++的思想给内核加上了命名空间机制,但是c本身没有命名空间的机制,因此在解决命名冲突的时候,这两个关键字就起作用了。你莫非只以为要和库冲突嘛?自己的多个文件同名不加static限制的变量也是可以冲突(编译可以通过,但是链接肯定通不过)的。

关于1. “本-即static所在文件”,extern所在文件还是static所在文件,你是要extern static 连用吗?
关于2. “全局变量”的全局默认下是指的整个程序范围,如果你觉得“全局变量”也可以是指“静态全局变量”的话,那我就很好奇你向别人解释“全局变量”和“静态全局变量”的区别会怎么说。
还有这不叫作“相对论的问题”,这是逻辑学中概念的外延的问题。“全局变量”的外延大于“静态全局变量”,所以可以说“后者是前者”,而反之的话是一件非常confusing的事。
关于3. “你莫非只以为要和库冲突”令人费解,我才猜你想说“你莫非只以为不要和库冲突”,“自己的多个文件同名不加static限制的变量也是可以冲突”读不太懂,是文件同名还是变量同名?如果是前者的话,17楼3.中“模块名_重名”后面跟了“之类”两字;如果是后者的话,干吗一定非要起同名变量和看文档的同志过不去呢?
还有我说的“不用别人的库”是考虑到你一方面用别人的库,另一方面又非要起同名变量,给库里的变量加static我觉得麻烦不小。
此外,我并不是在拍砖,你要是硬说我在拍砖,我也没办法。起因是12楼,你静下心来看看这回帖,不单是遗漏了“局部静态变量”的概念(无论“前提条件是作用域大小是多大范围”,你总都不能把它当“全局”了吧),把这样的回帖放到这整个楼层的作用域中,它到底有何意义,你觉得合适吗?
当然我也有责任,13楼回复未写清楚,让你误以为是要解释 static “这个关键词干吗”的。

读书人网 >C语言

热点推荐