12C++STL之Vector

本文详细介绍了STL中的Vector容器,包括其基本操作如插入、删除、遍历,以及内存管理和自定义类型存储。特别讨论了Vector的动态内存调整、初始化、赋值操作、容量调整、元素访问以及算法应用。此外,还阐述了如何处理Vector中的指针存储,以确保正确释放内存,并手写了简单的Vector实现。最后,探讨了Vector在存储大量数据时的内存释放策略。
摘要由CSDN通过智能技术生成

STL之Vector

1.简介

STL 是一套标准模板库。

从广义上来说,容器算法迭代器、仿函数、适配器、空间适配器

容器和算法之间通过迭代器进行无缝连接

STL几乎所有的代码都采用了模板类或者模板函数。

Vector使用上几乎等价于Java中list集合,但是二者在内部实现是完全不一样的。后面会分析。

2.Vector存放内置数据

迭代器:vector::iterator ;从某种意义上来说,迭代器就是指针

  • push_back( ) 成员函数在向量的末尾插入值,如果有必要会扩展向量的大小。
  • size( ) 函数显示向量的大小。
  • begin( ) 函数返回一个指向向量开头的迭代器。
  • end( ) 函数返回一个指向向量末尾的迭代器。
1.三种遍历方式
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void myPrint(int val)
{
    cout << val;
}

void test()
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    //第一种取数据
    vector<int>::iterator isBegin = vec.begin(); //迭代器第一个
    vector<int>::iterator isEnd = vec.end();     //指向容器中下一个位置
    while (isBegin != isEnd)
    {
        cout << *isBegin;
        isBegin++;
    }
    cout << endl;
    //第二种方式
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
    //第三种方式
    for_each(vec.begin(), vec.end(), myPrint);
    cout << endl;
}

int main(int argc, char const *argv[])
{
    test();
    system("pause");
    return 0;
}
2.存放自定义数据类型
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Person
{
public:
    string name;
    int age;
    Person(string name, int age);
    ~Person();
};
Person::Person(string name, int age)
{
    cout << "Person创建了"<< endl;
    this->name = name;
    this->age = age;
}
Person::~Person()
{
    cout << "Person析构了" << endl;
}

// void test()
// {
//     vector<Person> vec;
//     vec.push_back(Person("a", 10)); //Person("a", 10)为匿名对象,存入到vector中
//     vec.push_back(Person("B", 20));
//     vec.push_back(Person("C", 30));
//     vec.push_back(Person("D", 40));
//     for (vector<Person>::iterator it = vec.begin(); it != vec.end(); it++)
//     {
//         cout << it->name << it->age << endl;
//     }
// }

int main(int argc, char const *argv[])
{
    // test();
    vector<Person> vec;
    vec.push_back(Person("a", 10)); //Person("a", 10)为匿名对象,存入到vector中,匿名对象会发生析构
    vec.push_back(Person("B", 20));
    vec.push_back(Person("C", 30));
    vec.push_back(Person("D", 40));
    // Person p1("a", 10);
    // Person p2("b", 20);
    // Person p3("c", 30);
    // Person p4("d", 40);
    // vec.push_back(p1); //
    // vec.push_back(p2);
    // vec.push_back(p3);
    // vec.push_back(p4);
    for (vector<Person>::iterator it = vec.begin(); it != vec.end(); it++)
    {
        cout << it->name << it->age << endl;
    }
    // cout << p1.name << endl;
    system("pause");
    return 0;
}

Person创建了
Person析构了
Person创建了
Person析构了
Person析构了
Person创建了
Person析构了
Person析构了
Person析构了
Person创建了
Person析构了
a10
B20
C30
D40
请按任意键继续. . .

第二种:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Person
{
public:
    string name;
    int age;
    Person(string name, int age);
    ~Person();
};
Person::Person(string name, int age)
{
    cout << "Person创建了"<< endl;
    this->name = name;
    this->age = age;
}
Person::~Person()
{
    cout << "Person析构了" << endl;
}

// void test()
// {
//     vector<Person> vec;
//     vec.push_back(Person("a", 10)); //Person("a", 10)为匿名对象,存入到vector中
//     vec.push_back(Person("B", 20));
//     vec.push_back(Person("C", 30));
//     vec.push_back(Person("D", 40));
//     for (vector<Person>::iterator it = vec.begin(); it != vec.end(); it++)
//     {
//         cout << it->name << it->age << endl;
//     }
// }

