c++之重要的关键字(二)---const

      const 它限定一个变量不允许被改变,表示只读变量。使用const在一定程度上可以提高程序的安全性和可靠性

        const变量 & 常量

  为什么下面的例子在使用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢? 

  const int n = 5;

  int a[n];

      上面讨   论的是“常量”与“只读变量”的区别。

     常量肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。

    “只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。

      在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的)。

       enum类型和#define宏,这两个都可以用来定义常量。而被const修饰的只是只读变量

        const变量 & const 限定的内容

  下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢? 

  typedef char * pStr;

  char string[4] = "abc";

  const char *p1 = string;

  const pStr p2 = string;

  p1++;

  p2++;

  答案与分析:

  问题出在p2++上。

  1)、const使用的基本形式: const char m;

  限定m不可变。

  2)、替换1式中的m, const char *pm;

  限定*pm不可变,当然pm是可变的,因此问题中p1++是对的。

  3)、替换1式char, const newType m;

  限定m不可变,问题中的pStr就是一种新类型,因此问题中p2不可变,p2++是错误的。

        const变量 & 字符串常量

  请问下面的代码有什么问题?

  char *p = "i'm hungry!";

  p[0]= 'I';

  答案与分析:

  上面的代码可能会造成内存的非法写操作。分析如下, "i'm hungry"实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。

       const变量 & 字符串常量2

  请问char a[3] = "abc" 合法吗?使用它有什么隐患?

  答案与分析:

  在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为"abc",注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpy、printf等,都不能够被使用在这个假字符串上。

      变量
     const int A; 常量
     const int* pA; 指向常量的指针。 (*pA)++ 错误,不允许改变常量, 但是 pA = &D 可以改变指向的对象。
     int const * pA; 常量指针,指向int。(*pA)++ 允许, 但不可以改变指向,既 pA = &D 错误

     const int *const p3=&A;//p3不可变,*p3也不可变,此时既不能用*p3来修改其值,也不能转向

     指针和引用的区别很简单,就是引用更简洁,更安全。因为引用声明是必须初始化

     const指针可以接受const和非const地址,但是非const指针只能接受非const地址。所以const指针的能力更强一些,所以尽量多用const指针,这是一种习惯。

     函数 
     const int a(); 返回常量
     int const * a(); 返回常量指针
     const int* a(); 返回指向常量的指针
      形参是const类型的,说明该函数将不会修改其值,该函数便为const函数。

     限定函数类型.

 void function()const; //常成员函数, Const成员函数不能改变对象的成员函数。

     如:

      class Point {

  public:

        int GetY() const;

                void SetPt (int, int);

                ...........................

    };

       int Point::GetY() const                            //该函数调用时没有修改类的数据成员,只是读取。

  {

  return yVal;

  }

      void Point:: SetPt (int x, int y)               //该函数有改变类的数据成员,不能定义为常成员函数

  {

  xVal=x;

  yVal=y;

  }

     const Point p;

     int y=p.GetY() ;      //正确的

      p.SetPt(10,10);   //错误的,常对象只能调用常成员函数

    非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员。

     构造函数和析构函数对这个规则例外,它们从不定义为常量成员,但可被常量对象调用(被自动调用)。它们也能给常量的数据成员赋值,除非数据成员本身是常量。

     类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数。不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值