指针的使用

指针的语法

声明一个指针变量的语法:

<type>  *<ptr_name>;

注:该语法不仅仅指出一个变量为指针,同时表明指针所指向的内存的类型。

指针的指向:变量的地址

指针既可以直接指向新分配的内存,也可以指向一个已经存在的变量。

为了获得变量地址(即变量在内存中的位置),要把符号&放在变量名前。&称为取地址操作符,因为它能返回变量的内存地址:

    int x;
    int *p_x = &x;
    *p_x = 2;
    cout << x << endl;  //输出x的值等于2

&的作用是得到变量的地址。

(记忆方法:字符“&”的单词 ampersand 和“地址” address 都是以 a 打头的,使用&符号就像是通过网站的地址栏获得该网站的URL)

指针的使用通常可以用来做下列两件事:

  • 获得指针中存储的内存地址;
  • 获得内存单元中存储的值。

例如,输出指针 p_pointer_to_integer 指向(存储)的地址:

    int x = 5;
    int *p_pointer_to_integer = &x;
    cout << p_pointer_to_integer;  //输出x的地址
    //等价于 cout << &x

这个代码片段打印输出变量x的内存地址,而这个变量存储在 p_pointer_to_integer 中。

如果要访问内存单元中存储的值,可以使用 操作符,例如:

    int x = 5;
    int *p_pointer_to_integer = &x;
    cout << *p_pointer_to_integer;  //输出5
    //等价于 cout << x

代码 *p_pointer_to_integer 表示“到指针所指向的内存,去取出存储在里面的值”。在这个例子中,指针 *p_pointer_to_integer 指向了变量x,而x的值是5,所以输出了数值5。

使用*来获得指针变量指向的地址的值,这一过程称为间接引用指针(为了获得地址中存储的值,我们是通过一个到该内存地址的引用,使用它,间接地到达目的地)。

通过间接引用指针,还可以修改指针地址所指向的变量的值,例如:

    int x;
    int *p_pointer_to_integer = &x;
    *p_pointer_to_integer = 5;  //x的值现在修改为5
    cout << x;  //输出5

那么,什么时候应该在变量名前加上*号(或&号)?这个很容易出错,为此整理了一下,如下表所示:

操作目的

需要的操作符

示例

声明指针

*

Int *p_x

获得指针所指向的地址

不需要

Cout << p_x

调整指针所指向的地址

不需要

Int *p_x; p_x = /*address*/

获得指针所指向的地址中的值

*

Cout << *p_x

调整指针所指向的地址中的值

*

*p_x = 5;

声明变量

不需要

Int y;

获得变量的值

不需要

Int y; cout << y;

调整变量的值

不需要

Int y; y=5;

获得变量的地址

&

Int y; int *p_x; p_x = &y;

调整变量的地址

不可行

不可以,变量地址不能更改

要记住这张表,切记两个规则:

  • 指针存储的是地址。因此,直接使用“裸”指针(即不带任何符号的指针)得到的就是地址。要获得或调整存储在该地址中的值,必须添加额外的*。
  • 变量存储的是数据值。因此,直接使用变量得到的就是数据值。而要获得变量的地址,就必须额外添加&。

现在,我们通过一个简单的程序来演示下这些功能:

#include <iostream>

using namespace std;

int main()
{
    int x;  //x为普通变量
    int *p_int;  //p_int为指向一个整型数的指针

    p_int = &x;  //将x的地址赋值给p_int
    cout << "Please enter a number: ";
    cin >> x;  //读入一个值并赋给变量x,这里的x也可以用*p_int来代替
    cout << *p_int << '\n';  //使用*来获得指针所指向的变量的值
    *p_int = 10;
    cout << x;  //再次输出10
}

第一个cout输出变量x的值。让我们来逐步地执行程序,观察内存是怎样变化的。我们用箭头来表示指针指向的位置,方框中的数字表示非指针变量在内存中的值。

(1)刚开始,我们有一个整型变量x,以及一个指向整型的指针变量p_int。直观上,可以认为现在有两个值未知的变量:

(2)接着,代码通过使用取地址符(&)获得变量x的地址,并将该地址存储到指针p_int 中。

    p_int = &x;  //将x的地址赋值给p_int

因此,我们可以画一条从变量p_int到变量x的箭头,表示指针p_int指向变量x。

(3)然后用户输入一个数字,存储在变量x中,该存储位置也是p_int所指向的位置。

    cin >> x;  //读入一个值并赋给变量x,这里的x也可以用*p_int来代替

简单起见,我们假设用户输入数字5.现在内存的情况变成了这样:

(4)接着,下一行代码将*p_int传给cout。p_int间接引用了p_int,它会检查p_int中的地址,并且到该地址中取出其变量值。

    cout << *p_int << '\n';  //使用*来获得指针所指向的变量的值

(5)最后的两行语句表面,通过指针可以修改变量原来的值。这个语句将值10存储到p_int所指向的内存中,也就是存储着变量x的值的内存。

    *p_int = 10;

 总结

 在学习数据结构的时候,发现对指针这块还是有些模糊,于是回顾了一下指针,将其收获和感受写了下来。

此次学习使我了解了使用指针的好处之一就是方便修改其所指向内存的值;清楚了什么时候应该在变量名前加上*号(或&号);当搞不明白使用指针时内存的变化过程时,可以先绘制出内存的初始状态,配合箭头图逐步执行程序,内存的变化过程也就一目了然了,每当指针的指向改变时,便绘制新的箭头,每当变量的值发生变化时,更新它的值。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浅谈main(),int main(),void main(),int main(void)四者之间的区别

    Zoctopus
  • 求 pi 的近似值题型汇总

    Zoctopus
  • 2014年第五届蓝桥杯C/C++B组省赛题目解析

    Zoctopus
  • C++程序员经常问的11个问题

    这篇文章收了好长时间,但还是觉得贴出来,作为收藏,在网上这样的浮躁环境,很少能认认真真地看这样长的文章,有时间我也要把《Effective C++》的读书笔记作...

    阳光岛主
  • 【设计模式】—— 迭代模式Iterator

      模式意图   提供一个方法按顺序遍历一个集合内的元素,而又不需要暴露该对象的内部表示。   应用场景   1 访问一个聚合的对象,而不需要暴露对象的内部表...

    用户1154259
  • Xdigger Framework:一款网络安全测试辅助框架

    *本文作者、Xdigger Framework开发者:guyoung Xdigger Framework是一款基于.Net Framework的网络安全测试辅助...

    FB客服
  • Linux常用操作

    修改/etc/sysconfig/network-scripts/ifcfg-ens192文件

    剑行者
  • 127.0.0.1 vs 0.0.0.0 vs localhost vs 主机IP

    说明:上一篇写完《当你输入URL到页面显示经历了什么--URL到IP地址》之后读了好几本关于网络的书(当然都是跳着读),发现期初想的太简单,还是遗漏了许多,后面...

    前端黑板报
  • 程会玩 | 在.NET Core里操作Git

    Git是很多程序员的首选源代码版本控制工具,我最近也从TFVC切换到了Git,受益匪浅。今天我就来带大家看看如何在.NET Core里操作Git。

    Edi Wang
  • Java中的两个关键字——super、this

    1、当子类和父类都有同名的属性时,在子类中如果要使用父类的属性 super . 属性

    用户6182664

扫码关注云+社区

领取腾讯云代金券