int main(int argc, char const *argv[])
{
    // test();
    vector<Person> vec;
    // vec.push_back(Person("a", 10)); //Person("a", 10)为匿名对象,存入到vector中,匿名对象会发生析构
    // vec.push_back(Person("B", 20));
    // vec.push_back(Person("C", 30));
    // vec.push_back(Person("D", 40));
    Person p1("a", 10);
    Person p2("b", 20);
    Person p3("c", 30);
    Person p4("d", 40);
    vec.push_back(p1); //
    vec.push_back(p2);
    vec.push_back(p3);
    vec.push_back(p4);
    for (vector<Person>::iterator it = vec.begin(); it != vec.end(); it++)
    {
        cout << it->name << it->age << endl;
    }
    vec.clear();
    // cout << p1.name << endl;
    system("pause");
    return 0;
}

Person创建了
Person创建了
Person创建了
Person创建了
Person析构了
Person析构了
Person析构了
a10
b20
c30
d40
Person析构了
Person析构了
Person析构了
Person析构了
请按任意键继续. . .

vector存1放数据:会动态调整内存空间,所得到的存储空间总是大于等于所需存储空间。

3.vector 的初始化

    (1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
   (2)vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
   (3)vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
   (4)vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
   (5)int b[7]={1,2,3,4,5,9,8};
        vector<int> a(b,b+7); //从数组中获得初值
    (6)     vector<int>(vec); //匿名对象,匿名对象会被直接回收掉
#include <iostream>
#include <vector>
using namespace std;

void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> a(10); //10个0
    printVec(a);
    vector<int> b(10, 1);
    printVec(b);
    vector<int> c(b);
    printVec(c);
    vector<int> d(b.begin(), b.end());
    printVec(d);
    int e[7] = {1, 2, 3, 4, 5, 9, 8};
    vector<int> f(e, e + 7);
    printVec(f);

    vector<int> vec; //具有自动扩容的功能
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    system("pause");
    return 0;
}

4.vector赋值操作

  • vector& operator=(const vector &vec);//重载等号操作符
  • assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
  • assign(n, elem); //将n个elem拷贝赋值给本身。
#include <iostream>
#include <vector>
using namespace std;

void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> v1; //无参构造
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVec(v1);
    vector<int> v2;
	v2 = v1;//赋值操作,将v1的所有元素全拷贝给v2
	printVec(v2);

    vector<int>v3;
	v3.assign(v1.begin(), v1.end());//将[beg, end)区间中的数据拷贝赋值给本身。
	printVec(v3);

    vector<int>v4;
	v4.assign(10, 100); //10个100
	printVec(v4);
    system("pause");
    return 0;
}

6.vector基本操作符

1.判空 vec.empty();
    vector<int> vec;
    if (vec.empty())
    {
        cout << "vec为空" << endl;
    }
    else
    {
        cout << "vec不为空" << endl;
    }
2.大小 vec.size()
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    cout << vec.size() << endl;
3.插入数据 insert
  • 1.a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5

  • 2.a.insert(a.begin()+1,3,5);//在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5

#include <iostream>
#include <vector>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    vec.insert(vec.begin() + 1, 2);//第二位插入2
    printVec(vec);
    vec.insert(vec.begin() + 1, 3, 5); //从第二位插入3个555
    printVec(vec);
    system("pause");
    return 0;
}
4.删除元素 vec.erase
#include <iostream>
#include <vector>
using namespace std;

void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}
int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);//0 1 2 3 4 
    }
    vec.erase(vec.begin() + 1, vec.begin() + 3);//删除a中第2个,到第三个,不包含第三个
    printVec(vec);
    system("pause");
    return 0;
}
5.调整空间resize
  • 1.a.resize(10)将a的现有元素个数调至10个,多则删,少则补0
  • 2.a.resize(10,2);将a的现有元素个数调至10个,多则删,少则补2

注意:resize并不能缩减a.capacity();vector实际占用的内存大小。

#include <iostream>
#include <vector>
using namespace std;

void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}
int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i); //0 1 2 3 4
    }
    vec.resize(2); //少则删除
    printVec(vec);
    vec.resize(10); //多则补0
    printVec(vec);

    vector<int> vec2;
    for (int i = 0; i < 5; i++)
    {
        vec2.push_back(i); //0 1 2 3 4
    }
    vec2.resize(20, 2);//多则补2
    printVec(vec2);
    system("pause");
    return 0;
}
6.容量的实际大小capacity
  • size:表示地是vector元素的个数
  • capacity:vector实际内存可以容纳元素的个数,capacity>=size;

为什么capacity很多时候会比实际的size大,这样做优点?

答:与java中list集合一样,避免多次扩容,影响到性能,扩容是很耗性能的。

#include <iostream>
#include <vector>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10000; i++)
    {
        vec.push_back(i);
    }
    cout << "size" << vec.size() << "capacity:" << vec.capacity() << endl;
    system("pause");
    return 0;
}

size10000capacity:16384
请按任意键继续. . .

7.清空元素clear
    vec.clear();
