C++有三大类类型,内置类型,复合类型,类类型。复合类型是基于其他类型定义的类型。其中内置类型包括整型数,布尔值,字符,浮点数,空类型;类类型是用户自己定义的类;其他的就是复合类型,如引用,指针,数组
复合类型到底有哪些?
一、引用
引用类型是引用另一种类型的符合类型。它本身不是一个对象,是为已经存在的对象另外起了一个名字,并没有定义新的对象,其定义格式如下:
引用类型 &引用名 = 对象原名;
举例如下:
int a = 3;
int &b = a;
- 我们说引用时候一般说的是左值引用,而C++11中新增了一种引用叫做右值引用,这里暂时不讨论。
- 引用类型需要和被引用对象类型相同(常量引用可以引用不同类型的对象)
- 一旦引用定义完成,引用名就和原对象绑定在一起了,不可解绑
- 引用自身不是一个对象,因此不能定义引用的引用
- 定义引用时,等号右边必须是对象,不能是字面值或者表达式的计算结果
- 可以为一个对象定义多个引用
- 可以在一句话中同时存在引用和定义,其中引用前面必须有&,如
int a = 0;
int &b = a, c = a;
//其中b是a的引用;c是int型变量,并使用a的值进行初始化
二、指针
指针定义
指针类型是指向另一种类型的符合类型。其定义格式如下:
指针类型 *指针名 = 指针指向对象的地址;
举例如下:
int a = 1;
int *b = &a; //这里的*是声明b是一个指针,b才是指针名
- 指针类型一般需要与指向的对象类型相同,有两种例外(cosnt指针可以指向非const量)
- 指向对象的地址使用取地址符&获取
指针和引用的区别
- 指针是一个对象,引用不是一个对象
- 同一个指针可以通过重新赋值指向不同的对象,引用只能指向一个对象不能更改
- 指针在定义的时候可以不进行初始化,此时指针有一个不确定的值,即无效指针;而引用必须初始化,即和一个对象绑定
指针的值
- 指针的值(即地址)共有四种:
1. 指向一个对象
2. 指向紧挨着对象的下一个空间
3. 空指针,没有指向任何对选哪个
4. 无效指针,指向上述对象外的指针
- 指向对象的指针可以访问其指向的对象;其他三种指针没有指向任何对象,因此不可以访问其指向的对象
- 拷贝或访问空指针的值是禁止的,但编辑器可能不会报错
访问指针指向的对象
使用解引用符号*对指针指向的对象进行访问:
int a;
int *p; //这里的*是声明p是一个指针,p是指针名
p = &a; //p指针指向a的地址
*p = 0; //这里的*是解引用,访问p指向的对象a,则给a赋值0
空指针
当我们定义了指针却不知道应该指向何处时,可以先将其定义为空指针,定义方法有以下三种:
int *p1 = 0; //也是一种方法
int *p1 = nullptr; //C++11新特性,推荐使用
int *p1 = NULL; //有二义性问题,不推荐使用
- 注意,我们可以使用0来指定指针为空指针,但不能用其他数字或者int类型变量给指针赋值,如:
int a = 0;
int *p;
*p = 0; //使用字面值0的特殊含义指定指针p为空指针
*p = 1; //错误,除了0其他数字不能作为指针字面值
*p = a; //错误,不能将int型变量赋值给指针,即使int变量为0
指针作为判断条件
- 单个指针作为判断条件
指针为空指针结果为false;指针不是空指针(即使是无效指针,当然禁止这么用)为true
int *p = nullptr;
bool a = p; //结果为false
int *p = &c;
bool a = p; //结果为true
- 指针相等判定:指针相等判定的是两个指针的地址是否相等,相等为ture,否则为false。指针相等有四种情况
1.两个指针都是空
2.两个指针指向同一个对象
3.两个指针指向同一个对象的下一个地址
4.一个指针指向一个对象,另外一个指针指向第二个对象的下一个地址,而第一个对象正好
在第二个对象的下一个地址
无类型指针void *
无类型指针是可以存放任意类型的指针,其定义和一般的指针是一样的:
void *p; //定义了无类型指针p
- 由于我们不知道无类型指针到底指向了一个什么类型的对象,因此不能直接操作无类型指针指向的对象
- 无类型指针只有三种用途
1.和其他指针比较地址
2.赋值给另外一个无类型指针
3.作为函数的输入输出
三、复合类型的声明
一个语句定义多种变量
在定义符合类型时,*和&均只是类型修饰符,他们只作用于自身所对应的变量。
int i = 1, *p = &i, &r = i;
//这里i是int型变量,p是int型指针,r是i的引用
在C++中,将*或&和类型写在一起也是合法的,但这容易引起误会:
int* p1,p2; //这里p1为int型指针,p2为int型变量,*只对p1起作用
//因此,一般不要这么写,而是将*和&与变量名写在一起,如果非要这么写,一句话不应定义多个变量,避免引起误会:
int* p1;
int* p2;
指向指针的指针
指针类型修饰符*是可以嵌套的:
int a = 1;
int *p1 = &a;
int **p2 = &p1; //定义指向指针的指针p2,需要用两个修饰符**
同样,解指针的时候也需要修饰符嵌套:
int b = a;
int b = *p1;
int b = **p2; //这三句话都是用a的值给b初始化
由于引用自身不是对象,因此没有引用的引用,但一个对象可以定义多个引用
指向指针的引用
int *p; //定义一个int型指针p
int *&r = p; //为int型号指针p定义一个引用r
//其中修饰符&表明r是一个引用,int和*表明该引用指向一个int型指针
当变量定义具有多个修饰符,从右到左解读,最右边的对变量有最直接影响