C++——指针(一)

指针(pointer)

指针变量也称为指针,它保存着一个内存地址,或者说它的值是内存地址。

我们都知道程序运行的时候要放到内存,而程序中的每个符号都要对应一个内存地址。你可以把一个变量看成一个二元组。第一个元素是内存地址(adress),第二个元素是变量的值(value)。指针就保存着这个变量的地址。

指针利用解引用运算符(*)来访问指针指向的地址中的数据,也就是该变量的值。

可以说指针是C++的核心和灵魂。为什么说C语言和C++相比其他语言如Java和Python更接近底层?就是因为指针的存在。指针可以直接操作内存中的地址,这是其他很多语言无法做到的。但是这也是说C++难的一个重要原因。C++程序员需要手动的申请和释放内存,否则可能导致严重的后果,如内存泄漏。

声明指针

dateType* pointerName;

dateType*声明一个某种数据类型的指针变量,如int*,double*。("*"可以放在任何位置,不一定紧挨着dateType,也可以空一格或者挨着pointerName写,但是更推荐挨着dataType写)。

比如我们声明下面的指针:

//int类型的指针
int* pCount;
//char类型的指针
char* pLetter;
//string类型的指针
string* pString;

指针赋值

由于指针保存的是地址,所以我们就要先获取到一个变量的地址。这时候就要用到地址运算符(&)。它是一个一元运算符,放在变量的前面,表示该变量的地址。

#include <iostream>

using namespace std;

int main()
{
    int count = 0;
    char letter = ‘z‘;
    string str = "ABC";

    int* pCount;
    char* pLetter;
    string* pString;

    pCount = &count;
    pLetter = &letter;
    pString = &str;

    cout << "int类型变量count的值为" << *pCount << ",内存地址为" << pCount << endl;
    cout << "char类型变量letter的值为" << *pLetter << ",内存地址为" << pLetter << endl;
    cout << "string类型变量str的值为" << *pString << ",内存地址为" << pString << endl;

    return 0;
}

运行结果:

C++——指针(一)

通过一个指针变量引用变量的方式被称为间接引用,语法如下:

*point

如想让count++可以写为:

//使用指针进行++操作
(*pCount)++;
//相当于count++;

细心的同学应该注意到了。上面的字符指针输出地址时,输出的并非地址而是字符的值。

那么为什么int和string类型的指针可以正常输出16进制的内存地址,而char指针输出了值?可以参考下面博客:

c++中关于char型变量与字符串地址的输出

常量指针

由于指针直接操作内存,所以为了避免对内存的随意修改,可以将不需要改变的指针声明为常量指针。如:

double radius = 5;
//声明指针常量
double* const raduis = &radius;

这样一来就可以防止指针随意被修改而增加安全性。

typedef

C++允许使用typedef关键字来定义同义类型。相当于给原有的数据类型起了一个别名。语法如下:

typedef existingType newType;

如把int定义为integer

//int 与integer同义
typedef int integer;
//下一行代码与int number = 10;表达的意思完全一样
integer number = 10;

那么你可能会问,这么做有什么好处呢?我直接写int它不香嘛?

既然有这个关键字就自然有他的道理。之前的博客里说过,一个好的程序不仅仅是执行效率高,而且非常重要的一点是易读性。我们把int同义定义为integer,对于一个不懂C++的人来说(懂英文),他就可以看懂:噢!一个叫number的整数的值是10。

再比如我们刚学的指针,我们为一个int类型指针定义一个同类型的别名:

typedef int* intPointer;
int number = 10;
intPointer = &number;

把int*同义定义为intPointer,好处有两点。

第一仍然是使程序变得更加易读。

第二是防止在声明指针的时候,防止漏写*

typedef在使用结构体或者联合体的时候,好处更加明显,但这里就不多赘述了。