c++

【C++专题】数组

Posted by 卢小胖 on 2021-09-20
Estimated Reading Time 9 Minutes
Words 1.9k In Total
Viewed Times

数组是一个固定大小、相同类型的连续有序集合,是一块连续的内存块

数组的几种实现方式

原生数组

c++原生提供的数据结构,创建形式为:

type name[size]

type为数据类型,name为名称,size为初始化大小

初始化:

char name[4];

初始化并赋值:

char name[4] = {'A','B','C','D'};

Vector

vector意思:向量,是可以自由增删的数组,简称的动态数组,和java中的ArrayList类似。

使用需要导入头文件:

#include <vector>

初始化:

vector<int> test;

常用方法:

1.push_back 在数组的最后添加一个数据

2.pop_back 去掉数组的最后一个数据

3.at 得到编号位置的数据

4.begin 得到数组头的指针

5.end 得到数组的最后一个单元+1的指针

6.front 得到数组头的引用

7.back 得到数组的最后一个单元的引用

8.max_size 得到vector最大可以是多大

9.capacity 当前vector分配的大小

10.size 当前使用数据的大小

11.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值

12.reserve 改变当前vecotr所分配空间的大小

13.erase 删除指针指向的数据项

14.clear 清空当前的vector

15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)

16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)

17.empty 判断vector是否为空

18.swap 与另一个vector交换数据

实例:

#include <iostream>
#include <vector>
#include <array>

using namespace std;

int main(){

vector<int> test;

for (size_t i = 0; i < 100; i++)
{
test.push_back(i);
}

for (size_t i = 0; i < 50; i++)
{
test.pop_back();
}

// 更新数据
test[10] = 123;
test[11] = 112;
//更新第13个数据
test.insert(test.begin()+12,110);

// 删除数据
// 删除test[1]
test.erase(test.begin()+1);

// 普通遍历方式
for (size_t i = 0; i < test.size(); i++)
{
cout << test[i] << endl;
}

system("pause");
return 0;
}

数组中的指针和迭代器:

cout << "test begin:" << *test.begin() <<endl;
// 数组的最后一个单元+1的指针
cout << "test end:" << *test.end() <<endl;

cout << "test front:" << test.front() <<endl;
cout << "test back:" << test.back() <<endl;

cout << "test &front:" << &test.front() <<endl;
cout << "test &back:" << &test.back() <<endl;

// 迭代器,此时i的类型为:vector<int>::iterator
for (auto i = test.begin(); i != test.end(); i++)
{
cout<< *i <<endl;
}

这里需要注意是的end()指向数组的最后一个地址+1

复制数组:

// 复制数组:
vector<int> test3;
test3.insert(test3.end(),test.begin(),test.end());
cout <<"test3.size:" << test3.size() <<endl;

// 或者:
vector<int> test4(test);
cout <<"test4.size:" << test4.size() <<endl;

交换数组:

// 交换数组:
vector<int> test2;
// swap(test2,test);
// 或者:
test2.swap(test);
cout <<"test2.size:" << test2.size() <<endl;

Array

array是在C++11时候增加的,相比数组更安全,但是效率不会更低。array加入了更多的操作功能,类似于vector,但是array大小是固定的,不可以动态增删,需要在初始化的时候设置大小。

初始化:

// 初始化:
array<int,5> array1;

array<int,5> array2{};

array<int,5> array3{0,1,2,3,4};


for (size_t i = 0; i < 5; i++)
{
cout << array1[i] << endl;
}

cout<<"-----------------"<<endl;

for (size_t i = 0; i < 5; i++)
{
cout << array2[i] << endl;
}

cout<<"-----------------"<<endl;

for (size_t i = 0; i < 5; i++)
{
cout << array3[i] << endl;
}

上面申明了三种初始化方式,看下其默认值,输出结果:

225317808
462
-1887955703
32758
1
-----------------
0
0
0
0
0
-----------------
0
1
2
3
4

