C++学习笔记3——复合类型

总结:、

  1. 引用:
      1)普通引用:
       1)必须初始化,不允许指向字面值或表达式
       2)类型匹配(2种特殊情况)
      2)常量引用:
       1)初始化常量引用,允许任意表达式,只要
        其能转化为其类型,但不能通过引用改变值
int i=2;
const int &r1=i;//,类型虽不同,但正确
const int &r2=42;//正确

int i=2;
int &r1 = i;//错误,不能指向字面值

     3)指向指针的引用:

int i=2;*p=&i;
int *&r =p;
  1. 指针:

  1)普通指针:
    1)类型严格匹配;(2种特殊情况)
  2) 空指针:
  3)void*指针:
  4)指向指针的指针
  5)指向常量的指针
   const int i = 2;
   int * p = &i;//错误,普通整形数不能对应常量
   const int *pi = &i;//正确
   int d = 3;
   pi =&d;//正确,允许指向常量的指针指向一个
       非常量的对象
  6)常量指针(const指针)
   *在const之前,不变的是指针本身的值而非指向的值

 int err =0 ;
 int *const pi = &err;//pi是常量指针,将一直指向err
 const int *const pip = &err;// pi是指向常量的常量指针
  1. 顶层const: 指针本身为常量
    底层const:指针指向常量

更一般:顶层const表示任意的对象是常量;底层则与引用、指针等复合类型相关。指针既可以是顶层,也可以是底层

int i=0;
int *const p1 = &i;//顶层
const int ci =42;//顶层,
const int *p2 = &ci;//底层,指向常量的指针
const int *const p3 = p2;//靠左的是底层,靠右的是顶层,指针p3既是顶层也是底层。
const int &r = ci;//引用和声明的const都是底层

当执行拷贝操作,常量是顶层还是底层区别:
1)顶层不受影响
2)底层:1)拷入和拷出的对象必须具有相同的底层资格,或两个对象的数据类型可以转化,一般,非常量可以转化为常量。反之不行。

int *p = p3;//错误,p是普通的指针,p3是指向常量的常量指针
p2 = p3;//p2、p3是底层的,可
p2 = &i;//可,非常量i可转化为常量
int &r = ci;//错误,普通的int 不能绑定到int常量ci
const int &r2 = i;//const int引用可以绑定到普通的int

简单类型:定义、声明等

声明语句:一个基本数据类型和一个声明符列表
如:

extern int n;//声明
extern double pi =3.14//定义,显性初始化了

复合类型:引用、指针、…

  1. 引用(即别名)
    如:
int val = 3.14;
int &reval = val;//reval是指向val的引用

注:1)引用必须初始化
2)引用时的类型必须匹配(除了2种特殊情况。一种是在初始化常量引用时,允许使用任意表达式作为初始值,只要该结果可以转化为引用的类型就行)
3)只能指向对象,且不能是字面值,或表达式计算结果

int val = 3.14;
int &reval =3.14;//错误,不能指向字面值
double vel = 4;
int &revel = reval;//错误,类型不匹配
  1. 指针
int val = 42;
int *p = &val;

p是指向整型数val的指针,&是取地址符(也是引用的标识符)

注:1)类型应该严格匹配(除了两种特殊情况。第一种:指向常量的指针,允许令指针指向一个非常量对象,但不能通过指针改变其值)

const double p =3.14;
double *ptr =&p;//错误,p是个普通指针,不能指向常量
const double *cptr = &p;//可以,指向常量的指针
*cptr = 42//错误,不能通过指针改变其值
double dval = 3.14;
cptr = &dval;//可以,可以令指向常量的指针指向一个非常量对象
  1. 指针指向地址,加上解引用符*则可以访问该对象
    即给解引用的结果赋值,就是给指针指向的对象赋值

2.1 空指针:指向0、null、nullptr的指针
注:尽量避免使用null,而用nullptr

int *n =0;
if (n) //n为空指针,所以此时条件为false
if(*n)//*n=0,条件为假

2.2 void*指针
特殊类型的指针,可以存放任意类型的对象的地址

注:不能直接操作void*指针所指的对象,因不知道其类型

2.3 写法
int* p1,p2;
p1是指向int的指针,p2是int整型数。

2.4 指向指针的指针

int i = 1024;
int *p = &i;//p是指向int型的指针
int **pi = &p;//pi是指向int型指针p的指针。

2.5 指向指针的引用
(引用不是对象,没有指向引用的指针)

int i = 42;
int *p = &i;
int *&r = p; //r是对指针p的引用**

第三句的读法:从右向左,靠近r的是&,所以是引用,其他部分用以确定r引用的类型是什么。

  1. const限定符
    关键字const对变量的类型加以限定,其值不被改变。

注:1)必须初始化
2)默认情况,仅在本文件内生效,想要文件间共享,使用extern

3.1 const 的引用
1)因为const是对象,可以对其进行引用,称为对常量的引用,简称为“常量引用”,(但其实没有常量引用,因为引用不是一个对象,不能让其不变)
2)对常量的引用不能修改它绑定的对象

const int ci = 1024;
const int &r1 = ci;//正确,类型符合
r1= 42;//错误,r1是常量引用,不能修改其值
int &r2 = ci;//错误,类型不符合,试图让非常量引用指向一个常量

:引用的类型必须一致。例外:
1)初始化常量引用时允许使用任意表达式作为初始值,只要该表达式的结果可以转化成引用的类型就行。

int i =42;
const int &r1 =i;//初始化常量引用,可以const int 和 int 匹配
const int &r2 = 42;//可以,常量引用,
const int &r3 = r1*2;//可以,常量引用
int  &r4 = r1*2;//错误,r4时一个非常量的引用,不能是表达式

2)常量引用不同于常规引用,如1)所示,还有,引用的对象不一定必须是常量,

int i =42;
int &r1 = i;
const int &r2 = i;//r2绑定非常量i合法,但不能通过r2修改。
r1= 0 ;
r2=0;//错误,r2是一个常量引用,不能通过引用修改值。

3.2 指针与const

与引用一样,也可以令指针指向常量或者非常量,指向常量的指针不能通过指针改变其值。要想存放常量对象的地址,只能用指向常量的指针。

3.3 const指针

把指针本身定为常量,常量指针。
*在const前,说明指针是一个常量,不变的是指针本身的值而非指向的值。

int i =0int *const p =&i;//p将一直指向i
const double pi = 3.14;
const double *const pip =π//pip是一个指向常量对象的常量指针。

上述代码,为确定指针的含义,从右往左读,如 p紧挨着const,即p是一个常量对象,其类型由剩余部分确定,第二近的是*说明其是一个常量指针。

顶层const和底层const:

consrexpr和常量表达式:

  1. 常量表达式:
    指值不会改变并且在编译过程中就能得到计算结果的表达式,如字面值。
    一个对象是不是常量表达式是由它的数据类型和初始值共同决定。

  2. 声明为constexpr的变量一定是一个常量,且必须用常量表达式初始化。

constexpr int i = 20;//20是常量表达式
constexpr int j = i+1;//

字面值类型:

包括:算数、引用、指针,还有一些其他的

指针与constexpr :

const int *p = nullptr;//p指向整形常量的指针  底层
constexpr int *q = nullptr;//q是一个指向整数的常量指针  顶层

constexpr指针,既可以指向常量也可以指向非常量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值