序言
本文介绍C++中引用,指针,const限定符和常量表达式等几个部分的内容。对应原书45页——60页。
引用
引用为对象起了另外一个名字,引用类型可以引用另外一种类型。通常情况下可以将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。
- 举例如下
int a = 16; int &b = a; //b是a的引用,需要在b前加引用符& int &c; //错误,没有初始化!!!
- 引用的实质:引用并不是对象,而是对象的一个新名字,所有对引用的操作实际是都是在对源对象进行操作。
- 引用的定义:允许在一行中定义多个引用但是每个引用前必须有&限定,例如
int a = 1, b = 2; int &c = a, &d = b;
指针
指针是“指向”另外一种类型的复合类型,可以像引用一样实现对其他对象的间接引用。但是它有两点和引用不同——
- 指针本身是对象,可以对指针本身进行赋值和访问,而且可以在指针的生命周期内先后指向不同的对象
- 指针在定义的时候无需赋初值。和其他类型相似,如果在快作用域中的指针没有被初始化,则会拥有一个不确定的值。
指针基础知识
举例如下
//指针定义 int a = 1; int *b = &a; //用取地址符&取得a的地址,并将地址赋值给b int *c = b; //此时b和c其实是一样的 //用指针访问对象(仅适用于有效指针) cout << *b; //用解引用符*得到原指针指向的对象的值 *b = 0x7fff; //此时a的值被赋成0x7fff
指针的定义:允许一行对多个指针类型进行声明和定义
int a = 1, b = 2; int *c = &a, *d = &b;
空指针
- 一般要用
nullptr
进行初始化 - 空指针不能使用解引用符进行解引用
- 一般要用
关于
void
void
是一种比较特殊的指针类型,可以指向任意对象,存放任意对象的地址,但是也仅限于存放,不能进行访问,也不可以直接操作void*
所指的对象。- void可以做的事:
和其他指针进行比较、作为函数的输入和输出、或者赋值给另外一个
void*
指针。
指向指针的指针
int a = 1; int *b = &a; //b指向的是“int型” int **c = &b; //c指向的是“指向int的指针”
对指针的引用
int i = 1; int *p = &i; int *&r = p;
指针数组和数组指针
基本解释(参考这篇博客)
指针数组:指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。
数组指针:数组指针可以说成是”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。`
指针数组
- 指针数组的定义
char *a = {"red", "blue", "green"};
- 函数形参使用指针数组
//first method int function(char *a[]){ //... } //second method int function(char **a){ //... }
- 指针数组的定义
数组指针
- 数组指针的定义(注意此时是
(*p)
)
int a[5][4] = {0}; int (*p1)[4] = a; int (*p2)[4] = &a[0]; //p1和p2都是指向二维数组a的首地址
- 函数形参使用二维数组可用数组指针
void f1(a[][4]){ //... } void f2((*p)[4]){ //... } int main(){ int a[5][4]; f1(a); f2(a); return 0 }
### 指针函数,函数指针和函数指针数组
- 数组指针的定义(注意此时是
指针函数
- 定义:指针函数就是返回指针值的函数,本质是一个函数。所以指针函数等价于“返回值为指针的函数”
- 用法:
int *GetNum(int x); //指针函数声明形式
由此可以看出,指针函数的本质仍然是函数,可以把它当作一般函数来声明和使用。
函数指针
- 定义:函数指针就是一个指向函数的指针。每个函数在编译时,会被分配一个入口地址,一般用函数名来表示,这个地址就是该函数的指针。
- 用法1:(基础用法)
int max(int a, int b) { return a>b ? a : b; } int main() { int(*func)(int, int); //定义一个指向该函数形式的指针变量 func = max; cout << func(1, 2) << endl; return 0; }
- 用法2:(typedef)
typedef int(*func)(int, int); int max(int a, int b) { return a>b ? a : b; } void main(void){ func newfunc = max; cout << newfunc(1, 2) << endl; return 0; }
函数指针数组
- 定义:顾名思义,就是每个元素都是函数指针的数组,直接在函数指针名后面加上数组符号[ ]即可。
- 用法
void f1(){ cout << "f1" << endl; } void f2(){ cout << "f2" << endl; } void f3(){ cout << "f3" << endl; } int main() { //定义三个函数指针 void(*pf1)() = &f1; void(*pf2)() = &f2; void(*pf3)() = &f3; //接下来就是定义一个数组把他们三个装进去。 void(*pfarr[3])(); void(*pfunarr[3])(); pfunarr[0] = pfun; pfunarr[1] = pfun2; pfunarr[2] = pfun3; /* 或者这样赋值 pfunarr[0] = &fun1; pfunarr[1] = &fun2; pfunarr[2] = &fun3; */ pfunarr[0](); pfunarr[1](); pfunarr[2](); /* 或者这样调用 (*pfunarr[0])(); (*pfunarr[1])(); (*pfunarr[2])(); }
从上述代码中也可以看出来,函数名实际上就是函数地址,这一点与数组有异曲同工之妙。