8.swap操作
  • a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换

1.交换数据

#include <iostream>
#include <vector>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}
int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i); //0 1 2 3 4
    }
    vector<int> vec2;
    vec2.push_back(9);
    vec2.swap(vec);
    printVec(vec);
    printVec(vec2);
    system("pause");
    return 0;
}

vec指针指向vec2,vec2指针指向vec。 进行了交换,但是还有功能,可以进行vector实际内存大小缩水操作。

2.实际大小capicity缩水

#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10000; i++)
    {
        vec.push_back(i);
    }
    vec.resize(10);
    cout << vec.capacity() << endl; //16348,实际vec的内存容纳个数
    vector<int>(vec).swap(vec);
    cout << vec.capacity() << endl; //10,收缩空间
    system("pause");
    return 0;
}

——————vector(vec).swap(vec);怎么做到的, 首先:vector(vec)会产生匿名对象,开辟内存空间(只有实际个数大小的空间),vec原来的指向这个空间,匿名的指向原来大的内存空间,这样现在vec就只会有实际个数大小的内存空间。至于匿名的,会被编译器自动回收掉

9.相等比较

a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    vector<int> vec2(vec);
    if (vec == vec2)
    {
        cout << "相等" << endl;
    }
    system("pause");
    return 0;
}

10.其他操作
  • 1.a.back();返回最后一个元素
  • 2.a.front();返回第一个元素
  • 3.a[i]/a.at(i); //返回a的第i个元素
  • 4.pop_back;///删除a向量的最后一个元素
#include <iostream>
#include <vector>
using namespace std;

void printVec(vector<int> &vec)
{
    for(int i =0; i< vec.size();i++)
    {
        cout << vec.at(i) << endl;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    vector<int> vec2(vec);
    if (vec == vec2)
    {
        cout << "相等" << endl;
    }
    printVec(vec2);
    system("pause");
    return 0;
}

7.重要的算法algorithm

1.排序

sort(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}
int main(int argc, char const *argv[])
{
    vector<int> vec;
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(1);
    vec.push_back(4);
    vec.push_back(5);
    sort(vec.begin(), vec.end());
    printVec(vec);
    system("pause");
    return 0;
}
2.元素反转排序

reverse(a.begin(),a.end()); //反转排序

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(4);
    vec.push_back(5);
    reverse(vec.begin(), vec.end());
    printVec(vec);
    system("pause");
    return 0;
}
3.copy复制

copy(a.begin(),a.end(),b.begin()+1); //把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开 始复制,覆盖掉原有元素

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(4);
    vec.push_back(5);

    vector<int> vec2;
    vec2.push_back(6);
    vec2.push_back(7);
    vec2.push_back(8);
    copy(vec.begin(), vec.end(), vec2.begin()+1);//vec2没有扩容,这个个人觉得尽量少使用
    printVec(vec2);
    system("pause");
    return 0;
}

结果:612 ,vec2没有扩容,这个个人觉得尽量少使用, vec没有完全复制

4.查找

find(a.begin(),a.end(),10); //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 5; i++)
    {
        vec.push_back(i);
    }
    if (find(vec.begin(), vec.end(), 4) != vec.end())
    {
        int position = find(vec.begin(), vec.end(), 4) - vec.begin();
        cout << position << endl;
    }
    system("pause");
    return 0;
}

8.vector手动释放内存探讨

  • 1.直接声明的vector容器是一个普通变量,相当于一个未知大小的动态数组,不需要手动释放,超出作用于范围时会自动回收
  • 2.如果是*vec = new vector<>( )这种方法动态创建的vector,则需要delete vector;

第一种,普通变量,数据量超大时,我们执行clear

#include <iostream>
#include <vector>
using namespace std;
void printVec(vector<int> &vec)
{
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10000; i++)
    {
        vec.push_back(i);
    }
    cout << "size" << vec.size() << "capacity:" << vec.capacity() << endl;
    vec.clear();
    cout << vec.capacity() << endl;//实际内存空间大小并没有归0
    system("pause");
    return 0;
}

size10000capacity:16384
16384
请按任意键继续. . .

可以发现: vec.clear();执行clear之后,并没有立即就释放内存空间,这么大的一块内存空间,还是被占用了,极其不好,所以还是需要回收的。

1.方式1

vec.shrink_to_fit();//释放内存,缩水到实际数量大小

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10000; i++)
    {
        vec.push_back(i);
    }
    cout << "size" << vec.size() << "capacity:" << vec.capacity() << endl;
    vec.clear();//仅仅clear还不够
    vec.shrink_to_fit();//释放内存
    cout << vec.capacity() << endl;//实际内存空间大小并没有归0
    system("pause");
    return 0;
}

size10000capacity:16384
0
请按任意键继续. . .

