C++STL中swap函数操作与内存地址改变的简析
写在前面
这篇文章主要讨论了STL中swap函数在交换2个容器的内容的时候是交换内存还是交换元素的问题。由于博主对C++的学习并不好,如果有什么错误恳请大家提出。下面会有一些代码展示一下swap函数在对容器进行交换的时候对内存地址的影响,感兴趣的同学也可以自己写一下代码,会更加直观理解swap函数。
先放结论
swap函数会交换2个数据类型相同的容器内容。本身交换的速度非常快,因为swap在交换的时候并不是完全将2个容器的元素互换,而是交换了2个容器内的内存地址。除了数组,其他容器在交换后本质上是将内存地址进行了交换,而元素本身在内存中的位置是没有变化的。换而言之,如果说有2个房间,名字是a和b,那么swap函数交换的是2个房间的名字,而房间里的物品根本没有任何移动。那么外部指向物品的指针当然也没有任何变化,原来指向物品A的,swap交换后仍然指向物品A。而对于数组,
对vector使用swap函数
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main() {
int a[3] = { 1,2,3 };
int b[3] = { 4,5,6 };
vector<int> v1(a, a + 3);
vector<int> v2(b, b + 3);
cout << "v1中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << &v1[i] << " ";
}
cout << endl << "v2中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << &v2[i] << " ";
}
int *temp = &v1[2];
cout << endl << "temp指针指向的数据值:" << endl << *temp;
cout << endl << endl;
swap(v1, v2);
cout << "v1中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << &v1[i] << " ";
}
cout << endl << "v2中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << &v2[i] << " ";
}
cout << endl << "temp指针指向的数据值:" << endl << *temp;
cout << endl;
system("pause");
return 0;
}
下面是在博主计算机上的运行结果:
可以看出,v1与v2的各个元素的地址进行了交换,换而言之就是v1与v2的“名字”进行了交换,而里面的元素该在什么地址仍然在什么地址。
对数组使用swap函数
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main() {
int a[3] = { 1,2,3 };
int b[3] = { 4,5,6 };
cout << "a数组中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << a + i << " ";
}
cout << endl << "b数组中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << b + i << " ";
}
int *temp = a + 2;
cout << endl << "temp指针指向的数据值:" << endl << *temp;
cout << endl << endl;
swap(a, b);
cout << "a数组中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << a + i << " ";
}
cout << endl << "b数组中各个元素的地址:" << endl;
for (int i = 0; i < 3; i++) {
cout << b + i << " ";
}
cout << endl << "temp指针指向的数据值:" << endl << *temp;
cout << endl;
system("pause");
return 0;
}
下面仍然是在博主计算机上运行的结果:
可以看到,对数组进行swap交换后,地址是不变的,也就是说,对于数组,swap函数老老实实将所有的元素进行了交换。房间名不变,将里面的物品交换了位置。对于temp指针而言,temp指向的地址永远是不变的,但是由于交换了元素,所以temp指向的内存地址的数据发生了变化。可以理解为a房间是海尔饮水机,b房间是三星饮水机,temp指向的永远是a房间的饮水机,那么swap交换后,a房间的饮水机变成了三星的,那么temp指向的当然也变成三星饮水机了。
string
以下内容是之前不知道在哪里看的,因为博主不是搞C++的,当时参考的其他内容,并没有过于深究准确性,因为解决了个人问题,所以认为是正确的了。但是不够严谨,推荐大家专门看一下string的源码或者咨询其他搞C++的大佬。欢迎大家看下面的内容,有错误的地方可以评论改正。
string是比较特殊的,因为string的底层实现比较特殊。博主水平不够,就只能参考其他大佬的解释口胡了。
string在调用swap后,迭代器、引用、指针都会失效。因为string的内部实现并不是像C语言自己写的char数组,而是用_Ptr这个指针来储存字符串,指向的是字符串的首地址。字符串是储存在临时内存区域中的,也就是说,在进行交换后,内存会重新分配。所以之前的指针、迭代器等都会失效,因为它们指向的内存地址并不会随着字符串的改变而改变。
关于_Ptr这个指针,我的理解是指向字符串的内存开始,可以参考下面这个代码:
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main() {
string a = "abc";
string b = "def";
for (int i = 0; i < 3; i++) {
cout << &a[i] << " ";
}
cout << endl;
for (int i = 0; i < 3; i++) {
cout << &b[i] << " ";
}
cout << endl << endl;
swap(a, b);
for (int i = 0; i < 3; i++) {
cout << &a[i] << " ";
}
cout << endl;
for (int i = 0; i < 3; i++) {
cout << &b[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
而运行结果如下:
并不是想象中的给出内存地址,而是给出了3个字符串,因为这里得到的是_Ptr指针的内容,所以返回的是3个字符串。
C++STL中swap函数操作与内存地址改变的简析相关推荐
- stl中copy()函数_std :: copy_if()函数以及C ++ STL中的示例
stl中copy()函数 C ++ STL std :: copy_if()函数 (C++ STL std::copy_if() function) copy_if() function is a l ...
- stl中copy()函数_std :: rotate_copy()函数以及C ++ STL中的示例
stl中copy()函数 C ++ STL std :: rotate_copy()函数 (C++ STL std::rotate_copy() function) rotate_copy() fun ...
- stl中map函数_map :: empty()函数以及C ++ STL中的Example
stl中map函数 C ++ STL映射:: empty() (C++ STL map::empty()) It is built-in function in C++ STL and used to ...
- stl中copy()函数_std :: copy()函数以及C ++ STL中的示例
stl中copy()函数 C ++ STL std :: copy()函数 (C++ STL std::copy() function) copy() function is a library fu ...
- stl中map函数_map :: max_size()函数,以及C ++ STL中的Example
stl中map函数 C ++ STL映射:: max_size() (C++ STL map::max_size() ) It returns the maximum number of elemen ...
- c++语言swap函数,C++中swap函数
本文是我用到swap函数时,对其产生好奇,所以结合网上有关博文写下的.个人水平有限,若有错误的地方,欢迎留言指出.谢谢! 一.通用的函数交换模板 template void swap(T &a ...
- python中swap函数_python swap
swap里面的a,b 不会影响函数作用域外面的变量 java也不可以的吧:python里面没有指针,你可以认为所有的东西都是指向的内容,但是不要试图去改变指针的值 其实我觉得所有的对象都是不可变对象, ...
- 关于STL中iota()函数的使用
关于iota函数的介绍 iota()函数用于对STL中具有前向迭代器的容器进行一定范围内的批量递增赋值,简单来说就是可以对一个容器进行值的初始化,而且其中的值是递增的,递增的初始值由第三个参数决定. ...
- java 怎么输出地址,Java中char[]输出不是内存地址的原因详解
前言 Java中共有八种基本数据类型:byte,int,short,long,float,double,char,boolean. 计算机中的基础数据单位是bit, 1byte=8bit. 数据类型 ...
最新文章
- 两款旋转编码器测量LDP3806,BH60
- java自学手记——继承
- 009_JMS中的事务
- 使用CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件
- c语言 多线程 参数,如何用C语言实现多线程
- case mybatis 不同表_解决mybatis case when 报错的问题
- python中math模块函数_Python常用的一些内建函数和math模块函数
- 零基础零代码,也能一周学会动态报表?这个方法很多人都不知道
- php项目导入其他包,将一个外部项目导入Thinkphp环境中
- jquery 利用CSS 控制打印样式
- RAID磁盘阵列与阵列卡
- 【Android】DatePicker时间选择器
- 可以在idle内部执行python命令_2、Python IDLE入门
- w7 声音图标不见了
- Maven工具的学习内容与介绍<第一课>
- TDengineGUI无法连接TDengine
- 计算复杂性第九章——难解性
- linux查看链路聚合的协商信息,Linux 链路聚合
- ECDH算法与mbedTLS
- 基于uni-app实现微信小程序一键登录和退出登录功能
热门文章
- Day11多态部分-6 【1.4 多态的应用以及注意事项】
- [Python图像处理] 十八.图像锐化与边缘检测之Scharr算子、Canny算子和LOG算子
- [Python学习] 专题五.列表基础知识 二维list排序、获取下标和处理txt文本实例
- EduCoder Linux文件/目录高级管理二
- ACM-数论 —— 一.整除的性质
- oracel 中序列
- Java集合(八) 迭代器Iterator、泛型、Map映射
- rm -rf ~/.bashrc 的惨痛教训
- 【MFC】MFC消息映射(二)
- 【工业控制】学习喷墨打印技术 怎么能不知道波形