宏和枚举的区别:
宏和枚举之间的差别主要在作用的时期和存储的形式不同,宏是在预处理的阶段进行替换工作的,它替换代码段的文本,程序运行的过程中宏已经不存在了。而枚举是在程序运行之后才起作用的,枚举常量存储在数据段的静态存储区里。宏占用代码段中空间,而枚举除了占用空间,还消耗CPU的资源。
常变量(const)与符号常量(#define)的区别:符号常量不占用内存空间,在预编译时就全部由符号常量的值替换了,而常变量占用内存空间,只是此变量在存在期间不能重新赋值。
const的作用:
(一)const修饰参数。const只能修饰输入参数。
1、如果输入参数是指针型的,用const修饰可以防止指针被意外修改。
2、如果参数采用值传递的方式,无需const,因为函数自动产生临时变量复制该参数。
3、非内部数据类型的参数,需要临时对象复制参数,而临时对象的构造,析构,复制较为费时,因此建议采用前加const的引用方式传递非内部数据类型。而内部数据类型无需引用传递。
(二)const修饰函数返回值。
1、函数返回const指针,表示该指针不能被改动,只能把该指针赋给const修饰的同类型指针变量。
2、函数返回值为值传递,函数会把返回值赋给外部临时变量,用const无意义!不管是内部还是非内部数据类型。
3、函数采用引用方式返回的场合不多,只出现在类的赋值函数中,目的是为了实现链式表达。
(三)const+成员函数。任何不修改数据成员的函数都应该声明为const类型,如果const成员函数修改了数据成员或者调用了其他函数修改数据成员,编译器都将报错!
(四)const 修饰变量,表示该变量不能被修改。
1、const char *p 表示 指向的内容不能改变
2、char * const p,就是将P声明为常指针,它的地址不能改变,是固定的,但是它的内容可以改变。
3、这种const指针是前两种的结合,使得指向的内容和地址都不能发生变化.
const
常量与只读常量:
常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被 修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符。而ANSI C规定数组定义时长度必须是“常量”,“只读变量”也是不可以的。
例如:const int n = 5;
int a[n]; //错误
Const修饰形式参数:
如果函数中不需要修改参数中的数组,那么可以在函数的原型和定义形式参数时使用const修饰数组。使用const可以对数组提供保护,可以阻止函数修改调用函数中的数据。
例如:void add(const int ar [ ], int n);
还有,如果函数想要修改数组,那么在声明数组时就不要使用const,如果函数不需要修改数组,那么在声明数组参数时最好使用const。
通常也把指向常量的指针用作函数参数,以表明函数不会用这个指针来修改数据。
例如:void show(const double *ar,int n);
指向常量的指针不能用于修改数值:
例如:double rates [3 ]={1,2,3};
Const double *pd=rates; // pd指向数组开始处。
第二行代码把pd声明为const double 的指针。这样,就不可以使用 * 来修改它所指向的数值。
例如: *pd=5 ; // 错误
Rates [ 0 ]=8; // 允许,rates不是常量
但是可以让pd指向其他地址:
例如: pd++ ;
也就是说,如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
总而言之,一个位于*左边任意位置的const使数据成为常量,而一个位于*右边的const使得指针自身称为常量。
关于指针赋值和const有一些规则注意:
首先,将常量或者非常量数据地址赋给指向常量的指针是合法的。
例如:double rates [ 3 ]={ 5, 7, 9 };
Const double locked[ 4 ]={3, 4, 5};
Const double *pc= rates; //合法
Pc=locked; //合法
Pc=&rates [3 ] //合法;
然而,只有非常量数据才可以赋给普通的指针。
例如: double rates [ 5 ]={2, 4, 5, 6, 7};
Const double locked[ 4 ]={7, 8, 9, 10};
Double *pnc=rates; //合法
Pnc = locked; //非法
Pnc=&rates [ 3 ]; //合法
这样的规则是合理的,否则,您就可以使用指针来修改认为是常量的数据。
Const还有很多用法:
您可以使用关键字const来声明并初始化指针,以保证指针不会指向别处,关键在于const 的位置。
例如:double rates [5 ]={ 2, 3, 4, 5, 5};
Double *const pc=rates; //pc指向数组开始处
Pc=&rates[2]; //不允许
*pc=2; //允许,更改rates[0 ]的值
这样的指针仍然可用于修改数据,但它只能指向最初赋给它的地址。就是指,如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
最后,可以使用两个const来创建指针,这个指针既不可以更改指向的地址,也不可以修改所指向的数据。
例如:double rates [ 5 ]= {2, 3, 4, 5, 6};
Const double *const pc=rates;
Pc=&rates [ 2 ]; //不允许
*pc=8; //不允许