前言
很多学习C/C++刚接触指针和引用的同学都不能很好地理解这两个概念,这篇文章主要介绍 C/C++指针和引用 的常规用法。
如有错误,希望各位读者批评指正!
指针和引用
指针的内存结构
所有的指针(不考虑C++中Boost
封装的指针和STL
的迭代器,这里只讨论最基本的指针)都有相同的内存结构, 一个定长的内存区域 ,在这个区域中有一个 内存地址。在32位平台上,这个大小一般是4
字节(理论上由编译器配置决定)。
我们可以将指针内部存放的地址看成一个 无符号整数,表示了该指针指向的内存单元编号。如果该对象占多个连续内存单元,则指向该对象所占用的第一个内存单元,即 首地址。
指针的类型
一般情况下,指针的类型很好判断。比如有以下声明:
int a = 12;
int *b = &a;
我们称变量b
是一个 指向int
类型的指针。这个声明传达了两个信息:
b
是一个指针b
指向的内存区域应被视为一个int
类型的变量
这里的&
符号是对a
取地址,而a
的类型是int
类型,经过取地址操作后产生int
类型的指针。
再举个例子:
int **c = &b;
直接去掉离变量最近的一个*
就可以得到指针的类型,所以c
是一个 指向int*
类型的指针。b
的类型是int
类型的指针,经过取地址操作后生成 int
类型的指针 的指针,表示了b
这个指针本身所占用的内存单元,将这个地址赋值给c
。
我将不同的内存单元用不同的颜色表示,绘制了如下的示意图,希望能帮助您理解。
指针的初始化
在声明指针后立即初始化是一个很好的习惯。如果暂时不需要对这个指针赋值,一般的处理方法是把这个指针赋值为NULL
。NULL
是一个宏定义,在预编译阶段会被编译器替换成0
(一个约定的没有意义的指针)。
请注意,以下两种写法是 等价 的。指针声明中的*
和对指针取指向对象的*
是完全不一样的。
int a = 12;
int *b = &a;
int a = 12;
int *b = NULL;
b = &a;
指针的声明细节
在指针声明中,可能会遇到若干个*
连在一起的情况,如int ***a;
,这个声明与(((int*)*)*) a;
是等价的:表示a
是一个指针,指向的地址域应被识别为((int*)*)
类型。
如果几个不同类型的变量具有相同的 最终对象类型 ,那么是可以在同一个声明语句中声明的;而且由于声明语句的解析顺序从左向右,所以从语法角度讲也可以在声明一个变量后随后声明其指针。
比如:
int a, *b, *c = &a, **d = &c, &e = a, f[12][13] = {
0};
上述声明与下面的声明是等价的:
int a;
int *b;
int *c = &a;
int **d =