指针运算的一点小结

本文深入探讨了C++中指针的基本概念与使用技巧,包括指针与变量的关系、指针操作注意事项、指针与数组的关系,以及如何避免野指针等问题。文中还通过实例演示了delete操作的影响和正确用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

详情看代码,有详细注释。特别强调的是当 p 指向一个变量比如 a 时, 我们发现尽管 delete p 了,但是似乎依然可以得到 a 的值, 这其实是错误的,比如 a 最初为 5, delete运算后令 a = 10, 但此时 *p还是等于5. 

delete的时候,系统只是将指针指向 的堆空间回收,但是没有将这个指针变量的值赋为NULL,所以delete一个指针后应将其赋为NULL, 不然容易导致野指针的出现。


delete 一个指针变量后一定要将该变量赋为NULL!!!


带指针的结构体比如二叉树等,一定要在构造的时候先把指针全部置为NULL, 否则出现段错误,野指针等不可预知的错误。


#include <bits/stdc++.h>
#define endl "\n"

using namespace std;

int main(){
	ios::sync_with_stdio(false);
	int m;
	while(cin >> m) {
		
		int *p1 = &m;
		// int型指针变量p1中的内容(m的地址)  p1的地址 p2指向的变量m
		cout << " ---> p1 &p1 *p1 " << p1 << "  "  << &p1 << "  "  << *p1 << endl;
		int *p2 = &m;
		cout << " ---> p2 &p2 *p2 " << p2 << "  " << &p2 << "  " << *p2 << endl;
		(*p2)++;  // p2指向的变量m+1
		cout << " ---> p2 *p2 " << p2 << "  " << *p2 << endl;
		cout << " ---> p1 *p1 " << p1 << "  " << *p1 << endl;
		int *p3 = p1;
		(*p3)++;  // p3指向的变量m+1
		cout << " ---> p1 &p1 *p1 " << p1 << "  " << &p1 << "  " << *p1 << endl;
		cout << " ---> p3 &p3 *p3 " << p3 << "  " << &p3 << "  " << *p3 << endl;
		
		cout << " ---- after delete p3 ----" << endl;
		delete p3;
		cout << " ---> p1 &p1 *p1 " << p1 << "  " << &p1 << "  " << *p1 << endl;
		// *p3还是m的值,并不是delete后还能获取m的地址及m,delete p3后对m做任何更改*p3输出
		// 还是为delete p3前m的值
		cout << " ---> p3 &p3 *p3 " << p3 << "  " << &p3 << "  " << *p3 << endl;
		int a = 5;
		int *p = new int(a);
		// *p = 5
		cout << " ---> p &p *p  " << p << "  " << &p << "  " << *p << endl;
		cout << " after delete p " << endl;
		delete p;
		// *p还是等于5
		cout << " ---> p &p *p  " << p << "  " << &p << "  " << *p << endl;
		cout << " ---- after a = 10 ---- " << endl;
		a = 10;
		// a的值改变后 *p还是等于5,*p已经不代表a的值了
		cout << " ---> p &p *p  " << p << "  " << &p << "  " << *p << endl;
		cout << " ---- after make p = &a again ---- " << endl;
		p = &a;
		// *p又等于10
		cout << " ---> &p   *p  " << &p << "  " << *p << endl;
		
		int arr[] = {1, 2, 3};
		int *ptr = arr;
		// ptr中是arr[0]的地址 &ptr是ptr变量的地址 *ptr是ptr指向的arr[0]的值
		cout << " ---> ptr &ptr *ptr " << ptr << " " << &ptr << " " << *ptr << endl;
		// 不能有形如 &ptr++ 的形式, 地址值不可做此运算
		// ptr指向下一个内存单元,单元大小取决于指针类型, 这里int型则加4(与机器有关),
		// 如果是类的对象,那就看该类的一个对象许多多大的内存单元
		cout << " ptr++ " << ptr++ << endl; 
		cout << " ptr " << ptr << endl;  // ptr现在指向arr[1]
		// (*ptr)++先解指针得到arr[1]再将arr[1]+1
		cout << " (*ptr)++ " << (*ptr)++ << endl;
		// ptr指向arr[1] arr[1]现在等于3
		cout << " ptr *ptr " << ptr << " " << *ptr << endl;
		cout << arr[0] << " " << arr[1] << " " << arr[2] << endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值