C 和 C++ 中的指针

大部分照搬了《C 和 C++ 中的指针——可能是中文网络中关于 C 和 C++ 指针最好的文章》

数据、指令和内存

在冯·诺依曼体系中,程序的数据和指令,是存放在同一空间中的。具体到 C 和 C++ 语言来说,对应数据的那部分内存,存储的自然是数据;对应函数的那部分内存,存储的就是指令。
因此,对于内存中存储的内容来说,有两个关键要素:

  • 它在哪里(内存地址是多少);
  • 它具有哪些属性、能做哪些事情(它的类型是什么)。

指针是对内存区域的抽象

C 和 C++ 中的指针变量中存放着目标对象的内存地址,而与指针相符合的类型,则说明了相应内存区域中的内容具有哪些属性,以及能做什么事情。也就是说,在内存空间某块区域中的内容,如果有一个描述这块内存区域的指针存在,我们就能找到它(地址的作用),并且合理地使用它(类型的作用)。

定义和使用指针

指针的定义

在 C 和 C++ 中定义指针变量是很简单的,和定义普通的变量基本是一样的。所有的区别,仅在于我们需要在变量名称前使用解引用符号 * 来标记这是一个指针。

int *ip1, *ip2;   // ip1 和 ip2 都是指向 int 类型变量的指针变量
double d, *dp;    // d 是 double 类型变量,dp 是指向 double 类型变量的指针变量

在上述定义中,我们看到,ip1, ip2, dp是三个指针,因为在定义它们时,在变量名前用 * 号标记他们是指针;而d是一个普通的double类型变量。同时,我们注意到,ip1ip2 在定义之时,就确定了他们是指向int类型的变量。这意味着,被ip1ip2指向的内存,在使用ip1ip2进行访问的时候,将被当做是int类型的对象来对待。同理,dp指向的内存,在使用dp进行访问的时候,将被当做是double类型的对象来对待。
回顾一下,我们在本节中提到,内存空间中的内容有两个关键要素:地址和类型。在上述定义过程中,我们通过类型与解引用符号*相结合,已经确定了类型。如果要正确使用指针,我们还应该让指针记录一个地址。

获取对象的地址

上面说到,我们应该在定义指针之后,记录一个地址。在 C 和 C++ 中,我们需要使用取地址符号&来获取对象的地址。

int val = 42;
int *p  = &val; // &val 返回变量 val 的地址,记录在指向 int 类型变量的指针里

(绝大多数情况下,)指针的类型和对象的类型需要严格匹配。例如,你不能用一个指向int类型的指针变量,保存一个double类型的对象的地址。

double dval = 0.0;
double *pd1 = &dval;// 正确:pd1 保存 double 类型变量 dval 的地址
double *pd2 = pd1;  // 正确:pd1 是 double 类型的指针,可以赋值初始化同样类型的 pd2

int *pi1 = &dval;   // 错误:不能用指向 int 类型变量的指针保存 double 类型变量的地址
int *pi2 = pd1;     // 错误:pd1 是 double 类型的指针,不能将其赋值给 int 类型的指针

访问指针指向的对象

在下例中,指针p记录了变量val的地址。因此,我们可以通过解引用指针p来访问变量val

int val = 42;
int *p  = &val;     // &val 返回变量 val 的地址,记录在指向 int 类型变量的指针里
cout << *p << endl; // 通过指针 p 访问变量 val,输出 val 的值:42

*p = 360;           // 通过指针 p 改变变量 val 的值
cout << *p << endl; // 通过指针 p 访问变量 val,输出 val 的值:360
cout << val << endl;// 输出 val 的值:360
posted @ 2017-08-23 21:52  Planet6174  阅读(419)  评论(0编辑  收藏  举报