zoukankan      html  css  js  c++  java
  • const关键字总结

      在C语言中

      const是C语言中总结

      1.修饰的变量,使其具有常属性,使变量的值不能直接被改变。但是可以通过指针来间接的修改变量的值。

      2.便于进行类型检查(在编译时进行类型检查),使编译对处理内容有更多的了解,保护被修饰的东西,防止被意外修改,增强程序的健壮性。

      3.方便的进行参数的调整和修改(类似于宏定义)

      作用1说明:

      修饰的变量,使其具有常属性,使变量的值不能直接被改变。但是可以通过指针来间接的修改变量的值

      例如:

      const int t=10;

      //在以后的代码中,程序不可直接对i进行修改

      //但是可通过指针来间接的修改i变量中存的值

      t=2; //会报错

      int *p=(int *)&t;

      *p=2; //在此处就将i中的值存成2了

      const修饰指针变量:

      int main()

      {

      int a = 10;

      const int *p = &a; //const修饰int *,即p的指向,因而p指向的内容即通过pa解引用后不能被修改,但是p中存的内容可以改变,即p的指向可以改变

      int * const q=&a; //const修饰*,即q变量,因而q里存的内容不能变,即q的指向不能改变,但是q指向的内容即a中的内容可以修改。

      p++;//正确

      (*p)++;//错误

      q++;//错误

      (*q)++;//正确

      return 0;

      }

      所以看const修饰谁,要看const右面有什么

      比如:

      int **const* p; 则通过*p来修改对应的内容则报错

      int **const** p; 则通过**p来修改内容则会报错

      通过const的特性,const可以在很多地方派上用场

      比如在传参时,不想通过函数来改变实参值,在传实参地址时,形参接收在前可加const修饰,这样就不会在函数里通过解引用来修改实参值了

      在C语言中,const不用来修饰函数,原因看C++的用法

      在C++中

      在c++中:

      1.const修饰变量的用法和作用与c语言一样,但是有一点不同

      #include

      using namespace std;

      int main()

      {

      const int a = 1;

      int* p = (int *)(&a);

      *p = 2;

      cout << "value of p: " << *p << endl;

      cout << "value of a: " << a << endl;

      cout << "address of p: " << p << endl;

      cout << "address of a: " << &a << endl;

      return 0;

      }

      输出

      /*value of p: 2

      value of a: 1

      address of p: 0x7fbffff7fc

      address of a: 0x7fbffff7fc

      由答案可知,a并没有像c语言中一样,被p修改为2,这是为什么呢?

      原因: const int a其实是保存在符号表中,无内存地址,但自己对a进行&a,那么编译器会为a分配一个地址,但取a的值依然是从符号表中取值,而用指针int *p=&a;

      *p=4这个值是改变a的内存所表示值,不会改变符号表中a的值。

      #include

      using namespace std;

      const int a = 3; //此时a是全局变量

      int main()

      {

      //const int a = 3;

      int* p = const_cast(&a);

      *p = 4;

      cout << "value of p: " << *p << endl;

      cout << "value of a: " << a << endl;

      cout << "address of p: " << p << endl;

      cout << "address of a: " << &a << endl;

      return 0;

      }

      输出结果

      会发生如此运行时错误

      由此可见,在c++中全局const变量和局部const变量的编译器处理的方法是不一样的。因为全局const变量是不分配内存地址的,它编译器放置在符号表中作为编译期常量,全局const变量放在只读数据段中,受到只读数据段的权限保护,当你修改一个只读数据段中的内容时,会得到一个运行时错误。而局部const变量是放在堆栈之中,因为在内存中有地址,通过修改地址中的值可以达到修改const所指内存中值的目的。

      2.此外,在c++中,const还可用来修饰成员函数,其用法是放在形参列表之后,

      用来修饰隐式传入构造函数中的this指针,表明在函数调用的过程中,不可对this指向的内容进行修改,即不可修改调用这个构造函数对象中的内容。

      被const修饰的成员函数,称作为const类型的成员函数

      例如:无锡人流哪家好 http://www.wxbhffk.com/

      class Date

      {

      public:

      Date(int year = 1900, int month = 1, int day = 1)

      {

      _year = year;

      _month = month;

      _day = day;

      cout << "Date(int,int,int):" << this << endl;

      }

      // 在const成员函数中,不能修改类的任何成员变量

      void PrintDate()const

      {

      //_year++;

      //即this->_year++; 会报错

      // 在函数被修饰后,this的类型为 const Date* const (因为this指针本来就是const型的this不可修改指向,后面的const表明this指向里的内容也不可修改)

      _day++; //√

      cout << _year << "-" << _month << "-" << _day << endl;

      }

      private:

      int _year;

      int _month;

      mutable int _day; //在成员变量名前加mutable关键字后,成员函数即使加const也可修改_day的值

      };

      int main()

      {

      Date d1;

      d1. PrintDate();

      }

      用const修饰成员函数有以下注意事项:

      1>const不可修饰其他类外函数(对有this的函数才有用)。不可调用构造函数,因为构造函数目的就是要修改成员变量。

      2>const对象不可以调用非const成员函数。因为普通成员函数是可以修改成员变量的,如果允许修改,拿不可修改的const对象就会被修改了,不安全。

      3>非const对象可以调用const成员函数。因为普通变量可读可写,const函数只允许对调用对象进行读,因此没有什么不可。

      4>const成员函数不可以调用非const成员函数。普通函数可对对象进行修改,在调用普通函数时可能会修改对象,因此const成员函数不能调用非const成员函数。

      5>非const成员函数可以调用const成员函数

      const 变量与 define 宏定义的区别:

      (1) 编译器处理方式不同

      define宏是在预处理阶段展开。

      const常量是编译运行阶段使用。

      (2) 类型和安全检查不同

      define宏没有类型,不做任何类型检查,仅仅是展开。

      const常量有具体的类型,在编译阶段会执行类型检查。

      (3) 存储方式不同

      define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。

      const常量会在内存中分配(可以是堆中也可以是栈中)

      const修饰可以节省空间,避免不必要的内存分配(与宏定义的本质区别)

      宏的优点:

      1.增强代码的复用性。

      2.提高性能。

      缺点:

      1.不方便调试宏。(因为预编译阶段进行了替换)

      2.导致代码可读性差,可维护性差,容易误用。

      3.没有类型安全的检查

  • 相关阅读:
    javascript 学习笔记
    vim折叠设置(转载)
    描述符
    python运算符优先级
    python repr()和str()
    python super()
    [深入Python]__new__和__init__
    python中,类方法和静态方法区别。
    python中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
    关于字符集和字符编码自己汇总记录
  • 原文地址:https://www.cnblogs.com/djw12333/p/11630665.html
Copyright © 2011-2022 走看看