c++基础:复合类型与const限定符

(A).复合类型

一.引用(左值引用):引用不是对象,是“别名”
1.定义引用类型:等号左边出现&,定义一个引用类型

int ival = 1024 ;
int &refVal = ival ;  // 对,refVal与 ival绑定,
                      // 且之后 rafVal只能绑定这一个对象
int &refVal2 ;  // 错,引用必须初始化

2.引用相关的操作
引用的类型必须与对象的类型一致,但有两个例外

refVal = 2 ; // ival = 2 
int ii = refVal ; // ii = ival = 1024
int &refVal3 = refVal ; // refVal与 ival绑定
int &refVal4 = 10 ; // 错,引用类型的初始值只能是对象
double dval = 3.14 ;
int &refVal5 = dval ; // 错,引用类型和绑定对象类型不匹配

二.指针:指针本身是一个对象,可先后指向不同对象,无需在定义时赋初值
1.定义指针

int *lp1 , *lp2 ; //未初始化的指针
int ival = 42 ;
int *p = &ival ; // p存放 ival的地址
double dval ;
double *pd = &dval ;
int *pi = pd ; // 错,类型不匹配
int* p1 , p2 ; // p1是指针,p2是 int类型的变量
int ival = 1024 ;
int *pi = &ival ;
int **ppi = &pi ; //ppi指向一个 int型的指针 pi

2.指针相关的操作
定义时:int *p = &变量(变量的地址)= p2(另一个指针);
已定义p为指针:p = &变量(变量的地址)= p2(另一个指针);
*p (解引用,*p指p所指的对象)= 变量 = 常数 ;

int ival = 42 ;
int *p = &ival ;
*p = 0 ; // ival = 0 
int *p1 ;
p1 = p ; // p1也指向对象 ival

3.空指针

int *p1 = nullptr ;
int *p2 = 0 ;
int *p3 = NULL ; // 需要 #include cstdlib

4.void* 指针

double obj = 3.14 ;
void *pv = &obj ; // void指针可以存放任意类型对象的地址

三.指向指针的引用
引用不是对象,所以不能定义指向引用的指针(引用没有地址)

int i = 42 ;
int *p ;
int *&r = p ; // r是引用(从右往左读),它绑定了一个 int型指针 p
r = &i ; // p = &i ,令 p指向 i
*r = 0 ; // *p = i = 0 ,给 i赋值为 0

(B).const限定符

1.const类型对象的定义

const int i = 42 ;
const int k ; // 错,必须初始化

2.指向const的引用(引用自身不是const类型,引用认为自己所指向的对象是const类型的)
必须初始化。
1).引用const,对象const(引用非const,对象const的情况不允许)

const int ci = 42 ;
const int &r1 = ci ; // 引用是const,引用的对象是 const
r1 = 42 ; // 错,r1是常量引用,不能通过常量引用改变对象的值
int &r2 = ci ; // 错,引用不是 const,引用的对象是const,不匹配

2).引用const,初始值非const
初始化常量引用时,初始值可以是任何表达式,只要该表达式的结果能转换成const int/double等即可;

int i = 42 ;
const int &r1 = i ; // 对,引用是 const,引用的对象(初始值)是 int
const int &r2 = 42 ; // 对,引用是 const,初始值是常数
int &r4 = r1 * 2 ; // 错,引用不是 const,引用的对象是 const int,不匹配
int i = 42 ;
int &r1 = i ;
const int &r2 = i ;
r1 = 0 ; // 对
r2 = 0 ; // 错

原因如下:

double dval = 3.14 ;
const int &ri = dval ; // 对
//编译器把上述代码变成如下形式:
const int temp = dval ; // 将 dval转换成了const int型
const int &ri = temp ; // ri绑定了一个临时量
// ri不是 const时,ri绑定了临时量而非 dval,操作 ri时不是操作 dval,没有意义

3.指向常量的指针(指针自身不是const类型,指针认为自己所指向的对象是const类型的)
必须初始化。
可以先后指向不同的对象
1).指针const,对象const(指针非const,对象const不允许)

const double pi = 3.14 ;
double *ptr = &pi ; //错,指针非 const,对象是 const
const double *cptr = &pi ; // 对
*cptr = 0 ; //错,不能通过const指针 cptr改变对象的值

2).指针const,对象非const

double dval = 3.14 ;
const double *cptr = &dval ; // 对,但不能通过 cptr改变 dval的值

4.常量指针
指针是对象而引用不是,所以可以把指针本身定为常量,不变的是指针本身存放的地址,不是该地址中储存的对象。

int errNumb = 42 ;
int *const curErr = &errNumb ; //常量指针 curErr一直指向 int型对象 errNumb
*curErr = 0// 正确,errNumb = 0 
int *const p ; // 错,常量指针必须初始化

5.顶层const和底层const
顶层const:表示指针本身是常量,表示其他任意对象是常量
底层const:表示指针所指的对象是常量,表示引用的对象是常量

int i = 0 ;
int *const p1 = &i ; // 顶层 const
const int ci = 42 ; // 顶层 const
const int *p2 = &ci ; // 底层 const
const int &r = ci ; // 声明引用的 const都是底层 const

```cpp
const int ci = 42 ;
const int *p2 = &ci ;
const int *const p3 = p2 ; // p3指向 ci
int *p = p3 ; //错,p不能指向 ci

©.constexpr和常量表达式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值