C++ STL中一些既是成员函数又是算法函数

C++ STL算法与成员函数深度解析 本文详细解读了C++标准模板库(STL)中一系列算法和成员函数的用途、参数和操作。从基本的集合运算如排序、差集构造,到高级算法如堆操作和数值计算,内容涵盖了STL提供的丰富工具集。文章旨在为读者提供STL算法的实用指导,帮助开发者更高效地利用STL优化代码。 阅读详情

在C++的标准模板库(STL)中,有一些函数既可以作为容器的成员函数,又有其对应的算法函数版本。这些函数在设计上非常巧妙,允许开发者在不同的场景下灵活使用它们。通常,我们将这些函数分别称为“成员函数版本”和“非成员函数版本”或“算法版本”。

这种设计不仅使得代码更具可读性和可维护性,还增强了STL的通用性和适应性。在本文中,我们将深入探讨这些函数的具体应用场景,并分析它们在C++编程中的重要性。

 常见的双重身份函数

在C++标准模板库(STL)中,有一些函数既可以作为某些容器的成员函数,又可以作为独立的算法函数,以下是几个常用的函数的详细讲解: 

1. empty()

 成员函数:几乎所有标准容器(如`vector`、`list`、`map`等)都有一个`empty()`成员函数,用于检查容器是否为空。

std::vector<int> vec;
if (vec.empty()) {
    // 容器为空
}

算法函数:C++17引入了全局算法`std::empty`,它不仅可以用于标准容器,还可以用于数组和其他支持`empty()`成员函数的自定义容器。

int arr[5];
bool is_empty = std::empty(arr); // 返回false,因为数组有元素
if (std::empty(arr)) {
    // 判断容器是否为空
}

2. size()

成员函数:大多数标准容器都有一个`size()`成员函数,用于返回容器中元素的数量。

std::vector<int> vec = {1, 2, 3};
auto size = vec.size();  // size == 3

算法函数:C++17引入了全局算法`std::size`,它可以用于标准容器、数组和其他支持`size()`成员函数的容器。

auto size = std::size(vec);  // size == 3
int arr[] = {1, 2, 3, 4};
auto size = std::size(arr); // 返回4

3.data()

成员函数:如`vector`、`string`等容器提供`data()`成员函数,用于返回指向容器内部数据的指针。

std::vector<int> vec = {1, 2, 3};
int* p = vec.data();

算法函数:C++17引入了全局算法`std::data`,可以用于标准容器、数组或其他支持`data()`成员函数的对象。

int arr[] = {1, 2, 3, 4};
int* data_ptr = std::data(arr); // 返回指向arr的指针

4. begin() 和 end()

成员函数:

  • 定义:begin()和end()成员函数分别返回指向容器起始和末尾的迭代器。
  • 应用容器:这些函数几乎在所有STL容器中都存在,例如std::vector, std::list, std::deque, std::set, std::map等。
std::vector<int> vec = {1, 2, 3};
auto it_begin = vec.begin();
auto it_end = vec.end();

算法函数:

  • 定义:std::begin和std::end是泛型算法函数,能够返回适用于任何类型(包括C数组)的迭代器。
  • 适用场景:不仅适用于STL容器,还可以用于原生数组或其他实现了begin和end的容器。
auto it_begin = std::begin(vec);
auto it_end = std::end(vec);
int arr[] = {1, 2, 3, 4};
auto it_begin = std::begin(arr); // 指向arr的第一个元素
auto it_end = std::end(arr); // 指向arr的末尾元素之后的位置

5. swap()

成员函数:大多数标准容器(如`vector`、`deque`、`map`等)都提供`swap()`成员函数,用于交换两个同类型容器的内容。

std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
vec1.swap(vec2);  // 交换vec1和vec2的内容

算法函数:STL提供了全局算法`std::swap`,用于交换两个同类型对象的内容。这个函数不仅可以交换容器的内容,还可以交换普通变量。

std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
std::swap(vec1, vec2);

特殊情况

