c++的vector用法
文章目录
- 1. 创建和初始化 `std::vector`
- 2. 添加和删除元素
- 3. 访问和遍历元素
- 4. `std::vector` 的其他常用操作
std::vector 是 C++ 标准库中的一个动态数组容器,提供了灵活的存储和访问功能。
1. 创建和初始化 std::vector
#include <iostream>
#include <vector>int main() {// 创建一个空的 vectorstd::vector<int> v1;// 使用初始值创建 vectorstd::vector<int> v2 = {1, 2, 3, 4, 5};// 创建一个指定大小的 vector,所有元素初始化为 0std::vector<int> v3(5); // v3 中有 5 个元素,初始值为 0// 创建一个指定大小的 vector,并用特定值初始化所有元素std::vector<int> v4(5, 10); // v4 中有 5 个元素,所有元素的值为 10// 输出 vector 的内容std::cout << "v2: ";for (int num : v2) {std::cout << num << " ";}std::cout << std::endl;std::cout << "v3: ";for (int num : v3) {std::cout << num << " ";}std::cout << std::endl;std::cout << "v4: ";for (int num : v4) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
// 使用初始值创建 vector
std::vector<int> v2 = {1, 2, 3, 4, 5};// 输出 vector 的内容
std::cout << "v2: ";
for (int num : v2) {std::cout << num << " ";
}
std::cout << std::endl;
- 创建
vector
std::vector<int> v2 = {1, 2, 3, 4, 5};
-
步骤:
- 这里使用了
std::vector,它是一个动态数组,可以存储多个同类型的数据。 v2被初始化为一个包含五个整数(1, 2, 3, 4, 5)的vector。
- 这里使用了
-
调用过程:
- C++ 的标准库中
std::vector构造函数被调用,传入一个初始化列表{1, 2, 3, 4, 5} v2现在拥有五个元素,分别是 1, 2, 3, 4, 5。
- C++ 的标准库中
- 输出
vector的内容
2.1 输出头部信息
std::cout << "v2: ";
-
步骤:
std::cout是标准输出流,用于将信息输出到控制台。"v2: "是一个字符串,表示要输出的内容。
-
调用过程:
- 调用
std::cout的operator<<函数,传递字符串"v2: " - 字符串被输出到控制台。
- 调用
2.2 遍历 vector 并输出元素
for (int num : v2) {std::cout << num << " ";
}
-
步骤:
for (int num : v2)是范围-based 循环,遍历v2中的每个元素。num是循环变量,代表当前遍历到的元素。
-
调用过程:
- 编译器生成隐式的迭代器来遍历
v2的元素。 - 对于
v2中的每一个元素,执行std::cout << num << " ";:num被赋值为当前的元素值(例如第一次循环时是 1,第二次是 2,以此类推)。- 调用
std::cout的operator<<函数,将num的值输出到控制台。 - 再次调用
std::cout的operator<<函数,将一个空格" "输出到控制台。
- 编译器生成隐式的迭代器来遍历
-
执行的顺序:
- 第一次循环:
num= 1,输出1(后面有个空格)。 - 第二次循环:
num= 2,输出2(后面有个空格)。 - 第三次循环:
num= 3,输出3(后面有个空格)。 - 第四次循环:
num= 4,输出4(后面有个空格)。 - 第五次循环:
num= 5,输出5(后面有个空格)。
- 第一次循环:
- 输出换行
std::cout << std::endl;
-
步骤:
std::endl是一个操控符,表示输出一个换行符并刷新输出流。
-
调用过程:
- 调用
std::cout的operator<<函数,传递std::endl。 std::endl将换行符插入到输出流中,并调用flush方法,确保所有输出立即显示在控制台。
- 调用
总结
- 创建
vector:初始化v2为一个包含 1, 2, 3, 4, 5 的动态数组。 - 输出内容:
- 输出字符串
"v2: "。 - 遍历
v2中的每个元素,依次输出每个元素及其后面一个空格。
- 输出字符串
- 换行:最后输出一个换行符。
最终,控制台将显示如下内容:
v2: 1 2 3 4 5
2. 添加和删除元素
#include <iostream>
#include <vector>int main() {std::vector<int> v = {1, 2, 3};// 在末尾添加元素v.push_back(4);v.push_back(5);// 删除末尾元素v.pop_back();// 在指定位置插入元素v.insert(v.begin() + 1, 10); // 在索引 1 的位置插入 10// 删除指定位置的元素v.erase(v.begin() + 2); // 删除索引 2 位置的元素// 输出 vector 的内容std::cout << "v: ";for (int num : v) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
#include <iostream>
- 含义:包含输入输出流库,以便使用
std::cout进行输出。 - 执行过程:预处理器指令,将
iostream头文件的内容插入到当前文件中,以提供输入输出功能。
#include <vector>
- 含义:包含
std::vector容器的定义,以便使用vector类。 - 执行过程:预处理器指令,将
vector头文件的内容插入到当前文件中,以提供动态数组功能。
int main() {
- 含义:程序的入口点,主函数的定义。
- 执行过程:程序开始执行从
main函数开始的代码。
std::vector<int> v = {1, 2, 3};
- 含义:创建一个名为
v的std::vector<int>对象,并初始化为包含元素 1, 2, 3 的vector。 - 执行过程:
- 调用
std::vector<int>的构造函数,传入初始化列表{1, 2, 3}。 v现在包含三个整数元素:1, 2, 3。
- 调用
v.push_back(4);
- 含义:在
vector的末尾添加一个新元素 4。 - 执行过程:
- 调用
std::vector<int>的push_back方法,传入整数 4。 4被添加到v的末尾,v现在包含元素:1, 2, 3, 4。
- 调用
v.push_back(5);
- 含义:在
vector的末尾添加一个新元素 5。 - 执行过程:
- 调用
std::vector<int>的push_back方法,传入整数 5。 5被添加到v的末尾,v现在包含元素:1, 2, 3, 4, 5。
- 调用
v.pop_back();
- 含义:删除
vector末尾的一个元素。 - 执行过程:
- 调用
std::vector<int>的pop_back方法。 - 删除
v末尾的元素 5,v现在包含元素:1, 2, 3, 4。
- 调用
8. v.insert(v.begin() + 1, 10);起到中间添加元素的作用
- 含义:在
vector的指定位置(索引 1)插入新元素 10。 - 执行过程:
- 调用
std::vector<int>的insert方法。 v.begin()返回一个指向v第一个元素的迭代器。v.begin() + 1表示第二个位置的迭代器。- 插入元素 10 到索引 1 位置,
v现在包含元素:1, 10, 2, 3, 4。
- 调用
9. v.erase(v.begin() + 2);中间删除元素的作用
- 含义:删除
vector中指定位置(索引 2)的元素。 - 执行过程:
- 调用
std::vector<int>的erase方法。 v.begin() + 2表示第三个位置的迭代器。- 删除元素 2,
v现在包含元素:1, 10, 3, 4。
- 调用
std::cout << "v: ";
- 含义:输出字符串
"v: "到控制台。 - 执行过程:
- 调用
std::cout的operator<<函数,传递字符串"v: "。 - 字符串被输出到控制台。
- 调用
for (int num : v) { std::cout << num << " "; }
- 含义:遍历
vector中的每个元素,并将其输出到控制台。 - 执行过程:
for (int num : v)是一个范围-based 循环,遍历v中的每个元素。- 对于每个元素,
num被赋值为当前元素值。 - 调用
std::cout的operator<<函数,将num输出到控制台,再输出一个空格" "。 - 遍历
v中的所有元素,依次输出 1, 10, 3, 4。
std::cout << std::endl;
- 含义:输出一个换行符,并刷新输出流。
- 执行过程:
- 调用
std::cout的operator<<函数,传递std::endl。 std::endl输出换行符,并调用flush方法,确保所有输出立即显示在控制台。
- 调用
return 0;
- 含义:结束
main函数,返回 0 表示程序成功执行。 - 执行过程:
- 返回 0 给操作系统,表示程序正常结束。
总结
- 初始化
vector:创建并初始化v为{1, 2, 3}。 - 修改
vector:- 添加元素 4 和 5。
- 删除末尾的元素 5。
- 在索引 1 插入元素 10。
- 删除索引 2 位置的元素 2。
- 输出
vector内容:打印v中的每个元素,输出1 10 3 4。
最终,控制台将显示如下内容:
v: 1 10 3 4
3. 访问和遍历元素
#include <iostream>
#include <vector>int main() {std::vector<int> v = {1, 2, 3, 4, 5};// 使用索引访问元素std::cout << "Element at index 2: " << v[2] << std::endl;// 使用 at() 方法访问元素std::cout << "Element at index 3: " << v.at(3) << std::endl;// 使用迭代器遍历元素std::cout << "v elements: ";for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用范围-based for 循环遍历元素std::cout << "v elements (range-based): ";for (int num : v) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
- 包含头文件
#include <iostream>
#include <vector>
- 含义:引入标准输入输出流和向量容器的头文件,以便在程序中使用相应的类和函数。
- 创建并初始化
vector
std::vector<int> v = {1, 2, 3, 4, 5};
- 含义:创建一个
vector容器v,并初始化为包含 1, 2, 3, 4, 5 这几个整数元素。
- 使用索引和 at() 访问元素
std::cout << "Element at index 2: " << v[2] << std::endl;
std::cout << "Element at index 3: " << v.at(3) << std::endl;
- 含义:分别使用索引和
at()方法访问vector中的元素。 - 执行过程:
v[2]返回索引为 2 的元素,即第三个元素。v.at(3)返回索引为 3 的元素,即第四个元素。
- 注意:
at()方法会进行边界检查,当访问越界时会抛出std::out_of_range异常。
- 使用迭代器遍历元素
std::cout << "v elements: ";
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {std::cout << *it << " ";
}
std::cout << std::endl;
- 含义:使用迭代器遍历
vector容器中的元素。 - 执行过程:
v.begin()返回指向容器起始位置的迭代器。v.end()返回指向容器末尾位置的迭代器。- 在循环中,通过
*it访问迭代器指向的元素。
在使用迭代器遍历元素时,通过 *it 访问迭代器指向的元素,本质上是通过指针来进行访问的。
具体来说:
-
迭代器本质上是一个指针,指向容器中的某个元素。
-
当我们使用
v.begin()和v.end()获取迭代器时,实际上得到的是指向容器第一个元素和最后一个元素后面的位置的指针。 -
在遍历过程中,通过
++it来移动迭代器,实际上是在移动指针,让它指向下一个元素。 -
当我们使用
*it访问迭代器指向的元素时,实际上是通过解引用指针来获取该元素的值。
所以,使用迭代器遍历元素的本质就是通过指针来访问容器中的元素。迭代器提供了一种更加安全和易用的方式来遍历容器,但其底层实现确实是基于指针的访问机制。
- 使用范围-based for 循环遍历元素
std::cout << "v elements (range-based): ";
for (int num : v) {std::cout << num << " ";
}
std::cout << std::endl;
- 含义:使用范围-based for 循环遍历
vector容器中的元素。 - 执行过程:对于容器
v中的每个元素,将其值赋给num,然后输出到控制台。
- 总结
这段代码展示了如何使用向量容器(vector)存储整数元素,并演示了如何通过索引、at() 方法、迭代器和范围-based for 循环访问和遍历向量的元素。
4. std::vector 的其他常用操作
下面是对你提供的 C++ 代码逐行解释,并附上每一行的输出结果:
#include <iostream> // 包含输入输出流库
#include <vector> // 包含向量库int main() {std::vector<int> v = {1, 2, 3, 4, 5}; // 创建一个整数向量 v,初始值为 1, 2, 3, 4, 5// 获取 vector 的大小std::cout << "Size of v: " << v.size() << std::endl;// 输出结果: Size of v: 5// 解释: v.size() 返回向量 v 的当前大小,即其中元素的个数。此时,v 包含 5 个元素。// 获取 vector 的容量std::cout << "Capacity of v: " << v.capacity() << std::endl;// 输出结果: Capacity of v: 5// 解释: v.capacity() 返回向量 v 的当前容量,即 v 能够容纳的元素的最大个数而不需要重新分配内存。初始时,它的容量等于大小。// 重新调整 vector 的大小v.resize(7, 100); // 将 vector 调整为 7 个元素,新增的元素初始化为 100// 清空 vectorv.clear(); // 清空 v 中的所有元素std::cout << "Size of v after clear: " << v.size() << std::endl;// 输出结果: Size of v after clear: 0// 解释: v.clear() 会移除向量中的所有元素,v.size() 返回清空后的大小,即 0。return 0;
}
逐行解释
-
#include <iostream>- 含义: 包含输入输出流库,以便使用
std::cout和std::endl
- 含义: 包含输入输出流库,以便使用
-
#include <vector>- 含义: 包含
std::vector类的定义,以便使用std::vector容器。 - 效果: 使得程序可以使用
std::vector类型来管理动态数组。
- 含义: 包含
-
int main()- 含义:
main函数是程序的入口点。所有 C++ 程序都从main函数开始执行。 - 效果: 程序从这里开始运行。
- 含义:
-
std::vector<int> v = {1, 2, 3, 4, 5};- 含义: 创建一个
std::vector<int>类型的变量v,并初始化为{1, 2, 3, 4, 5}。 - 效果:
v是一个包含 5 个整数的向量,元素依次是 1, 2, 3, 4, 5。
- 含义: 创建一个
-
std::cout << "Size of v: " << v.size() << std::endl;- 含义: 输出向量
v的大小。v.size()返回向量的元素个数。 - 输出结果:
Size of v: 5 - 解释: 向量
v目前包含 5 个元素,所以大小为 5。
- 含义: 输出向量
-
std::cout << "Capacity of v: " << v.capacity() << std::endl;- 含义: 输出向量
v的容量。v.capacity()返回向量可以容纳的最大元素个数而不需要重新分配内存 - 输出结果:
Capacity of v: 5 - 解释: 向量的初始容量与其大小相等,即 5。容量可能会根据实现和分配策略有所不同,但在这里,大小和容量相同。
- 含义: 输出向量
-
v.resize(7, 100);- 含义: 调整向量
v的大小为 7。如果新的大小大于当前大小,则用100初始化新增的元素。 - 效果: 向量
v的大小变为 7,原有的元素保持不变,新增的元素值为 100。 - 解释: 向量的内容变为
{1, 2, 3, 4, 5, 100, 100}。
- 含义: 调整向量
-
v.clear();- 含义: 清空向量
v中的所有元素。 - 效果: 向量
v的所有元素被移除,大小变为 0。 - 解释: 向量被清空,所有元素都被删除,但容量 (
capacity) 可能不变。
- 含义: 清空向量
-
std::cout << "Size of v after clear: " << v.size() << std::endl;- 含义: 输出向量
v在清空后的大小。 - 输出结果:
Size of v after clear: 0 - 解释: 清空后,向量
v不再包含任何元素,所以大小为 0。
- 含义: 输出向量
总结
v.size(): 返回向量的当前大小,即元素个数。v.capacity(): 返回向量的容量,即能容纳的最大元素个数而无需重新分配内存。v.resize(new_size, value): 调整向量的大小至new_size。如果新大小大于当前大小,新增元素会初始化为value。v.clear(): 移除向量中的所有元素,清空向量,但容量可能保持不变。
相关文章:
c++的vector用法
文章目录 1. 创建和初始化 std::vector2. 添加和删除元素3. 访问和遍历元素4. std::vector 的其他常用操作 std::vector 是 C 标准库中的一个动态数组容器,提供了灵活的存储和访问功能。 1. 创建和初始化 std::vector #include <iostream> #include <vect…...
【Linux网络】Linux网络初探:开启网络世界的大门
W...Y的主页 😊 代码仓库分享💕 前言:我们已经系统的学习了Linux的基本操作、进程、线程、文件、通信等待,但是在如今社会没有网络通信方式是万万不行的,今天我们就走进网络中,系统的学习一下有关Linux网…...
目录、用户与组、出错相关函数、时间函数
一、目录相关函数及属性 1、 opendir()函数 opendir 用于打开一个目录,并返回一个目录流指针。name:要打开的目录的路径。 返回值:成功时返回指向目录流的指针,失败时返回 NULL。 #include <dirent.h> DIR *opendir(con…...
<keep-alive> 一分钟了解
<keep-alive> 一分钟了解 <keep-alive> 是 Vue.js 提供的一个抽象组件,它的主要用途是在页面或组件切换时保留其状态,避免重复执行昂贵的渲染操作,从而提升应用性能。 文章目录 <keep-alive> 一分钟了解 一、 <keep-ali…...
Android 启动动画太生硬
跟 android:launchMode"singleTask"属性无关系 请禁用路由 ARouter.getInstance() .build(Routes.Main.MAIN) .withTransition(R.anim.activity_anim_in, R.anim.activity_anim_out).navigation() 正确做法是 val intent Intent(thisSplashActivity,MainActivit…...
深度学习中常用概念总结
最近在做深度学习,里面涉及到很多概念,有的名称都差不多容易记混。所以写这篇文章总结一下。眼过千遍不如手过一遍。 1. 轮数(Epochs): 一轮(Epoch)指的是整个训练数据集在训练过程中被完整使用一次。…...
进 程
1.进程:进行中的程序。 微观串行,宏观并行。 程序的一次执行过程 进程是程序的一个实例 一个程序可以对应一个或多个进程。 2.为什么需要进程? 3.进程的组成部分: 进程 pcb 块 栈|堆|bss|data|text 其中: 家族…...
Taro-UI
一、安装Taro UI 进入项目文件,执行项目 //使用yarn安装taro-ui yarn add taro-ui//使用npm安装taro-ui npm install taro-ui//注:因为要支持自定义主题功能,需要将样式从组件中抽离出来,在微信小程序中依赖 globalClass 功能&a…...
TypeScript 之 JavaScript文件类型检查
启用对 JavaScript 文件的类型检查 在 TypeScript 编译选项 compilerOptions 全部配置项 中,可以通过以下2个属性配置 JavaScript Support: allowJs 是否允许编译 JavaScript 文件。默认值是 false。在默认情况下,TypeScript 编译器只处理 .…...
基本数据类型变量间的自动提升与强制转换以及进制的转换
基本数据类型变量间的自动提升与强制转换 测试基本数据类型的运算规则 这里基本类型不包括布尔 运算规则 自动类型提升 当容量小的变量与容量大的变量做运算时,结果自动转换容量大的数据类型 说明:此时容量大小,指的是数据范围大小&…...
SparseConv 的学习笔记
安装 环境设置在74.183 sdfstudio 里面,SparseNeus 推荐的版本是是 torchsparse 2.0.0版本 命令行如下: 需要 C 的 sudo 权限指定安装: ## 安装依赖项 conda install -c conda-forge sparsehash sudo apt-get install libsparsehash-dev 进入官网下…...
vscode 快速生成vue 格式
1.用快捷Ctrl Shift P唤出控制台 输入“Snippets”并选择 Snippets: Configure User Snippets 2.输入vue,选中vue.json vs code自动生成vue.json文件 3.在 vue.json 中添加模板 {"Print to console": {"prefix": "vue2","b…...
react笔记:redux
redux状态管理 安装redux:num i redux 新建redux文件夹: store.jscount_reducer.js count_action.js constant.js (常量) 1. store.js文件: // 该文件专门用于暴露一个store对象,整个应用只有一个store对…...
数据结构与算法--图的应用
文章目录 回顾提要连通图生成树最小生成树构造最小生成树的算法普里姆(Prim)算法克鲁斯卡尔(Kruskal)算法 最短路径狄杰斯特拉 (Dijkstra) 算法当前最短路径的更新拓扑排序拓扑排序方法拓扑排序示例总结 回顾 图的遍历方法: 深度优先遍历 (DFS):从任意…...
【leetcode图文详解】特殊数组II : 空间换时间的“记忆化”,越多越好吗?
题目详解 需求:判断给定区间内的元素是否满足“特殊数组”要求 尝试: 暴力求解? 如果试着直接对每个queries中的区间进行检测而不做其他处理,那么最后不出意外地超时了。。 细想优化策略,不难察觉到其中可能存在大量的重复运算 那还等什…...
离线安装prometheus与Grafana实现可视化监控
简介 prometheus 是一个专为云环境设计的开源系统监控和警报工具,它收集并存储多维度的时间序列数据,通过PromQL查询语言提供强大的数据检索能力,并支持可视化及警报功能。而 Grafana 则是一个开源的数据可视化平台,能够与包括Pr…...
【Python学习-UI界面】PyQt5 小部件7-QSpinBox 计数器
样式如下: 一个 QSpinBox 对象向用户呈现一个文本框,右侧有一个上下按钮,显示一个整数。如果按下上下按钮,文本框中的值将增加/减少。 默认情况下,框中的整数从0开始,最高到99,并以步长1变化。对于浮点数…...
[二次元]个人主页搭建
文章目录 域名买一个免费的 框架HexoHexo-Theme-ParticleX Halo 参考 域名 买一个 有钱人玩这个 免费的 github.io 教程在github官方文档有; 框架 Hexo 静态的 Hexo-Theme-ParticleX Argvchsの小窝 Halo 动态的 halo 参考 基于Hexo框架的GitHub个人主页…...
Spring Data JPA 自动创建时间的相关注解和用法
以Springboot项目为例 在实体类上加上注解 EntityListeners(AuditingEntityListener.class)在相应的字段上添加对应的时间注解 LastModifiedDate 和 CreatedDateApplication启动类中添加注解 EnableJpaAuditing...
Java基础之隐式类型转换
类型转换 基本数据类型表示范围大小排序: 在变量赋值及算术运算的过程中,经常会用到数据类型转换,其分为两类: 隐式类型转换 显式类型转换 1 隐式类型转换 情形1:赋值过程中,小数据类型值或变量可以直…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
