vector动态数组

本文深入讲解了STL模板库中的vector容器,包括其创建、常用函数及其功能,并通过实例演示了如何正确使用这些函数,如resize(), swap(), push_back()等。

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

vector是STL模板库中的序列式容器,利用它可以有效地避免空间的浪费。
创建vector容器
vector< int >v;vector< char >;vector< int >v[10]。
vector常用函数及功能
c.clear() 清空容器中所有元素
c.empty() 判断容器是否为空
c.pop_back() 删除容器最后一个元素
c.push_back() 在尾部加入一个元素
c.resize() 重新指定容器的长度
c.reserve() 保留适当的容量
c1.swap(c2) 交换c1和c2的值
swap(c1,c2) 同上
使用vector容器注意
vector<int>v,v相当于一个一维数组,长度不定,需注意如果当前数组v的长度为n,不可像普通数组一样写成v[n]=x,这样做是毫无意义的,但是如果在n以内,可以直接写做v[m]=x (m < n)。
在这里我要特别说一下resize()函数,先看下面的代码和输出

// resizing vector
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  vector<int> myvector;

  // set some initial content:
  for (int i=1;i<10;i++) myvector.push_back(i);

  myvector.resize(5);
  myvector.resize(8,100);
  myvector.resize(12);

  cout << "myvector contains:";
  for (int i=0;i<myvector.size();i++)
    cout << ' ' << myvector[i];
  cout << '\n';

  return 0;
} 

Output:
myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0

从这里可以很明显的看出,如果利用resize()函数减少容器的长度,很简单直接把想要保留的长度作为参数传给它,如果增加长度x,执行c.resize(n+x,a),那么新增加部分的数组的值为a,但是如果不传第二个参数给它,就会默认为0。
其他函数我就在代码中为大家展示它的功能。测试代码如下

#include<iostream>
#include<vector> 
using namespace std;
int main()
{
    vector<int>p;
    for(int i=0;i<10;i++)
    p.push_back(i);

    swap(p[2],p[1]);
    for(int i=0;i<p.size();i++)
    cout<<p[i]<<" ";
    cout<<endl;

    p.resize(7);
    for(int i=0;i<p.size();i++)
    cout<<p[i]<<" ";
    cout<<endl;

    while(!p.empty())
    {
        p.pop_back();
    }
    p.clear();
    cout<<p.size()<<endl;

    return 0;
} 

如有不当之处欢迎指出!!

动态数组在C语言中是一种非常重要的数据结构,它允许在运行时动态地分配和调整内存大小。这种灵活性使得动态数组能够有效地管理不确定数量的数据集合。在C语言中,动态数组的实现通常依赖于指针和标准库函数如`malloc`、`realloc`以及`free`来完成内存的分配、调整和释放。 ### 动态数组的基本结构 为了实现一个动态数组(通常称为`cvector`),首先需要定义一个结构体来保存动态数组的相关信息,例如当前大小、容量以及指向实际数据存储的指针。下面是一个简单的`Vector`结构体定义: ```c typedef int ElementType; // 可以根据需求更改元素类型 typedef struct Vector { ElementType *data; // 指向数据的指针 int size; // 当前元素数量 int capacity; // 当前容量 } Vector; ``` ### 创建和销毁动态数组 创建动态数组时,需要为其分配初始内存空间。通常我们会设定一个初始容量,当数组满载时再进行扩容操作。销毁动态数组时,则需要释放之前分配的所有内存资源。 ```c // 创建一个动态数组 Vector* create_vector(int initial_capacity) { Vector *v = (Vector*)malloc(sizeof(Vector)); if (v == NULL) { // 分配失败处理 return NULL; } v->data = (ElementType*)malloc(initial_capacity * sizeof(ElementType)); if (v->data == NULL) { free(v); return NULL; } v->size = 0; v->capacity = initial_capacity; return v; } // 销毁一个动态数组,释放内存 void destory_vector(Vector *v) { if (v != NULL) { free(v->data); free(v); } } ``` ### 添加元素 向动态数组中添加元素是常见操作之一。当向数组末尾添加元素时,如果当前容量不足以容纳新元素,则需要对数组进行扩容。扩容通常是通过`realloc`函数实现的,该函数可以调整已分配内存块的大小[^3]。 ```c // 向动态数组末尾添加一个元素 void vector_push_back(Vector *v, ElementType val) { if (v == NULL) { // Vector不能是NULL return; } if (v->size == v->capacity) { // 容量不足,扩容 v->capacity *= 2; // 扩容策略,这里简单地将容量翻倍 ElementType *new_data = (ElementType*)realloc(v->data, v->capacity * sizeof(ElementType)); if (new_data != NULL) { v->data = new_data; } else { // 处理分配失败的情况 return; } } v->data[v->size++] = val; } // 在动态数组最前面添加元素,所有元素依次后移 void vector_push_front(Vector *v, ElementType element) { if (v == NULL) { return; } if (v->size == v->capacity) { v->capacity *= 2; ElementType *new_data = (ElementType*)realloc(v->data, v->capacity * sizeof(ElementType)); if (new_data != NULL) { v->data = new_data; } else { return; } } for (int i = v->size; i > 0; --i) { v->data[i] = v->data[i - 1]; } v->data[0] = element; ++v->size; } // 将元素val添加到索引为idx的位置,idx后面的元素依次后移 void vector_insert(Vector *v, int idx, ElementType val) { if (v == NULL || idx < 0 || idx > v->size) { return; } if (v->size == v->capacity) { v->capacity *= 2; ElementType *new_data = (ElementType*)realloc(v->data, v->capacity * sizeof(ElementType)); if (new_data != NULL) { v->data = new_data; } else { return; } } for (int i = v->size; i > idx; --i) { v->data[i] = v->data[i - 1]; } v->data[idx] = val; ++v->size; } ``` ### 打印动态数组 遍历打印整个`Vector`动态数组可以帮助我们检查数组的内容是否正确。 ```c // 遍历打印整个Vector动态数组 void vector_print(Vector *v) { if (v == NULL) { return; } for (int i = 0; i < v->size; ++i) { printf("%d ", v->data[i]); } printf("\n"); } ``` ### 清空和析构操作 清空动态数组意味着移除所有元素,但保留其容量不变。而析构操作则是彻底释放动态数组占用的所有资源。 ```c // 清空数组 void vector_clear(Vector *v) { if (v == NULL || v->size == 0) { return; } memset(v->data, 0, v->size * sizeof(ElementType)); v->size = 0; } // 析构函数,释放动态分配的内存 void vector_free(Vector *v) { if (v != NULL) { free(v->data); free(v); } } ``` ### 宏定义简化构造函数调用 为了简化构造函数的调用,我们可以使用宏定义来隐藏一些细节,使代码更加简洁易读。 ```c // 简化构造函数的调用 #define VECTOR(type, name, capacity) Vector name; vector_init(&name, capacity, sizeof(type)) #define VECTOR_GET(type, name, index) *(type*)vector_get(&name, index) #define VECTOR_FRONT(type, name) *(type*)vector_front(&name) #define VECTOR_BACK(type, name) *(type*)vector_back(&name) ``` 以上就是C语言中实现动态数组的一些基本方法。这些函数提供了创建、销毁、添加、插入、打印、清空及析构等基础功能,为构建更复杂的应用打下了坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值