std::list是一个特殊的序列容器,是一个双向链表,不支持随机访问迭代器。它为某些操作提供了专门的成员函数版本(如sort(), reverse(), remove())。这些成员函数版本针对链表结构进行了优化,通常比通用算法版本更高效。

1. reverse()

成员函数:STL中的容器类并没有直接提供reverse()作为成员函数,但std::list容器是个例外。std::list有一个reverse()成员函数,它可以直接反转链表中的元素顺序。

std::list<int> lst = {3, 1, 2};
lst.reverse();  // 现在lst为{1, 2, 3}

算法函数:STL提供了一个全局算法std::reverse,可以用于任何支持随机访问迭代器或双向迭代器的容器(如vector、deque等),来反转容器中的元素顺序。

std::vector<int> vec = {3, 1, 2};
std::reverse(vec.begin(), vec.end());  // 现在vec为{1, 2, 3}

区别:

  • 成员函数版本可能对特定容器(如list)有优化。
  • 算法版本更通用,可用于任何双向迭代器。

 2. sort()

成员函数:标准容器如vector、deque、list等,并没有sort()成员函数。这意味着不能通过调用容器的成员函数来对元素进行排序。不过,需要特别注意的是,std::list容器是个例外,它提供了sort()成员函数,因为std::list是一个双向链表,无法使用随机访问迭代器。

std::list<int> lst = {3, 1, 2};
lst.sort();  // 现在lst为{1, 2, 3}

算法函数:STL提供全局算法`std::sort`,用于对支持随机访问迭代器的容器(如`vector`、`deque`等)进行排序。

std::vector<int> vec = {3, 1, 2};
std::sort(vec.begin(), vec.end());  // 现在vec为{1, 2, 3}

区别:

  • 成员函数版本针对链表结构优化,不需要随机访问迭代器。
  • 算法版本更通用,但要求随机访问迭代器。对于大多数容器(如vector)通常更高效。

3.remove()

 remove 主要作为算法函数存在,而不是普遍的容器成员函数。某些特定容器如 std::list 提供了成员函数 remove,实现实际的删除操作。

算法函数:std::remove 是一个泛型算法,它从指定范围中移除与给定值相等的所有元素,并将这些元素移动到范围的末尾。需要注意的是,它并不实际从容器中删除元素,而是将不需要的元素覆盖掉,并返回一个新的尾迭代器,指向新的“逻辑末尾”。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 2, 4, 5, 2};
    
    auto new_end = std::remove(vec.begin(), vec.end(), 2);
    
    // 输出去除 2 之后的内容,但实际容器大小没有改变
    for (auto it = vec.begin(); it != new_end; ++it) {
        std::cout << *it << " ";  // 输出: 1 3 4 5
    }
    std::cout << std::endl;
    
    // 如果需要实际删除这些元素,需要调用 vec.erase(new_end, vec.end());
    vec.erase(new_end, vec.end());
    
    // 此时容器的大小变小,元素也被删除了
    for (int v : vec) {
        std::cout << v << " ";  // 输出: 1 3 4 5
    }
    std::cout << std::endl;
    
    return 0;
}

成员函数:标准容器(如 vector、list、deque 等)并没有提供 remove 作为成员函数。相反,某些容器如 std::list 提供了一个名为 remove 的成员函数,它的作用与 std::remove 类似,但会实际删除元素。

#include <iostream>
#include <list>

int main() {
    std::list<int> lst = {1, 2, 3, 2, 4, 5, 2};
    
    lst.remove(2);  // 实际删除所有等于 2 的元素
    
    for (int v : lst) {
        std::cout << v << " ";  // 输出: 1 3 4 5
    }
    std::cout << std::endl;
    
    return 0;
}

 区别:

  • 成员函数版本直接修改容器,移除元素并调整大小。
  • 算法版本不会改变容器大小,需要额外的erase()调用。

小结

这些函数在C++ STL中的存在形式为程序员提供了更大的灵活性。根据需求,可以选择使用成员函数或全局算法函数。

  • 成员函数版本:成员函数则直接与容器的实现关联(通常限于特定的容器),适用于具体容器操作,代码简洁性要求高的情况,或者当你需要利用容器的特定功能时。
  • 算法函数版本:全局算法函数通常更通用,支持更多类型的容器或数据结构,适用于需要通用性、灵活性以及跨容器类型操作的场景。

