Const
Const关键词并不能把一个变量变成一个常量, 在符号前加上const表示这个符号不能被赋值, 即他的值对这个符号来说是只读的, 但并不代表这个值不能用其他方法去改变. 通过下面的例子就能比较好理解,
int i = 5;
const int *a = &i;
*a = 8; //报错, 只读不能赋值
i = 10; //OK
Const最有用处的地方是用它来限定函数的形参, 来表明该函数不能修改实参指针所指向的数据. 同上面的理解, 并不表示这个数据是常量, 在函数外是可以修改的. 如void func(const char *)
Const出现的位置也比较让人困惑, c太灵活的坏处
char *p = "hello"; // 非const指针, 非const数据
const char *p = "hello"; //非const指针 const数据
char * const p = "hello"; // const指针,非const数据
const char * const p = "hello"; // const指针,const数据
你可以在头脑里画一条垂直线穿过指针声明中的星号(*)位置,如果const出现在线的左边,指针指向的数据为常量;如果const出现在线的右边,指针本身为常量;如果const在线的两边都出现,二者都是常量
Static
C语言 中,
static 局部变量 , 生存期为这个源程序, 不过作用域仍难是局部
int fun()
{
static int a = 1;
a++;
print('%d',a);
}
只有第一次调用该函数时a会被初始化为1, 后面每次调用a都会增加1, 所以只要程序不结束这个static a是一直存在的
但他是局部变量, 所以在fun函数之外无法访问, 虽然static a 一直存在
static 全局变量
全局变量本身就是静态存储方式, 再加上static, 是改变他的作用域, 即只能本当前文件访问. 而非static 全局变量的作用域为整个源程序
所以对局部变量, static改变的是他的生存期, 而对于全局变量, static改变的是他的作用域
对于c这样用相同关键词, 却用做完全不同的用处, 真是无法理解, 简直是在忽悠用户
static 函数
在c语言中, 函数的默认作用域是全局可见的, 即整个源程序, 你也可以给函数加上个冗余的extern, 来表示其作用域
如果在函数前加上static, 表示将其作用域缩小至本文件, 同于静态全局变量的用法.
此处普遍认为是c语言的设计失误, 不应该默认将作用域设为全局, 容易造成命名空间冲突.
C++ 中
C++中除了C中的用法, 还多了static成员变量, 和static成员函数的用法
表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员.
在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义.
所以对静态成员的引用不需要用对象名, 可以直接使用类名,
静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数,这是由于静态的成员函数没有this指针
Extern
参考自(http://blog.csdn.net/keensword/archive/2005/06/23/401114.aspx)
如果想明白为什么需要extern, 需要从编译和链接讨论起,
现 代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部。但是到 了链接阶段,要将各个文件的内容“合为一体”,因此,如果某些文件中定义的全局变量名相同的话,会报错. 因此,各个文件中定义的全局变量名不可相同。
//A.cpp
int i;
void main()
{
}
//B.cpp
int i;
所以上面两个文件编译是没有问题的, 但是到了链接就会报重名错误
如果此时A.cpp里面要用到, B.cpp中定义的i, 应该怎么办?
那么既然上面说了重复定义出错, 那就把A.cpp中的"int i;"定义直接去掉是否可以
看 起来好像可以的, 因为全局变量的作用域是整个源程序, 这边也许是很多人会产生疑问的地方, 既然全局变量和全局函数的作用域是整个源程序的, 为什么在其他的文件里面使用一定要先声明(这样的声明往往在.h文件中, 并在使用处include该.h, 记住include就是copy, 之所以要使用.h, 而不是直接写在.c中, 只是为了保证易维护性, 最终编译器会自动将.h copy到每个.c中)