C/C++ 指针详解

有了 chatgpt 或 deepseek 后,学习成本与时间大大降低。想起之前自学 c 语言时花了累计一年看谭浩强的教材,花了一年多看一本 C++ 800多页的大厚书,最终也没有学明白,尤其是指针云里雾里的。感觉借助生成式 AI ,要不了多久,我应该也可以像上手 Java 那样上手 C++ 的大型程序了。

这篇博客基于两个 AI 的回答,整理了指针的相关知识点。

1. 指针的本质

指针本质上是存储地址的变量。普通变量存储的是,而指针存储的是某个变量的地址,它指向这个变量在内存中的位置。

int a = 10;   // 变量 a,存储整数 10
int* p = &a;  // 指针 p,存储 a 的地址

在这段代码中:

  • a 是普通变量,存储数值 10
  • &a 获取 a 的内存地址。
  • p 是指针变量,它存储的是 a 的地址,而不是 a 的值。

2. 指针的存储和工作方式

2.1 变量的存储

假设 a 的地址是 0x100,那么变量 a 在内存中的存储如下:

变量名地址
a0x10010

2.2 指针的存储

指针 p 存储的是 a 的地址 0x100

变量名地址
p0x2000x100
a0x10010

3. 指针的基本操作

3.1 指针声明

指针的声明格式:

数据类型 *指针变量名;

例如:

int* p;   // p 是一个指向 int 类型的指针
double* q; // q 是一个指向 double 类型的指针

3.2 赋值(存储地址)

int a = 10;
int* p = &a;  // p 存储 a 的地址

3.3 取值(解析地址)

cout << *p << endl;  // 输出 10
  • p 是一个变量,存储了另外一个变量 a 的地址。
  • *p 解析指针 p 指向的地址,即得到 a 的值。

3.4 通过指针修改值

*p = 20;  // 通过指针修改 a 的值
cout << a;  // 输出 20

4. 指针和数组

数组名本质上是指向数组第一个元素的指针,即数组第一个元素的地址。

int arr[] = {1, 2, 3};
int* p = arr;  // p 指向 arr[0],相当于 int* p = &arr[0]

cout << *p << endl;     // 输出 1
cout << *(p + 1) << endl; // 输出 2
cout << *(p + 2) << endl; // 输出 3
  • p + 1 指向 arr[1]p + 2 指向 arr[2]

5. 指针的指针

指针可以指向另一个指针:

int a = 10;
int* p = &a;  // p 指向 a,即 p 的值为 a 的地址
int** pp = &p; // pp 指向 p,即 pp 的值为 p 的地址,并不是 *pp 的值为 p 的地址
               // 其实,*pp 表示解析 pp 的值,得到的反而是 p 的值,即 a 的地址
cout << **pp << endl;  // 输出 10
  • p 存储的是 a 的地址
  • **pp 中,里面的*解析 pp 的值(p的地址),得到的是 p的值(a的地址)
  • **pp 中,外面的*解析 p 的值(a的地址),得到的是 a的值
  • 因此**pp 访问 a

我实际测试:

变量名地址
a0x1523d0000(a的地址)10
p0x1523d8000 (p的地址)0x1523d0000 (a的地址)
pp0x1528380000x1523d8000(p的地址)
*p0x1523d0000 (实际是a的地址,因为*p的值为a)10
*pp0x1523d8000 (相当于 &*pp,因此等同于pp的值,即 p 的地址)0x1523d0000(a的地址)
**pp0x1523d0000 (实际是a的地址,因为**p的值为a)10

这个指针套指针,我混淆了很多年了。总结了,一句话:对于形如 int** pp = &p

  • 不管指针变量前面几个星号,指针变量的值为等号右边变量的地址;根据星号解析地址的作用,从里到外一个一个解析就好了。

并且,当 p 为有效指针时,

  • *&p=&*p

6. 指针与动态内存

C++ 允许使用 new 分配堆内存:

int* p = new int(10);  // 分配一个 int
cout << *p << endl;  // 输出 10
delete p;  // 释放内存
  • new 申请内存,返回指针。
  • delete 释放内存。

7. 指针的本质总结

  1. 指针是一个变量,存储的是某个变量的地址,而不是值。
  2. * 用于解引用,访问指针指向的变量。
  3. 指针可以指向数组,指针运算可用于遍历数组。
  4. 指针可以指向指针,实现多级指针。
  5. 指针可以用于动态内存管理,newdelete 操作堆内存。

指针的核心就是存储地址,然后可以通过 * 访问该地址处的数据。指针在 C 和 C++ 中非常重要,理解指针有助于掌握底层内存管理和数据操作!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心态与习惯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值