不同容器中的成员函数和算法函数

在使用时,一般来说,如果容器有对应的成员函数,优先使用成员函数版本,因为它们通常针对特定容器进行了优化。如果需要更通用的解决方案,或者处理的不是整个容器而是一个范围,那么使用算法函数版本可能更合适。

find函数 

成员函数版本

适用容器:find 成员函数只存在于关联容器(如 std::set, std::map, std::multiset, std::multimap)中。

std::set<int> s = {1, 2, 3, 4, 5};
auto it = s.find(3);
if (it != s.end()) {
    std::cout << "Found: " << *it << std::endl;
} else {
    std::cout << "Not found" << std::endl;
}

算法函数版本

适用容器:std::find 是一个通用算法,可以用于任何支持迭代器的容器。

std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
    std::cout << "Found: " << *it << std::endl;
} else {
    std::cout << "Not found" << std::endl;
}

 区别:

  • 成员函数版本只能用于关联容器,但通常更高效(O(log n)复杂度)。
  • 算法版本可用于任何容器,但对于非关联容器是线性搜索(O(n)复杂度)。

count函数

成员函数版本

适用容器:count 成员函数只存在于关联容器中,如 std::set, std::map, std::multiset, std::multimap。

std::multiset<int> ms = {1, 2, 2, 3, 3, 3};
auto count = ms.count(3);
std::cout << "Count of 3: " << count << std::endl;  // 输出: 3

算法函数版本

适用容器:std::count 是一个通用算法,可以用于任何支持迭代器的容器。

#include <iostream>
#include <vector>
#include <algorithm> // 包含 std::count

int main() {
    std::vector<int> vec = {1, 2, 3, 2, 4, 2, 5};

    // 计算 vector 中值为 2 的元素个数
    int count_of_twos = std::count(vec.begin(), vec.end(), 2);

    std::cout << "Number of 2s in the vector: " << count_of_twos << std::endl;

    return 0;
}

 比较和使用建议

  1. 效率:

    • 关联容器:对于关联容器,成员函数版本的 find 和 count 通常比算法版本更高效,因为它们能够利用容器的内部结构(如平衡二叉树)来实现对数时间复杂度的查找。
    • 其他容器:对于如 std::vector、std::deque 等容器,算法函数版本的 find 和 count 是唯一的选择,因为这些容器不提供相应的成员函数。
  2. 灵活性:

    • 算法函数版本:算法函数版本更通用,可以应用于任何支持迭代器的容器或范围。它们使得代码可以在不同容器类型之间更容易复用。
    • 成员函数版本:成员函数版本与特定容器类型紧密耦合,语法上可能更简洁,但不具备算法函数的通用性。
  3. 使用建议:

    • 对于关联容器(如 std::set, std::map),优先使用成员函数版本,因为它们更高效。
    • 对于非关联容器(如 std::vector, std::deque),使用算法函数版本,因为这些容器没有相应的成员函数。
    • 在编写通用代码时,使用算法函数版本可以提高代码的通用性和适应性。

总结 

