首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • const初级问题,大家指教。 [已结贴,结贴人:green__hand]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • green__hand
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2008-08-22 08:53:49 楼主
    请问:const是个什么东西,是变量说明符,还是属于什么东西?具体有什么用?(在应用中)


    const char *pContent; //*pContent是const, pContent可变

    char* const pContent; //pContent是const,*pContent可变


    const char* const pContent; //pContent和*pContent都是const


    char const * pContent;// *pContent是const, pContent可变

    (char *) const pContent;//pContent是const,*pContent可变

    char* const pContent;// pContent是const,*pContent可变

    char const* const pContent;// pContent和*pContent都是const


    这几个都怎么区分,是否可以用程序举例说明?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unbutun
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 08:54:351楼 得分:10
    mark
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • freshui
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 08:56:092楼 得分:10
    说明变量是只读的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 08:56:393楼 得分:10
    注释已经说的很清楚了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lunarfan
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:03:524楼 得分:10
    const char *pContent = char const *pContent 这个可换其意义不变
    char* const pContent这个换了后意义也变了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wangdeqie
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:10:285楼 得分:10
    const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:

      沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

      另外,需要注意:对于const (char *) ; 因为char *是一个整体,相当于一个类型(如 char),因此,这是限定指针是const。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ztz0223
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:14:096楼 得分:10
    弄的这么复杂
    那我就一句话告诉你吧,const的位置跟*有关,在星号前面就是整个对象的值不可变,在星号后面就是指针值不可变
    给你两个实际的例子吧:
    C/C++ code
    int _tmain(int argc, _TCHAR* argv[]) { int b = 100; const int * a = &b; //*a = 1201; //wrong error C3892: 'a' : you cannot assign to a variable that is const int c = 200; int * const aa = &b; *aa = 1000; //okey //aa = &c; wrong 指针值不可以变 return 0; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • qqwx_1986
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:14:367楼 得分:10
    const 限定元素为只读的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lunarfan
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:15:598楼 得分:10
    沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
    这个方法不错哦,学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • greenbit
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:21:179楼 得分:10
    使用const的好处在于它允许指定一种语意上的约束------某种对象不能被修改--------编译器具体来实施这种约束。通过const,你可以通知编译器和其他程序员某个值要保持不变。只要是这种情况,你就要明确地使用const,因为这样做就可以借助编译器的帮助确保这种约束不被破坏。
     首先解释一下const与指针的关系:
    const在指针的声明中有一下三种形式:
    const char*p="hello";//非const指针,
    //const数据,就是说p指向的那个内存空间的数据是不可变的,但p还可以指向新的内存地址。
    char *const p="hello";//const指针,
    //非const数据,就是说这个指针p一旦赋值或初始化,就不能在指向其他位置了,但其指向的位置的数据值是可变的。
    const char*const p="hello";//const指针,
    //const数据,这个就很明显了,集上述两家之长处(也可能是短处哦,),上述两者都不可变。
    一般来说,你可以在头脑里画一条垂直线穿过指针声明中的星号(*)位置,如果const出现在线的左边,指针指向的数据为常量;如果const出现在线的右边,指针本身为常量;如果const在线的两边都出现,二者都是常量。
    恩,差点忘了,还有一种形式:
    char const *p="hello";
    这其实与上边的情形一是一样的,只是由于个人习惯的不同,二者都是对的。
     在一个函数声明中,const可以指的是函数的返回值,或某个参数;对于成员函数,还可以指的是整个函数。
    const(1)int fun(int const(2)&) const(3)
    {
    int temp;
    return temp;
    }
    参数的const属性(上例2处)一般用引用传递,是为了保证该参数在函数中不允许被修改,一旦修改,编译器会报错。
    而返回值的const属性(上例1处)是保证函数的返回值不被修改,也许你会质疑这种可能性,但是这种可能性确实存在,详细情形如下:(摘自effective c++)
    const rational operator*(const rational &lhs, const rational &rhs);
    很多程序员第一眼看到它会纳闷:为什么operator*的返回结果是一个const对象?因为如果不是这样,用户就可以做下面这样的坏事:
    rational a, b, c;
    ...
    (a*b)=c;//对a*b的结果赋值
    我不知道为什么有些程序员会想到对两个数的运算结果直接赋值,但我却知道:如果a,b和c是固定类型,这样做显然是不合法的。一个好的用户自定义类型的特征是,它会避免那种没道理的与固定类型不兼容的行为。对我来说,对两个数的运算结果赋值是非常没道理的。声明operator*的返回值为const可以防止
    这种情况,所以这样做才是正确的。
    呵呵,象Scott Meyers这样的大师见地就是不一般吧
    接下来说明函数的const属性:(上例3处)
    当然喽,一般用于成员函数了,它有以下属性:
    (1)const成员函数不被允许修改它所在对象的任何一个数据成员。
    (2)const成员函数能够访问对象的const成员,而其他成员函数不可以。
     尽量使用const代替define吧,因为const是类型安全的。
    应该使用const double pi = 3.1415926;
    而不要用#define pi 3.1415926
    后者是宏,仅仅是对程序中的pi用3.1415926代替,会让你对于一些编译时的错误很难定位。

    定义常量时的区别
    const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
    编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
     const定义常量是有数据类型的,而#define宏定义常量却没有。
     这样const定义的常量编译器可以对其进行数据静态类型安全检查,而#define宏定义的常量却只是进行简单的字符替换,没有类型安全检查,且有时还会产生边际效应(不如你愿处)。所谓边际效应举例如下:
     #define N 100
     #define M 200 + N
     当程序中使用 M*N 时,原本想要 100 * (200+ N )的却变成了 100 * 200 + N。
     有些调试程序可对const进行调试,但不对#define进行调试。
     当定义局部变量时,const作用域仅限于定义局部变量的函数体内。但用#define时其作用域不仅限于定义局部变量的函数体内,而是从定义点到整个程序的结束点。但也可以用#undef取消其定义从而限定其作用域范围。

    光用const定义常量,并不能起到其强大的作用。const还可修饰函数形式参数、返回值和类的成员函数等。从而提高函数的健壮性。因为const修饰的东西能受到c/c++的静态类型安全检查机制的强制保护,防止意外的修改。

    const修饰函数形式参数
    形式参数有输入形式参数和输出形式参数。参数用于输出时不能加const修饰,那样会使函数失去输出功能。因为const修饰的东西是不能改变的。
    const只能用于修饰输入参数。
    谈const只能用于修饰输入参数之前先谈谈C++函数的三种传递方式。
    C++函数的三种传递方式为:值传递、指针传递和引用传递。简单举例说明之,详细说明请参考别的资料。
    值传递:
    void fun(int x){
    x += 5; //修改的只是y在栈中copy x
    }
    void main(void){
    int y = 0;
    fun(y);
    cout < <"y = " <
    }
    指针传递:
    void fun(int *x){
    *x += 5;//修改的是指针x指向的内存单元值
    }
    void main(void){
    int y = 0;
    fun(&y);
    cout < < < <"y = " <
    }
    引用传递:
    void fun(int &x){
    x += 5;//修改的是x引用的对象值 &x = y;
    }
    void main(void){
    int y = 0;
    fun(y);
    cout < < < <"y = " <
    }
    看了传递方式后我们继续来谈“const只能用于修饰输入参数”的情况。
    当输入参数用“值传递”方式时,我们不需要加const修饰,因为用值传递时,函数将自动用实际参数的拷贝初始化形式参数,当在函数体内改变形式参数时,改变的也只是栈上的拷贝而不是实际参数。
    但要注意的是,当输入参数为ADT/UDT(用户自定义类型和抽象数据类型)时,应该将“值传递”改为“const &传递”,目的可以提高效率。
    例如:
    void fun(A a);//效率底。函数体内产生A类型的临时对象用于复制参数 a,但是临时对象的
    //构造、复制、析构过程都将消耗时间。
    void fun(A const &a);//提高效率。用“引用传递”不需要产生临时对象,省了临时对象的
    //构造、复制、析构过程消耗的时间。但光用引用有可能改变a,所以加const


    当输入参数用“指针传递”方式时,加const修饰可防止意外修改指针指向的内存单元,起到保护作用。
    例如:
    void funstrcopy(char *strdest,const char *strsrc)//任何改变strsrc指向的内存单元,
    //编译器都将报错
    这样就保护了指针的内存单元,也可以保护指针本身,防止其地址改变。
    例如:
    void funstrcopy(char *strdest,const char *const strsrc)

    const修饰函数的返回值

    如给“指针传递”的函数返回值加const,则返回值不能被直接修改,且该返回值只能被赋值给加const修饰的同类型指针。
    例如:
    const char *GetChar(void){};
    赋值 char *ch = GetChar();//错误const char *ch = GetChar();//正确

    const修饰类的成员函数(函数定义体)

    任何不会修改数据成员的函数都应用const修饰,这样当不小心修改了数据成员或调用了非const成员函数时,编译器都会报错。
    const修饰类的成员函数形式为:int GetCount(void) const;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hqin6
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:30:5710楼 得分:0
    引用 8 楼 lunarfan 的回复:
    沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
    这个方法不错哦,学习


    hehe ,很实用~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • k2eats
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 09:50:5211楼 得分:0
    const表示只读,你不能修改它,但是可以初始化!
    应用于:定义常量,const int N = 5;相当于C语言#define N 5
    传递参数的修饰符,void f(const char* p)这样就不能修改p指向的内容,只能读其内容,类似的有const引用,
    作为类成员函数修饰符,如:
    class A{
        void f()const{...}
    };
    这样函数f()不能修改类成员,只能读取内成员
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • realdragon2
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:20:2112楼 得分:0
    引用 10 楼 hqin6 的回复:
    引用 8 楼 lunarfan 的回复:
    沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
    这个方法不错哦,学习


    hehe ,很实用~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • matthous
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:24:4213楼 得分:0
    沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
    很不错的方法~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • mifeixq
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:25:1614楼 得分:0
    const 是限定符

    在C里,const + 类型 != 常量
    c++里可以看成常量

    有个诀窍就是  const 左作用  就是看到const 找它左面的类型。const就是修饰这个类型的!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhdsheng
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:31:0115楼 得分:0
    引用 6 楼 ztz0223 的回复:
    弄的这么复杂
    那我就一句话告诉你吧,const的位置跟*有关,在星号前面就是整个对象的值不可变,在星号后面就是指针值不可变
    给你两个实际的例子吧:

    C/C++ codeint _tmain(int argc, _TCHAR* argv[])
    {
        int b = 100;
        const int * a = &b;
        //*a = 1201; //wrong error C3892: 'a' : you cannot assign to a variable that is const
        int c = 200;
        int * const aa = &b;
        *aa = 1000; //oke…



    这个讲得很透彻了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zjw6861982
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:32:0916楼 得分:0
    找一本C++primer 上面说的很清楚了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • e_sharp
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:34:4117楼 得分:0
    引用 5 楼 wangdeqie 的回复:
    const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:

      沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

      另外,需要注意:对于const (char *) ; 因为char *是一个整体,相当于一个类型(如 char),因此,这是…


    这个方法好
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • e_sharp
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 10:34:5718楼 得分:0
    引用 5 楼 wangdeqie 的回复:
    const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:

      沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。

      另外,需要注意:对于const (char *) ; 因为char *是一个整体,相当于一个类型(如 char),因此,这是…


    这个方法好
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unbutun
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-22 11:41:4119楼 得分:0
    6楼和11楼的说的很好。


    哪位高人再从实际中解释解释。


    那些搬网页,搬书的,没意思。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • waji2000
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-24 09:33:5820楼 得分:0
    const char *pContent; //*pContent是const, pContent可变
    该声明可以看作两个部分:
    const为修饰符,修饰其左边的元素。
    先声明一个const char* 的变量pContent。const char看作一起,也就是说代表一个不可变的字符,即字符常量。
    因此:pContent这个指针变是可以变的,但其必须指向const char。取其指向值,当然也就是不可变的。
    故:*pContent是const, pContent可变

    char* const pContent; //pContent是const,*pContent可变
    分析:
    const用来修饰变量pContent,也就是说pContent声明后即应被初始化,初始化就不能改变其值。
    后面一部分说明pContent的类型,char*。即为字符型指针。
    故:pContent是const,*pContent可变

    char const * pContent;// *pContent是const, pContent可变
    const 修饰的是变量类型* 即指针类型,常量指针,然后用char加强.
    同const char *pContent;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xqls_xqls
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-24 09:43:5421楼 得分:10
    引用 8 楼 lunarfan 的回复:
    沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。
    这个方法不错哦,学习


    const的位置跟*有关,在星号前面就是整个对象的值不可变,在星号后面就是指针值不可变


    这两条规则都很实用,学习了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jillnicky
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-08-24 10:13:0122楼 得分:0
    楼上各位说得很清楚了
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved