指针的使用

指针的语法

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

<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;

总结

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

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

时间: 2024-10-28 11:43:08

指针的使用的相关文章

[c/c++] programming之路(17)、高级指针

一.二级指针 二级指针的作用:1.函数改变外部变量指针2.外挂改变一个指针的值 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 void main(){ 5 int a = 10; 6 int b = 20; 7 int *p1 = &a; 8 int *p2 = &b; 9 int **pp = &p1; 10 printf("%d,", **pp); 11 printf("\n%x,

C++学习笔记----2.4 C++引用在本质上是什么,它和指针到底有什么区别

从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量). 在C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的: 指针传递参数本质上是值传递的方式,它所传递的是一个地址值.值传递过程中,被调

【转】父类子类指针相互转换问题

1.当自己的类指针指向自己类的对象时,无论调用的是虚函数还是实函数,其调用的都是自己的: 2.当指向父类对象的父类指针被强制转换成子类指针时候,子类指针调用函数时,只有非重写函数是自己的,虚函数是父类的: 3.当指向子类对象的子类指针被强制转换成父类指针的时候,也就是父类指针指向子类对象,此时,父类指针调用的虚函数都是子类的,而非虚函数都是自己的. 将上面三句话总结成一句话就是:当父类子类有同名非虚函数的时候,调用的是转换后的指针类型的函数: 当父类子类有同名虚函数的时候呢,调用的是指针转换前指

C++ Primer 学习笔记与思考_7 void和void*指针的使用方法

(一)void的含义 void的字面意思是"无类型",void差点儿仅仅有"凝视"和限制程序的作用,由于从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错.提示"illegal use of type 'void'".只是.即使void a的编译不会出错.它也没有不论什么实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数參数的限定. int f(void); equal t

当this指针成为指向之类的基类指针时,也能形成多态

this指针: 1)对象中没有函数,只有成员变量 2)对象调用函数,通过this指针告诉函数是哪个对象自己谁. 1 #include<iostream> 2 using namespace std; 3 class Shape 4 { 5 public: 6 //void cal_display(Shape* this) 7 void cal_display(){ 8 display(); 9 this->display(); 10 } 11 private: 12 virtual vo

指针x(超简单的x)

指针! 1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 /* 7 相加或者相乘 8 */ 9 10 int main() 11 { 12 int a,b,s,t; 13 cin>>a>>b; 14 int *p; 15 p=&a; 16 int *q; 17 q=&b; 18 s=(*p)+(*q); 19 t=(*p)*(*q); 20 printf(

二重指针实现排序

1 //双指针对十个数排序 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #define N 8 6 //2017.3.5 7 int main() 8 { 9 //初始化数组 赋值N个数 用指针数组指向 10 int num[N]; 11 int *pNum[N]; 12 int **p = NULL; 13 for (int i = 0; i < N; i++) 14 { 15 num[i] = rand() % 100;/

c指针-专题

六---指针 内存和地址怎么理解呢? 机器中有一些位置,每一个位置被称为[字节]/byte,许多现代机器上,每个字节包含8个位.更大内存单位[字],通常包含2个或4个字节组成. 一个字包含4个字节,它的地址是什么? 他仍然只有一个地址,是最左边还是最右边的那个字节的位置,取决于机器. 机器事实-关于整型的起始位置: 在要求边界对齐(boundaryalignment)的机器上,整型存储的起始位置只能是某些特定的字节,通常是2或4的倍数. 变量名和地址关系? 所有高级语言的特性之一,就是通过名字而

智能指针的原理和简单实现

什么是智能指针? 智能指针实质上是一个类,定义一个类来封装资源的分配和释放.这个类的构造函数中传入一个指针,完成资源的分配和初始化.在析构函数中释放传入的该指针,完成资源的释放. 为什么要用智能指针? 智能指针就是智能,自动化的管理指针所指向的动态资源. 例如以下情况:代码中经常会忘记释放动态开辟的内存资源,导致内存泄露. // case1 void Test2() {  int* p1 = new int(2);  bool isEnd = true;  //...  if (isEnd)  

单继承与多继承中的虚函数表和虚函数指针

首先,我们了解一下何为单继承,何为多继承?? 单继承:一个子类只有一个直接父类. 多继承:一个子类有两个或多个直接父类. 单继承中的虚函数表分析: 示例程序: #include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virt