在C++标准模板库(STL)中,许多函数既可以作为容器的成员函数使用,也可以通过对应的算法函数来实现。这种设计为开发者提供了极大的灵活性,使得代码不仅更具可读性和可维护性,也增强了STL的通用性和适应性。以下是对这些双重身份函数的总结:

  1. 成员函数版本与算法函数版本的灵活性:成员函数版本通常与特定容器的内部实现密切相关,因此在某些情况下(如std::list的reverse()和sort())能提供更高效的操作。另一方面,算法函数版本更加通用,可以应用于支持迭代器的各种容器,不受具体容器类型的限制。

  2. 常见的双重身份函数:如empty()、size()、data()、begin()、end()、swap()等,这些函数既有成员函数形式,也有全局算法函数形式。成员函数通常在特定容器中更高效,而算法函数则适用于更多的场景。

  3. 特定容器的优化:对于std::list这样的容器,它们提供了一些成员函数(如sort()、reverse()、remove()),这些函数经过优化,能够更有效地处理链表结构。对于其他容器,则可以使用通用的算法函数版本来实现类似的功能。

  4. 关联容器的特殊情况:在关联容器(如std::set、std::map)中,成员函数版本的find()和count()由于能够利用容器的内部结构,通常比算法函数版本更高效。在其他容器中(如std::vector、std::deque),则只能使用算法函数版本来进行查找和计数。

  5. 使用建议:对于特定容器,如关联容器,优先选择成员函数版本以获得更好的性能。在编写通用代码时,使用算法函数版本可以提高代码的适应性和可重用性。在需要针对特定容器进行优化时,成员函数版本往往是更好的选择。

综上所述,了解并灵活运用这些函数的双重身份,可以帮助开发者在C++编程中编写更高效、更易维护的代码。

掌握STL:算法与容器成员函数的精要 本文详细介绍了C++标准模板库(STL)中的算法和容器成员函数。通过附录F中的图表,我们能够快速理解STL所提供的丰富功能,包括非变异序列操作、变异序列操作、排序及相关操作等。这些工具对于高效编程至关重要,能帮助开发者提升代码的可读性、效率和模块化。 阅读详情

相关推荐

掌握C++ STL:容器、算法与迭代器的综合运用

本文详细介绍了C++标准模板库(STL)的核心概念,包括容器、适配器、算法和迭代器。通过表格形式列出了常用成员函数及其用途,讨论了栈、队列和优先队列的创建及其特性,并通过实例演示了如何使用STL算法对数组进行排序和搜索。文章还探讨了不同类型的迭代器以及STL在实际应用中可能遇到的问题和解决方案。

weixin_28933797的博客 416

STL 中类vector的成员函数

STL 中类vector的成员函数 向量是最简单的STL容器,其数据结构与数组相似,占据着一块连续的内存块。由于内存位置是连续的,所以向量中的元素可以随机访问,访问向量中任何一个元素的时间也是固定的。存储空间的管理是自动的,当将一个元素插入到已满的向量时,会为向量分配一个更大的内存块,将向量中的元素复制进新的内存块,然后释放旧的内存块。所以,向量是一个灵活的数组,能够动态改变自身大小。 表1-1...

Jacky的博客 751

提供一个微信投票刷票的js代码

最近几天,有个朋友找我去写一个脚本帮他 在微信上刷票、微信投票刷票,我大概看了一下,本次微信投票刷票其实就是根据微信的openid来限制,每个openid只能投三次票的限制。上图可以看出,其实只要openid,和toopenid即可,openid是自己的微信id,toopenid是投票对象的微信id,那我们定时修改openid即可给某一个人刷投票。把这段代码复制到浏览器F12之后的console里,直接回车即可开始微信投票刷票(刷新或关闭浏览器即可停止刷票)//生成随机的ip地址。

qq_858865388专业提供快速微信投票教程攻略和方法的博客 2万+

C++STL容器——string类(2)——成员函数详解

C++——String类的简单函数介绍

weixin_69283129的博客 1145

Proteus+汇编+8086电子时钟实战:从框架搭建到中断驱动的核心实现

本文详细介绍了使用Proteus仿真软件和8086汇编语言实现电子时钟的完整过程。从程序框架搭建、内存分段模型理解,到核心的8259中断控制器配置与编程,再到中断服务程序编写和数码管动态扫描显示驱动,系统阐述了底层软硬件协同开发的核心原理与实战步骤。该项目是深入理解计算机中断机制和汇编语言编程的绝佳实践。

weixin_29189381的博客 413

非球面检测

摘要:非球面镜检测主要采用干涉法,包括零位补偿和非零位补偿两种方式。零位补偿通过透镜组完全校正像差,精度达1%波长,但设计复杂成本高;非零位补偿利用部分像差补偿降低波前斜率,适用于规则非球面。折射-衍射混合补偿镜能同时校正多种像差。实际检测中可采用物理补偿镜或动态CGH加载方案,光路设计需运用坐标断点和多重结构技术实现复杂光路建模。不同方法各具优势,需根据检测需求选择合适方案。