array中的常用函数与vector相似,参考:http://c.biancheng.net/view/6688.html

常用操作:

int size = array2.size();
cout << "size:" << size << endl;

bool empty = array1.empty();
cout << "is empty:" << empty << endl;

交换复制:

cout << "---------数组交换--------" << endl;
// 数组交换
array2.swap(array3);
for (auto i : array2) {
cout << i << endl;
}

cout << "--------数组复制1---------" << endl;
// 数组复制
array1 = array2;
for (auto i : array1) {
cout << i << endl;
}

cout << "-------数组复制2----------" << endl;
// 或者:
array<int, 5> array4;
copy(array2.begin(),array2.end(),array4.begin());
for (auto i : array4) {
cout << i << endl;
}

数组的奇妙之旅

数组配合函数

作为函数参数:

// 指针指向数组
void function(int *p){

}

// 大小为10的数组
void function2(int p[10]){

}

// 未定义数组大小
void function3(int p[]){

}

作为函数返回值

c++中不能直接返回数组,可以利用指针代替:

int* function4(int size){
int *arr;
arr = new int[size];
for (size_t i = 0; i < size; i++)
{
arr[i] = i * 10;
}
return arr;
}


int main(){


int *p;
p = function4(10);

for (size_t i = 0; i < 10; i++)
{
cout<< p[i] <<endl;
}

system("pause");
return 0;
}

数组与指针

在C++中可以用指针代替数组名,指针指向的是数组第一个元素的地址,如下:

int arr[3] = {1,2,3};

int *p;
p = arr;
cout << "p0:" << p[0] << endl;
cout << "p1:" << p[1] << endl;
cout << "p2:" << p[2] << endl;
// 超出范围
cout << "p3:" << p[3] << endl;

指针p指向&arr[0],我们直接使用p[i]来访问数组第i个元素,但是需要注意是别超出数组的本身范围。

指针数组和数组指针

是不是有点头晕,啥玩意这是?

  • 数组指针:指向数组的指针
  • 指针数组:其对象都是指针的一个数组

数组指针:

int arr4[3] = {12,123,123324};

// 初始化一个数组指针
int (*cp)[3] = &arr4;
for (size_t i = 0; i < 3; i++)
{
cout<<"error usage "<<*cp[i] <<" success usage "<<(*cp)[i]<<endl;
}

输出结果:

error usage 12  success usage 12
error usage 1 success usage 123
error usage 0 success usage 123324

其看起来和上述的普通指针没什么区别,等在下多维数组中就可理解数组指针 存在的意义了。

指针数组:

这个也很好理解,数组中的所有元素都在指针。

方式一:

    // 指针数组:数组里面的每个原生都是指针
char *tp[3] = {"asd","as","f"};
for(auto i:tp){
cout<<"value:"<<i<<" address:"<<&i<<endl;
}

输出:
value:asd address:0x6fd53ffcf8
value:as address:0x6fd53ffcf8
value:f address:0x6fd53ffcf8

方式二:


// 无法通过上面方式初始化
int *ttp[3];

int arr4[3] = {12,123,123324};
for (size_t i = 0; i < 3; i++)
{
ttp[i] = &arr4[i];
cout<<"address:"<<ttp[i] << " value:"<<*ttp[i] << endl;
}

输出:
address:0x6fd53ffd38 value:12
address:0x6fd53ffd3c value:123
address:0x6fd53ffd40 value:123324

多维数组和多级指针

我们上面讲的都是一维数组,还有多维数组,比较常见的就是二维数组。

初始化:

int test[3][4];
int array[3][4] = {
{1,2,3},
{123,123,234},
{12313,123123,123123}
};

我们看下array[0]是什么样的

cout << "array[0]:" << array[0] << endl;

输出:
array[1]:0x3529fff9a0

其指向一个数组指针


还有多级指针,省略,不想写了

参考:https://www.cnblogs.com/chenyangyao/p/5222696.html