const 的用法

来源:互联网 发布:哪个牌子的油汀好 知乎 编辑:程序博客网 时间:2024/06/07 03:13

 很久就说来写一篇文章,以便于加加分数,但是一直都没有写。
不过,也没有忘记。

今天想跟大家讨论讨论const和volatile.
说起const的话,可能第一个反应应该就是常量吧?
其实把它的理解为常量是不对的。在一个符号前面加一个const
只是表示这个符号不能被赋值.也就是它的值对于这个符号来说
是只读的,但并不能防止其它的方法来改变这个值的值.我想,
const最有用的地方就是把它用来限定形参,这样函数将不会修
改实参指针所指向的数据,但其它的函数却可能可以。
注:若是不对的话,请指正。thanks in advanced.

比如说:int const a=10; //当然您也可以这样子写const int a=10;
             //只是我个人比较喜欢这样子也而且,
             //个人觉得好读一点点。

表示的是a不能做左值。只能做右值。这个时候的a就是不能被改变的。
但是要是您要是加上指针的话,可能就变得有些麻烦了,如:

int    b=20;
int const *p=&b;     //一个指向整型数据的指针。

很多的人在这个地方很不理解,我慢慢的解释一下。

跟上面的int const 一样 ,既然a是不能做为左值的,那么此时的
*p也同样是不能做为左值.即b是不可以通过*p来改变的。(希望这
个地方没有把您给弄晕等一下我会给出例子,看了就会明白了).

既然,*p不可以改变,那么p可不可以改变呢?可以,p是可以改变的
喔。因为我们并没有限定p,而只是限定了它所指向的数值。那么
怎么样子限定p呢?int *const p;    //就可以了。
现在的p就是不能修改的了.

举个例子来说吧:

    int a=3;
    int const b=2;
    int const *p=&b;
    int *const pl=&a;

    a=10;    //这个肯定是对的撒.

    b=20;   //错的.  b不能做为左值.

    p=&a;   //对的。我们并没有限定p,只是限定了p所指向的
        //数据,而这个数据也没有成为左值,当然是可以的了.

    *p=40;  //错的。跟我们刚刚说的一样,*p是不可以做为左值的。
        //修改*p就意味着去修改a,而a已经被p所保护,
        //所以这里会给出错误提示或者是警告.

    pl=&b;  //错的,pl是一个常量指针,指向整型数a。
   

既然都说到这里来了,我就索性把有关的都说了吧。
上面说的左值和右值我就再解释一下吧。
简单的说来就是等式的左边和右边。
eg: a=b;这一个赋值的语句。
a就是左值,b就是右值.
a用的是地址,而且只能是地址,b用的是数值,并且只能是数值.
也就是说,对于一个等式的话,位于左边的,一定是一个地址,
而右边的一定是一个数值了.
我再说一个比较难于理解的吧。就是常常犯错的一点。我想举个例子来说
的话或者更于明白。

void func(char const **pt)
{...}

int main(int argc,char **argv)
{
    ...
    func(argv);  //这里会出现警告或者是错误。
    ...
}

    我在解释这个例子之前,好好的整理了一下我自己的语言,
因为要把这一个问题解释清楚,还真的是不太容易。
解释之前,我先把我们要说的提出来吧,就是“相容”问题。
若是我们将上面的char ** 和char const **改成char * 和char const *
那么,上面的调用却又是没有问题的。不信的话,可以试试。
也就是说,char * 和char const * 是相容的。那为什么char **和char
const ** 却又是不相容的呢?
在ANSI C 里面有这么一句话:
    每个实参都应该具有自己的类型,这样它的值就可以给与它所对应
的形参类型的对象(该对象的类型不能含有限定符).

    要使赋值合法,必须满足以下的条件之一:
    两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针
指向的类型必须具有右边指针所指向类型的全部限定符。

也就是说,相空的才可以相互赋值,而不相容的就不可以。首先呢?得明白,
参数的传递其实就是类似于赋值的一个过程.正是由于上面的那个条件,
这就使得为什么char * 和char const * 是相容的.

还是举例来说明吧。
char *ch;
char const *cp;
cp=ch;

左值:是有个具有限定符const的指向char型的指针。
右值:是一个没有限定符的char型的指针.
左值是一个char型的指针,右值也是一个char型的指针,左值包含了右值的限定符
即:没有限定符。而char与char是相容的。所以说,char * 和char const * 是
相容的。
而要是您反过来: ch=cp;这个就是不行的了。原因是什么我想我就不用解释了吧?
若是不信的话,您可以去试一试。
好了,现在来解释下接下来的.
还是先来说说这个声明吧:
char const * 类型并不是一个有限定符的类型。它的类型是指向有一个具有const限
定符限定的char型数据的指针,也是就限定的是指针所指的对象,而并不是指针本身.
这跟我上面所说的是一样的,现在只是再来回顾一下。

类似的 char const ** 类型也同样的不是一个有限定符的类型.它表示的是指向一个
具有const限定符限定的指针的指针.
注意:指向类型是char const *
同样char ** 类型,表示指向一个没有任何限定符限的指针的指针.
注意:指向类型是char *

好了,有没有人告诉过您char const * 和char *是同一类型的呢?No...
既然两者都不是同一类型的,那么,它们是不是相容的呢?肯定不是了撒。
所以,这个时候就不可以传过去了咯.


好了,说了那么多的东东,现在又说回来,扯得有一点点远了哈!
我们一次的把多个关于const的弄出来吧!

有了前面的一些认识,现在来弄得深入一点点的.

int const *a;    //a是一个指向 const整型 的指针   
int *const a;    //a是一个指向 整型的 const指针        
int const *const a;    //a是一个指向 const整型的 const指针

嗯?.........好了,现在来一点点稍微复杂的.
int **a;    //a是一个指向 int型指针的指针
int const **a;    //a是一个指向 const int *指针的指针.
int *const *a;    //a是一个指向 int 型的 const 指针的指针.
int **const a;    //a是一个指向 int 型指针的 const指针.
int const *const *a;    //a是一个指向int const 型的 const指针的指针.
int *const *const a;    //a是一个指向int型的 const型指针的const指针.
int const *const *const a;    //a是一个指向int const 型的 const 型指针 的const 型指针.

好了,我想再复杂也不会超过这样子的复杂程度了吧????

本来还想说说volatile的,但是,我想您看到这里应该已经晕了吧?
所以了,下次说volatile吧!平时用这个限定符的时候其实并不多.

 

 

 

From : http://www.52cuit.cn/bbs/viewthread.php?tid=308&extra=page%3D1

原创粉丝点击