Zhaxibamao的博客 2106

STL vector成员函数详解

一、 常用简单成员函数 vector::push_back(Type val) //将val添加到向量尾部 vector::pop_back() //将最后一个元素删除 iterator vector::begin() //返回指向第一个元素的迭代器 iterator vector::end() //返回指向最后一个元素之后的迭代器 vector::clear() //删除向量,并没有释放vector,还是占有capacity个空间,如果要释放空间,可使用 swap(vector<_Ty>()

qq_38843532的博客 3016

dify upload存在SSRF漏洞

Dify 是一个用于构建 AI 应用程序的开源平台。

nnn2188185的博客 1479

STL函数大全

目录 一、数组-vector 1.vertor的访问 2.vector的初始化 3.函数 二、栈-stack 三、链表-list 1.初始化 2.函数 四、队列-queue 1.初始化 2.基本操作 3.priority_queue的初始化 4. priority_queue操作与链队列一致。 五、集合-set 1.初始化 2.基本操作 六、映射-map 1.初始化 2.操作函数 一、数组-vector vector是数组的一种类表示,它提供了自动内存管理.

weixin_61907955的博客 4863

Transformers 实战修炼与源码剖析专栏大纲

本专栏以 Hugging Face Transformers 为主线,围绕“能用、会调、敢上线、懂源码”四个目标展开。内容不把理论堆成公式墙,而是用真实或拟真的业务场景驱动:客服分类、合同抽取、知识库问答、模型微调、推理服务、监控告警、源码扩展等。采用“业务痛点 → 三人剧本对话 → 代码实战 → 总结思考”的四段式结构,让读者在动手完成一个个小项目的过程中,逐步理解 Tokenizer、Model、Pipeline、Trainer、Generation、PEFT、Accelerate、Serving等概念

davidwang456的专栏 922

MATLAB算法实战应用案例精讲-【数模应用】装箱问题

装箱问题可以根据不同的维度进行分类。以下是一些常见的装箱问题二维装箱问题:二维装箱问题假设所有物品都是平面上的矩形,并且需要将它们放入平面上的容器中。这个问题的目标是找到一种装箱方案,使得物品不重叠并占据的总面积最小。三维装箱问题:三维装箱问题考虑到物品可以具有高度,并且需要将它们放入三维容器(如箱子或货柜)中。目标是找到一种装箱方案,使得物品不重叠且总体积最小。多维装箱问题:多维装箱问题是指在更高维度空间中进行装箱的问题。除了长度和宽度之外,物品可能具有其他属性,如高度、重量、形状等。

qq_36130719的博客 1572

STL容器的常用成员函数

一、vector&deque (唯二支持随机访问的容器) 1.插入: v.push_back(5); v.insert(it,5); //在制指定位置插入 v.insert(p,n,t);//在p迭代器位置插入n个t v.insert(p,b,e);//在p迭代器位置插入b迭代器和e迭代器之间的元素 dq.push_front(); 2.删除 v.pop_back(); v.eras...

truzby的博客 726

网红商品数据抓取:基于Python的高效爬虫实战

本篇博客介绍了从爬取到存储、分析和可视化网红商品数据的完整流程。通过Python的强大生态,我们能够轻松完成复杂的数据抓取任务。在实际应用中,还可以将此爬虫与机器学习模型结合,进一步挖掘数据价值。

2201_76125261的博客 1476

C++ STL list 成员函数 sort算法分析

