1,引用为对象起了一个别名,改变a和改变b的效果一样,一旦引用,不能再绑定到其他对象。
int &a=b;
2,引用必须初始化,且初始值必须是对象。
int &a=10; //错误
3,引用的类型要与之绑定的对象类型严格匹配。
double c=3.22;
int &a=c; //错误
指针
1,指针也实现了对其他对象的间接访问,但与引用不同,指针本身也是对象,可以赋值和拷贝,指针可以不在定义时赋初值。
int *ip1,*ip2;
//ip1和ip2都是指向int型对象的指针。
double dp1,*dp2;
//dp1是double,dp2指向double
dp2=&dp1;
//正确,把dp1的地址赋给dp2指针
2,指针的类型一般与它所指向的对象严格匹配,特殊情况除外。
ip1=&dp1;
//错误,dp1是double,ip1是int型指针。
3,利用指针访问对象。
int val=0;
int *p1=&val;
cout<<*p1;//输出0
4,空指针不指向任何对象,一般建议初始化所有的指针,且尽量在对象定义之后再定义指向它的指针,不然容易出错。
在新表转下,定义指针最好用字面值nullptr来初始化指针。
int *p2=nullptr;//虽然0,NULL也可以
int *p2=0;
int *p2=NULL;
5,指针拥有合法值,则可以作为条件表达式。
if(*p1);//不是空指针,指向val变量的地址,TRUE
if(*p2);//是空指针,FALSE
6,void*指针是一种特殊的指针,可以存放任意类型对象的地址,一个void*可以作为函数输入输出,但是无法访问和操作void*指针所指
的对象。
7,指向指针的指针
int val1=10;
int *p3=&val1;
int **p4=&p3;
所以p4存放着p3的地址,*p4就是p3的内容,就是val1的地址;
**p4就是*p3,就是val1的值。
8,没有指向引用的指针,因为引用不是对象;但是有指向指针的引用。
int val2=22;
int *pp;
int *&r=pp;
r=&val2; //pp指向val2
要理解r 的类型是什么,最简单的方法是从右向左阅读r 的定义。离变量名最近的符号(此例为&)对变量有最直接的影响。
因此r 是一个引用,* 说明r 引用的是一个指针。最后int 说明是引用的是int型指针。
const 限定符
const对象
1,必须初始化,且一旦创建后其值不能被改变。
const int bufsize=256;
bufsize=512;//错误,不能被赋值,但是可以把const赋给别人,因为复制又不改变const变量的值。
2,默认状态下,const对象仅在文件内有效。对于多个文件共享的解决办法是在声明和定义const对象时都加上extern。
const 的引用
const 引用是对常量的引用,如同对int 型的引用,只是对常量的引用不允许通过引用去改变常量的值。
double dd=3.44;
const int &r2=dd;//正确,虽然dd不是常量,虽然不是同一类型。与本文引用第3条对比
r2=8.8;//错误,常量引用不能改变值
const和指针
1,指向常量的指针,与上面指向常量的引用联想,总的来说,指向常量的指针和引用所指的对象不一定是常量,只是自以为指向了常量。
如果是常量就必须用指向常量的指针和引用,不是常量也可以用指向常量的指针和引用,这个时候指针和引用也自觉地不去改变所指的非常量的值。
const double cp=9.33;
const double *ppp=&cp;
2, 常量指针:把指针定义为常量,所以必须初始化。一旦初始化完成,指针所指的地址就不能改变了。把*放在const前面,意味着const的是指针,而不是指针所指的对象。
int t=80;
int *const pp1=&t;//pp1是常量指针,指针不变,所指的值可变。
const int *const pp=&t;//pp是一个指向常量对象的常量指针。地址和值都不能改变。
处理类型
1,类型别名,相当于起了另一个名字。
typedef double wages;//wages等价于double
typedef wages base,*p;//base等价于double,p等价于double*
using wages=double;//wages等价于double
2,auto类型说明符,auto让编译器通过初始值来判断变量的类型,auto定义的变量必须有初始值。
用auto在一条语句声明多个变量时,这些变量的基本数据类型应该一致。
auto i=0,*p3=&i;//正确,auto判断int
auto i=0,pi=3.14;//错误,auto无法判断
3,decltype
int i=99;
decltype(i) ii;//ii为int型
int *p=&i;
int &r=i;
decltype(r) c1;//c1是引用
decltype(r+0) c2;//c2是int
decltype(*p) c3;//c3是int& 引用,需要注意
decltype((i)) c4;//双括号,c4是引用