2021-10-22-const指针和常变量的问题

其中的一些概念:

常量表达式是指:值不会改变并且在编译过程之后就能得到计算结果的表达式。字面值属于常量表达式,且用常量表达式初始化的const对象也是常量表达式。
而常量的概念不同:常量的范围应该是大于常量表达式,无论是运行时初始化还是编译时初始化都是属于常量的一部分。
例如:
 const int j = get_size(); //在运行时初始化
 const int j = 42;         //在编译时初始化
 int i = j;               //将j的值拷贝给了i
   

j的常量特征只体现在执行改变j的操作时才会发挥作用,所以在j去初始化i时根本无须在意j的常量特性。

const修饰一般的对象:

  1. const int k =1
  2. 在文件之间共享时,const 常量需要在一个文件之中定义,并在多个文件之间声明(这里也体现出定义和声明的不同了)
//在声明并定义的文件之中
   extren const  int bufsize = 1//在其他用到的的文件之中
   extren const int bufsize;

和#define不同,一个const定义的常量在程序之中只有一个内存,而编译器在编译的过程之中会将所有用到该变量的地方用bufsize的值来替代,如1(共用了同一个地址).而#define会在所有使用到的地方生成立即数。
const修饰的引用
const int ci = 1024;
const int &r1 = ci;//引用是怎么表现的,指向同一个地址?或许在编译原理里面会有解释
1.当一个常量的引用绑定到另外一种类型上时,发生的结果如下所示:

 double dval = 3.14;
 const int &ri = dval;
 而实际上
 const int temp = dval;
 const int &r1 = temp; //编译器为了让r1绑定上整数,进行了如上的转换。很显然,r1绑定上了临时变量并没有任何的意义

量temp上,所以对r1的改变不会影响到dval(如果r1不是常量的话),显然这样定义引用就没有什么意义了(把int引用绑到double上本来就没有意义吧)
2.当const 引用引用了一个非const的对象
由于常量引用仅仅对引用可参与的操作进行了限制(封死了通过引用来改变原值的能力),所以一个非const对象通过除了引用之外的别的途径还是能够照常来修改值的

int i = 42;
 int &r1 = i;
 const int &r2 = i;
 r1 = 0;     //r2引用影响不到i和r1,所以r1照常
 r2 = 0;    //r2引用自身被限定不能改变值,可能在传参数的时候用这种形式会好一点

3.const和指针
主要有三种情况,分清楚就可以了
int d = 1; //从左向右读
const int *a = &d; //*a指针指向常量类型的int,指针自身的类型是变量 ,即指向常量的普通指针
int * const a = &d; //*const a指针指向一个普通的int变量,即指向普通变量的常指针
const int *const a = &d; //*const a指针指向一个const类型的int变量,即指向常变量的常指针
c++P上有这么一句话:所谓指向常量的指针或是引用,不过是指针或是引用“自以为是”(一厢情愿也蛮适合的)罢了,它们觉得自己指向了常量(然而未必),所以自觉地不去改变所指对象的值。(严于律己,宽以待人的意思)

顶层const:可以表示任意的对象是常量(当然也包括了指针在内)
底层const:表示指针所指的对象是一个常量(都是从自身的角度出发),与指针和引用等复合类型的基本类型部分有关。
也只有指针可以同时拥有两种属性(虽然引用可以const const,但是引用本身不是对象?const的部分和指针类型不一样,那是什么?)

constexpr
在C++11新标准规定之中,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式,constexpr之中隐含了const。
constexpr int mf = 20;
constexpr int limit = mf+1; //先知道了mf的情况然后再mf的基础上加1?跟编译的顺序有关系吗
constexpr int sz = size(); //成立的前提是size是一个constexpr函数
还有如果在constexpr声明之中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指向的对象无关。
const int *p = nullptr; //p是一个指向整型常量的指针
constexpr int *q = nullptr;//q是一个指向整数的常量指针,constexpr把它所定义的对象置为了顶层const
constexpr也可以指向非常量
int j = 0;
constexpr int *p1 = &j
字面值类型
常量表达式的值需要在编译的时候就得到计算,因此对声明constexpr时用到的类型必须有所限制。因为这些类型一般比较简单,值也显而易见、容易得到。就把他们成为字面值类型(constexpr声明所用的类型)
算数类型,引用和指针都属于字面值类型。而自定义类 Sales_item(我不知道他是什么)、IO库、string类型则不属于字面值类型。

在函数之中使用const

可能有必要了解一下参数返回的事。
返回一个值的方式和初始化一个变量或形参的方法完全一样:返回的值用于初始化调用点的一个临时量,该临时量就是函数调用的结果。相当于是右值
如果 int i = func();//又相当于把临时量赋给了i
1.void func(const int var)
void func(int *const var)//无意义,形参本身只是临时变量,对原数产生不了影响。
2.void func(const int *var)//对比上面就有了比较实际的意义
3.参数为引用,增加效率,且同时防止被修改
void func(const A &a) //const类型防止修改,引用减少了临时对象的生成。但前提是A为非内部数据,比如比较复杂的类类型,这种类型产生临时变量的构造、析构会消耗比较多的资源,而int这种内部类型就完全没有必要。
4.const int func1();//返回了一个const类型的值
但是它本身没有任何的意义

const int func1()
{
  return 1;
}
 int x = func1();
     x = 2;
  cout<<"right"<<endl;//也能够正常执行

因为函数返回值作为一个临时量,它的作用就只在于给别人拷贝或是输出等。拷贝等过程并不会改变它的值。
5.const int *func2(); 返回值为一个指针,指针指向的内容不能改变。
但是返回指针的话,指针指向的内容不能是临时的,不能是在函数体中定义的,所以要有传入的有意义的数据(指针或者引用等)

6.int *const func3();
返回一个不能改变的指针,和1一样没有太大的意义

在类中使用const

不太理解原因这个到时候再看

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值