宏(#define)、枚举(enum)、常变量(const)

来源:互联网 发布:matlab矩阵乘法运算 编辑:程序博客网 时间:2024/06/05 10:22

宏和枚举的区别:

宏和枚举之间的差别主要在作用的时期和存储的形式不同,宏是在预处理的阶段进行替换工作的,它替换代码段的文本,程序运行的过程中宏已经不存在了。而枚举是在程序运行之后才起作用的,枚举常量存储在数据段的静态存储区里。宏占用代码段中空间,而枚举除了占用空间,还消耗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;                        //不允许