指针初步续集

本文探讨了指针等级的概念,解释了不同等级指针在加1操作时的行为差异,并通过三维数组实例展示了如何理解指针的不同等级及其与数组名之间的联系。

       上次我们看了指针的简单理解,和数组名当首元素地址指针,并且看到了数组名这个指针是依附在首元素地址上的。这次我们看看指针的等级。

对于一个三维数组,我们看看他们各个首是什么情况,

 

与我们预计一样,各个首地址都是相同的,无论是指针还是首元素。

那我们如果给他加1会怎么样?

 我们可以看到结果有很大的差别,明明都是同一个东西,为什么加1之后的差别怎么大,加1后的东西又是什么。那我们来逐步探究一下这些东西。

 

 先看&a[0][0][0]+1,这个很简单,按照我们之前的思想,地址+1就是往后移动一位,一个·int四个字节,正好相差4,所有他的结果应该和a[0][0][1]的结果,结果确实如此。

接下来看&a[0][0]+1,按照我们之前的显示,这地址都是同一个,都是1699728,那加1得到的结果应该相同 都是1699732。但是结果显示确实1699768.与之前相差了40,与a[0][1]的地址相同。并且我们也可以看出,即使是三维数组,其实他在内存中还是连续的,并不是说是立体的那种。如果我们不把a看作三维数组,这个结果我们确实可以接受,a[0][0]的地址加1变成a[0][1]的地址,卡看起来也很合理。那这种情况说明了说明呢?我们之前说的这个加1是广义上的加1。指的是加一个与自身相同的单位。那这是不是说明了一个地址,他是有不同的等级,所有导致他加1的时候,因为等级不同,加1加的大小也不同。那有等级的话,我们就可以将我们数组分一下类。

小数组0:a[0][0][0],a[0][0][1],a[0][0][2],.........a[0][0][9];我们知道这10个元素,有一个老大,是a[0][0][0],所以他们的老大,授予a[0][0]称号,

小数组1:a[0][1][0],a[0][1][1],a[0][1][2],.....a[0][1][9],我们知道这10个元素,有一个老大,是a[0][1][0],所以他们的老大,授予a[0][1]称号,

。。。。。。

小数组9:。。。。。

那我们知道这10个小数组,分别有10个老大,是a[0][0],a[0][1],.....a[0][9],在其中,再次挑选一个老大,授予a[0]称号。

同样的,还有另外数组老大被授予a[1],a[2],.....a[9],其中又要选择一个老大,那就当然是第一个a[0]了,授予a称号。

那我们看看a是什么,a是a[0],a[0]是什么,a[0]是a[0][0],a[0][0]是什么,是a[0][0][0]的地址。所以他们都是同一个地址,确实拥有不同的身份。类似于战争中的战斗编队,一个战斗班,10个人,1号是班长,10个班为一个排,1号班长担任排长,10个排为一个连,1号排长担任连长。那么这个连长是谁,其实他就是1排1班的1号战士。只是他同时具有,战士,班长,排长,连长这些职务。假设他们要站队报数,如果他作为一个战士报数1,那么报2的应该是他们班的二号战士,如果他作为一个班长报数1,那么报2的应该是这个排的二班的班长,如果他作为排长报数1,那么报2的应该是二排长,如果他作为连长来报数1,那么报2的应该是下一个连的连长。

指针等级:我们看到数组名的等级,那指针等级是不是也一样呢?

 

 

我们看到三级指针指向a,实际指向的是最小的那一个级别的指针,因为他加1,地址只增加了4,并且只能做1次解引用。那如果我们用更低或者更高的指针去指向呢?

 我们可以看到,用更高的去指向,结果还是一样。那更低的比如二级指针呢,那这就报错了,不可以。那我们可以得出结论,指针的级别只能等同或高于数组级别。并且指向最低级别。

结论:数组名的指针虽然地址相同,但是是有级别,不论几维数组地址也是连续的,普通指针的级别只能等同或高于数组级别。

 

### C++ 智能指针初步使用教程 智能指针是C++中用于管理动态分配内存的一种工具,它通过封装普通指针,利用RAII(Resource Acquisition Is Initialization)机制,在对象生命周期结束时自动释放资源,从而避免内存泄漏等问题[^3]。 #### 1. 智能指针的基本概念 智能指针本质上是一个类模板,它内部维护一个指向动态分配对象的普通指针。当智能指针对象被销毁时,其析构函数会自动释放所管理的内存资源[^4]。 #### 2. 常见的智能指针类型 C++标准库提供了三种主要的智能指针类型:`std::unique_ptr`、`std::shared_ptr` 和 `std::weak_ptr`。 - **`std::unique_ptr`** `std::unique_ptr` 是一种独占所有权的智能指针,意味着同一时间只能有一个 `std::unique_ptr` 管理某个对象。它的实现基于移动语义,不能进行拷贝操作,但可以通过 `std::move` 进行所有权转移[^5]。 ```cpp #include <iostream> #include <memory> int main() { std::unique_ptr<int> ptr1(new int(10)); // 下面的代码会导致编译错误,因为 unique_ptr 不支持拷贝 // std::unique_ptr<int> ptr2 = ptr1; // 使用 std::move 进行所有权转移 std::unique_ptr<int> ptr2 = std::move(ptr1); if (!ptr1) { std::cout << "ptr1 is null after move." << std::endl; } std::cout << *ptr2 << std::endl; return 0; } ``` - **`std::shared_ptr`** `std::shared_ptr` 是一种共享所有权的智能指针,允许多个 `std::shared_ptr` 实例同时管理同一个对象。它通过引用计数机制来跟踪有多少个 `std::shared_ptr` 实例指向同一个对象。当最后一个 `std::shared_ptr` 被销毁或重置时,才会释放所管理的对象[^4]。 ```cpp #include <iostream> #include <memory> int main() { std::shared_ptr<int> ptr1 = std::make_shared<int>(10); std::shared_ptr<int> ptr2 = ptr1; // 引用计数加1 std::cout << "Use count: " << ptr1.use_count() << std::endl; // 输出 2 ptr1.reset(); // 引用计数减1 std::cout << "Use count after reset: " << ptr2.use_count() << std::endl; // 输出 1 return 0; } ``` - **`std::weak_ptr`** `std::weak_ptr` 是一种不控制对象生命周期的智能指针,通常与 `std::shared_ptr` 配合使用。它不会增加引用计数,因此不会阻止所指向对象的销毁。`std::weak_ptr` 主要用于解决 `std::shared_ptr` 的循环引用问题。 ```cpp #include <iostream> #include <memory> struct Node { std::shared_ptr<Node> next; }; int main() { std::shared_ptr<Node> node1 = std::make_shared<Node>(); std::shared_ptr<Node> node2 = std::make_shared<Node>(); node1->next = node2; node2->next = node1; // 循环引用 // 使用 weak_ptr 解决循环引用 std::weak_ptr<Node> weakNode = node1; if (auto lockedNode = weakNode.lock()) { std::cout << "Node still exists." << std::endl; } else { std::cout << "Node has been destroyed." << std::endl; } return 0; } ``` #### 3. 智能指针的优势 智能指针的主要优势在于能够自动管理动态分配的内存,减少手动调用 `delete` 的需求,从而降低内存泄漏的风险。此外,智能指针还提供了线程安全的引用计数机制和灵活的所有权管理方式[^4]。 #### 4. 注意事项 - 在使用 `std::shared_ptr` 时,需要注意避免循环引用问题,否则可能导致内存泄漏。 - 使用 `std::make_shared` 创建 `std::shared_ptr` 是推荐的做法,因为它比直接传递裸指针更高效且安全[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值