C++ 什么是指针

2020-11-22  本文已影响0人  付凯强

序言

我们平时所说的指针其实是指针变量。而指针变量,顾名思义,是含有指针的变量。而这个指针指的是内存地址。所以指针变量也可以说是含有内存地址的变量。

指针

系统的内存就像是带有编号的小房间,如果想使用内存就需要得到房间号。假如定义一个整型变量i,它需要4个字节,这个时候编译器为变量i会分配连续编号的小房间,比如4001到4004.每个房间代表一个字节。


一个变量在内存中的存储

在程序代码中通过变量名来对内存单元进行存取操作,代码经过编译后会将变量名转换为该变量在内存的存放地址,对变量值的存取是通过地址进行的。比如,变量i在参与计算的时候,会找到变量名对应的内存地址,首先会找到变量i的地址4001,然后从4001开始读取4个字节数据放到CPU的寄存器中。

由于通过地址能访问指定的内存存储单元,可以说地址“指向”该内存单元,例如房间号4001指向系统内存中的一个字节。地址可以形象的称为指针,即一个变量的地址可以形象的称为该变量的指针。

指针变量

一个变量的地址可以形象的称为该变量的指针,所以存放指针(内存地址)的变量,就是指针变量,而这个变量的类型,称为指针类型。
我们平时所说的指针,是指"指针变量",而不是内存地址,毕竟我们写代码,是通过变量操作地址,而不是直接操作地址。
即我们平时说的指针是一种数据类型,通常说的指针就是指针变量,它是一个专门用来存放地址的变量,而变量的指针主要指变量在内存中的地址。
下文所说的指针都指的是指针变量。

指针的声明和赋值以及关于指针使用的说明

    int *i;
    float *a,*b;

分别声明了整型指针和浮点指针。

    int i = 100;
    int *p_ipoint = &i;
    int *p_ipoint;
    int i = 100;
    p_ipoint = &i;

取值运算符和取地址运算符

"*" 和 "&" 是两个运算符,前者是取值运算符,后者是取地址运算符。

    int a = 100;
    int *p = &a;
    printf("%d\n",p);

    -536471336
    int a = 100;
    int *p = &a;
    std::cout << " a=" << a << std::endl;
    std::cout << " p=" << *p << std::endl;
    a=100
    p=100

指针运算

指针变量存储的是地址值,对指针做运算就等于对地址做运算。

    int a = 100;
    int *p = &a;
    printf("address:%d\n",p);
    p++;
    printf("address:%d\n",p);
    p--;
    printf("address:%d\n",p);

    address:-422471464
    address:-422471460
    address:-422471464

说明:定义指针变量必须指定一个数据类型。

指向空的指针与空类型指针

指针可以指向任何数据类型的数据,包括空类型(void): 定义如下:

void *p;

空类型指针可以接受任何类型的数据,当使用它时,可以将其强制转化为所对应的数据类型。

    int *pI = NULL;
    int i = 4;
    pI = &i;
    float f = 3.333f;
    bool b = true;
    void *pV = NULL;
    cout<<"依次赋值给空指针"<<endl;
    pV = pI;
    cout<<"pV = pI ----- "<<*(int*)pV<<endl;
    cout<<"pV = pI ----- 转为float类型指针"<<*(float*)pV<<endl;
    pV = &f;
    cout<<"pV = &f ----- "<<*(float*)pV<<endl;
    cout<<"pV = &f ----- 转为int类型指针"<<*(int*)pV<<endl;

    依次赋值给空指针
    pV = pI ----- 4
    pV = pI ----- 转为float类型指针5.60519e-45
    pV = &f ----- 3.333
    pV = &f ----- 转为int类型指针1079332831

可以看到空指针被赋值后,转化为对应类型的指针才能得到我们所期望的结果。若将它转换为其他类型的指针,得到的结果将不可预知,非空指针类型指针同样具有这样的特性。

指针常量与指向常量的指针

    int i = 9;
    int* const p = &i;
    cout<<"指针变量p中的指针指向的内存地址是"<<p<<endl;
    cout<<"指针变量p中的指针指向的内存地址是"<<*p<<endl;
    *p = 3;
    cout<<"指针变量p中的指针指向的内存地址是"<<p<<endl;
    cout<<"指针变量p中的指针指向的内存地址是"<<*p<<endl;

    指针变量p中的指针指向的内存地址是0x7ffee86d58d8
    指针变量p中的指针指向的内存地址是9
    指针变量p中的指针指向的内存地址是0x7ffee86d58d8
    指针变量p中的指针指向的内存地址是3

将关键字const放在标识符前,表示这个数据本身是常量,数据类型是int*,即整型指针。与其他常量一样,指针常量必须初始化。我们无法改变常量指针的内存指向,但是可以改变它指向内存的内容。

    int i = 9;
    int const *p = &i;

这是指向常量的指针,虽然其所指向的数据可以通过赋值语句进行修改,但是通过该指针修改内存内容的操作是不被允许的。

    int i = 9;
    int const* const p = &i;

该指针是一个指向常量的指针常量。既不可以改变他的内存指向,也不可以通过他修改指向内存的内容。

后续

如果大家喜欢这篇文章,欢迎点赞;
如果想看更多C++方面的技术知识,欢迎关注!

上一篇下一篇

猜你喜欢

热点阅读