const、static、内部链接属性和外部链接属性整理
说起const、static、以及#define大家都知道,我一直以为我也是知道的,昨天一同学说他面试时被问到#define定义一个常量和const定义一个常量有什么不同,
我整理了下思路,发现当想向他说清楚这个问题时,我发现自己对const和#define中有些问题还是很模糊,我想这可能就是某位高手说的:“当你可以向别人清楚的
解释某个问题时,你才算真正懂了这个问题”。于是乎,赶紧学习了下,理理思路,记下。
1、c语言中:
1 const int i=10;
2 int array[i] ;
这个i不能说是常量而是一个不可改变的变量,它的不可改变是由编译器确定的,因此将 i 作为数组的长度;会出错,数组的长度
必须是一个编译期常量(下面解释)。在C++中这样定义却是可以通过的,在C++中有一个常量折叠概念。
2、编译期常量和运行期常量
两者都是常量,它们的区别, 可以用是否具备内存空间来区分
编译期常量,
比如, #define MAX 128
这个 MAX 就是编译期常量, 没有对应的内存空间,
在编译时候, 所有的 MAX 都被 128 这个值代替
运行期常量,
比如 const int x=128;
就是一个运行期常量, 分配内存空间,
但是其值不允许改变
还有 const int y = ram();//ram()是一个获取随机数的函数,
这样y肯定是一个运行期常量,在编译时不知道它的值,而是在运行期获得,但不可改变。
3、常量折叠
所谓“常量折叠”是C++中编译器的一种优化手段,对于上面的const int x = 128;编译器一般不为x分配内存空间,而是将它保存在一个符号表中
这样导致的结果就是 const int x=128; 类似这样的定义, 产生的结构和 define 一样, 出现 x 的地方直接被 128 这个值代替了
我了解的,在下面情况下const定义的常量会分配内存。
1)当用extern修饰const变量将强制为其分配内存,因为extern表示采用外部链接,因此其必须有某个地址保存其值。
2)等取x的地址时,会强制分配内存。
3)用static 修饰时,应该也要分配内存。
4、一个类中各种变量的初始化。
//myclass.h
class myclass
{
public:
myclass();
~myclass();
public:
int x=1;//error
static int y = 2; //error
const int a = 3;//error
static const int b = 4;//ok
}
对于上面这个类中各变量:
普通变量x如果在类定义的头文件中初始化,由于此时没有定义对象,未分配内存空间,所以没有地方存放x,或者像网友所说:要构造函数干嘛?
静态变量x不是属于哪一个对象的,所有对象共享,只能初始化一次,若在类中定义,那不每个对象都初始化一次?它初始化一般为:myclass::x = 2;
const常量在定义时就必须初始化,一般放在初始化列表中初始化。
static const定义(注:必须是整形或字符型,规定)可以在类定义时直接初始化,首先static被所有对象共享,存储在静态存储区中,其次,const限定了其不可改变,每个对象中都一样。
5、内部链接属性和外部链接属性
就是相当于c中变量或函数的作用域,static修饰的变量或函数只能在本文件中可见,const修饰的也默认为内部链接属性,extern修饰为外部链接属性(和const同时修饰时,压过const修饰的属性)。
可能很多说的不是很全面,欢迎指正。
author:good90
参考:http://topic.csdn.net/u/20070128/22/80cc01e6-7a54-4c70-b8fd-82766f24ee2e.html
http://blog.csdn.net/lovenankai/article/details/6848655