最近在读《STL源码剖析》,颇有收获。当看到list结构的排序方法sort时,发现侯捷先生点到为止,说采用的是快速排序,也没有继续说明。我心存疑虑,怎么看这个代码都不像快排。 template template void list::sort(_StrictWeakOrdering __comp){  // Do nothing if the list has length 0 or 1

煮石 4727

【专栏必读】王道考研408计算机组成原理万字笔记使用说明及章节导航

本文是为准备408王道计算机组成原理考试的学生精心整理的万字笔记,涵盖了从计算机系统概述、数据表示和运算到存储系统、指令系统等多个章节的重点内容。本文强调了学习笔记的重要性,并分享了学习建议,如按视频课逻辑记录,建立学科框架。笔记详细记录了每章的关键知识点,包括存储器、CPU、I/O系统的工作原理,还附带了习题和思维导图,旨在帮助考生高效复习。

快乐江湖的博客 9万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++ stl 通用算法和成员函数使用

在stl中既有通用函数,又有相同成员函数主要表现在list中。 以remove为例 list coll; // insert elements from 6 to 1 and 1 to 6 for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); }

寧靜致遠 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

配合STL算法编写类的成员函数

配合STL算法编写类的成员函数 我们在使用C++的开发工作中,经常会编写许许多多的类,当然也会编写大量的成员函数。但是对于如何设计类的结构,如何确定类的成员,这将会是一个艰难的抉择过程。在编写C++类的过程中,我们都希望是我们的成员函数集合最小化,但是常常很难做到这一点。本文就来详细的讨论一下这个问题!在游戏开发中有一个单元类: class Unit{public:

2409

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Effective STL第5条:容器之(区间成员函数优先于与之对应的单元素成员函数)

一、案例引入 问题:如果有v1、v2两个矢量(vector形式的),现在要使v1的内容和v2的后半部分相同,那么你会使用什么方法? 解决方法 如果你的答案是调用assign方法(如下所示),那么你的答案是高效的 vector<int> v1; vector<int> v2; v1.clear(); //将v1容器的元素替换为v2指定迭代器区间的元素 v1.assi...

董哥的黑板报 1232

简单的程序诠释C++ STL算法系列之十五:swap

相信大家看到swap这个词都一定不会感到陌生,甚至会有这样想法:这不就是简单的元素交换嘛。的确,swap交换函数是仅次于Hello word这样老得不能老的词,然而,泛型算法东风,这个小小的玩意儿却在C++ STL中散发着无穷的魅力。本文不仅详细地阐述STL泛型算法swap,并借助泛型算法这股东风,展现STL容器中swap成员函数的神奇魅力。注意哦,泛型算法swap和容器中的swap成员函数,这是

坚持是世界上每个有所建树的人共有的品质! 577

STL容器常用函数和算法总结表格

公共成员函数功能size()返回容器中元素的个数empty()判断容器是否为空clear()清空容器insert()向容器中插入元素erase()删除容器中指定位置或指定元素的元素find()在容器中查找指定元素begin()返回指向容器首元素的迭代器end()返回指向容器尾元素的迭代器rbegin()返回指向容器尾元素的反向迭代器rend()返回指向容器首元素的反向迭代器容器类型非公共成员函数功能vectorcapacity()返回当前容量。

hyisoe的博客 551

C++STL---静态数组array

std::array是C++11引入的固定大小数组容器,封装了C风格数组并提供了STL接口。它保留了栈上分配、连续内存布局的优点,同时解决了原生数组容易退化为指针、不支持迭代器等问题。std::array支持随机访问、STL算法、值语义和成员函数操作,具有零额外开销且类型安全。其大小在编译期确定,不可动态调整,适用于需要固定大小、性能敏感的场景。与std::vector相比,std::array更轻量但不支持动态扩容,是与C API交互时的理想选择。

MzKyle的博客 1607

[C++]在程序中高效实用STL

在程序中使用STL1. 算法调用优先于手写循环使用算法的有如下理由: 效率:算法通常比手写循环效率更高 正确性:自己写循环容易出错 可维护性:使用算法比手写循环更加易懂。 在效率上来说,例如,在以下代码中,手写循环在每一次循环中都要计算vec.end(), 但在算法调用中只计算了一次vec.end()。因为在循环进行过程中,vec.end()并没有发生改变。 for (vector<int>:

stary_yan的博客 2085
上一篇: C++职工管理系统
下一篇: C++中的字符和字符串
py_cpp_java_c
博客等级 码龄3年 125粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值