c++基础——指针
创始人
2024-05-30 05:57:16
0

变量的地址、指针

在程序中,我们的数据都有其存储的地址。在程序每次的实际运行过程中,变量在物理内存中的存储位置不尽相同。不过,我们仍能够在编程时,通过一定的语句,来取得数据在内存中的地址。

地址也是数据。存放地址所用的变量类型有一个特殊的名字,叫做“指针变量”,有时也简称做“指针”。

地址只是一个刻度一般的数据,为了针对不同类型的数据,“指针变量”也有不同的类型,比如,可以有 int 类型的指针变量,其中存储的地址(即指针变量存储的数值)对应一块大小为 32 位的空间的起始地址;有 char 类型的指针变量,其中存储的地址对应一块 8 位的空间的起始地址。

事实上,用户也可以声明指向指针变量的指针变量。

假如用户自定义了一个结构体:

struct q {int a;int b;int c;
};

则 q 类型的指针变量,对应着一块 3 × 32 = 96 bit 的空间。

指针的声明与使用

C/C++ 中,指针变量的类型为类型名后加上一个星号 *。比如,int 类型的指针变量的类型名即为 int*。

我们可以使用 & 符号取得一个变量的地址。

要想访问指针变量地址所对应的空间(又称指针所 指向 的空间),需要对指针变量进行 解引用(dereference),使用 * 符号。

int main() {int a = 123;  // a: 123int* pa = &a;*pa = 321;  // a: 321
}

对结构体变量也是类似。如果要访问指针指向的结构中的成员,需要先对指针进行解引用,再使用 . 成员关系运算符。不过,更推荐使用“箭头”运算符 -> 这一更简便的写法。

struct q {int a;int b;int c;
};int main() {q x{1, 2, 3}, y{6, 7, 8};q* px = &x;(*px) = y;    // x: {6,7,8}(*px).a = 4;  // x: {4,7,8}px->b = 5;    // x: {4,5,8}
}

指针的偏移

指针变量也可以 和整数 进行加减操作。对于 int 型指针,每加 1(递增 1),其指向的地址偏移 32 位(即 4 个字节);若加 2,则指向的地址偏移 2 × 32 = 64 位。同理,对于 char 型指针,每次递增,其指向的地址偏移 8 位(即 1 个字节)。

使用指针偏移访问数组

我们前面说过,数组是一块连续的存储空间。而在 C/C++ 中,直接使用数组名,得到的是数组的起始地址。

int main() {int a[3] = {1, 2, 3};int* p = a;  // p 指向 a[0]*p = 4;      // a: [4, 2, 3]p = p + 1;   // p 指向 a[1]*p = 5;      // a: [4, 5, 3]p++;         // p 指向 a[2]*p = 6;      // a: [4, 5, 6]
}

当通过指针访问数组中的元素时,往往需要用到“指针的偏移”,换句话说,即通过一个基地址(数组起始的地址)加上偏移量来访问。

我们常用 [] 运算符来访问数组中某一指定偏移量处的元素。比如 a[3] 或者 p[4]。这种写法和对指针进行运算后再引用是等价的,即 p[4] 和 *(p + 4) 是等价的两种写法。

指针的进阶使用

使用指针,使得程序编写者可以操作程序运行时中各处的数据,而不必局限于作用域。

指针类型参数的使用

在 C/C++ 中,调用函数(过程)时使用的参数,均以拷贝的形式传入子过程中(引用除外,会在后续介绍)。默认情况下,函数仅能通过返回值,将结果返回到调用处。但是,如果某个函数希望修改其外部的数据,或者某个结构体/类的数据量较为庞大、不宜进行拷贝,这时,则可以通过向其传入外部数据的地址,便得以在其中访问甚至修改外部数据。

下面的 q 方法,通过接收两个 int 型的指针,在函数中使用中间变量,完成对两个 int 型变量值的交换。

void q(int *a, int *b) {int t;t = *a;*a = *b;*b = t;
}int main() {int a = 6, b = 10;q(&a, &b);// 调用后,main 函数中 a 变量的值变为 10,b 变量的值变为 6
}

动态实例化

除此之外,程序编写时往往会涉及到动态内存分配,即,程序会在运行时,向操作系统动态地申请或归还存放数据所需的内存。当程序通过调用操作系统接口申请内存时,操作系统将返回程序所申请空间的地址。要使用这块空间,我们需要将这块空间的地址存储在指针变量中。

在 C++ 中,我们使用 new 运算符来获取一块内存,使用 delete 运算符释放某指针所指向的空间。

int* p = new int(1234);
/* ... */
delete p;

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...