2.方式2 swap

匿名的vector

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10000; i++)
    {
        vec.push_back(i);
    }
    vector<int>().swap(vec);
    cout << vec.capacity() << endl;
    system("pause");
    return 0;
}

9.vector存储指针

vector存放指针,则需要手动去释放内存,因为,vector释放内存时,vector内部元素指针指向的对象并不会销毁,堆中数据需要手动释放内存。

#include <iostream>
#include <vector>
using namespace std;
class Person
{
public:
    string name;
    int age;
    Person(string name, int age);
    ~Person();
};
Person::Person(string name, int age)
{
    cout << "Person创建了" << endl;
    this->name = name;
    this->age = age;
}
Person::~Person()
{
    cout << "Person析构了" << endl;
}
void printerVec(vector<Person *> &vec)
{
    for (vector<Person *>::iterator it = vec.begin(); it < vec.end(); it++)
    {
        cout << (*it)->name << (*it)->age << endl;
    }
}
void releasePointer(vector<Person *> &vec)
{
    for (vector<Person *>::iterator it = vec.begin(); it < vec.end(); it++)
    {
        if ((*it) != nullptr)
        {
            delete (*it);
            (*it) = nullptr;
        }
    }
}

int main(int argc, char const *argv[])
{
    vector<Person *> vec;
    Person *p1 = new Person("zhangsan", 10);
    Person *p2 = new Person("lisi", 20);
    Person *p3 = new Person("wangwu", 30);
    vec.push_back(p1);
    vec.push_back(p2);
    vec.push_back(p3);
    printerVec(vec);

    //清空并释放空间
    releasePointer(vec);
    vec.clear();
    vec.shrink_to_fit();
    cout << vec.capacity() << endl;
    system("pause");
    return 0;
}

10.手写一个Vector

#include <iostream>
#include <cmath>
using namespace std;

class OutOfException : public exception
{
};

class Array
{
public:
    int size;
    int maxsize; //capicity,动态扩容
public:
    int *arr;

public:
    Array(int maxSize);
    ~Array();
    int &operator[](int i) const; //取数据
    void push_back(int value);
    void remove(int location);
};

Array::Array(int maxSize)
{
    this->size = 0;
    this->maxsize = maxSize;
    arr = new int[maxSize];
}

Array::~Array()
{
    if (this->arr != nullptr)
    {
        delete[] arr;
        arr = nullptr;
    }
}

int &Array::operator[](int i) const
{
    if (i > size - 1)
    {
        return this->arr[0]; // 抛出异常
    }
    else
    {
        return this->arr[i];
    }
}

void Array::push_back(int value)
{
    if (size >= maxsize)
    {
        //扩容
        int newMaxSize = ceil(maxsize + maxsize / 2);
        int *newArr = new int[newMaxSize];
        for (size_t i = 0; i < size; i++)
        {
            newArr[i] = arr[i]; //拷贝数据
        }
        delete[] arr;
        arr = nullptr;
        arr = newArr; //地址重新指向newArr
        maxsize = newMaxSize;
    }
    arr[size++] = value;
}

void Array::remove(int location)
{
    if (location > size - 1)
    {
        //抛出异常
    }
    else
    {
        for (size_t i = location; i < size - 1; i++)
        {
            arr[i] = arr[i + 1];
            // arr[i] = arr[i++];
            // *(arr + i) = *(arr +(++i));
        }
        size--;
    }
}

void printArray(Array &arr, int size)
{

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

int main(int argc, char const *argv[])
{
    Array arr(2);
    arr.push_back(1);
    arr.push_back(2);
    arr.push_back(3);
    arr.push_back(4);
    arr.push_back(5);
    arr.push_back(6);
    printArray(arr, arr.size);

    arr.remove(2);
    printArray(arr, arr.size);

    cout << "获取值" << arr[0] << endl;
    system("pause");
    return 0;
}
    {
        newArr[i] = arr[i]; //拷贝数据
    }
    delete[] arr;
    arr = nullptr;
    arr = newArr; //地址重新指向newArr
    maxsize = newMaxSize;
}
arr[size++] = value;

}

void Array::remove(int location)
{
if (location > size - 1)
{
//抛出异常
}
else
{
for (size_t i = location; i < size - 1; i++)
{
arr[i] = arr[i + 1];
// arr[i] = arr[i++];
// *(arr + i) = *(arr +(++i));
}
size–;
}
}

void printArray(Array &arr, int size)
{

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

}

int main(int argc, char const *argv[])
{
Array arr(2);
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
arr.push_back(5);
arr.push_back(6);
printArray(arr, arr.size);

arr.remove(2);
printArray(arr, arr.size);

cout << "获取值" << arr[0] << endl;
system("pause");
return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值