目的
有这么一个需求,就是绘制学生成绩的表格:
这一个表格就是二维表格,显示二维数据正合适,下面就用二维数组实现这一个表格数据的存储与打印。
二维数组是经常用到的东西,特别是表格处理时,表格与二维数组正好对应,使用起来方便。
还是推荐用vector,vector在C++中称为向量,其就是动态的数组。
过程
C++的传统的静态二维数组
1、什么是二维数组
在 C++ 中,二维数组是一种常用的数据结构,它可以看作是数组的数组,类似于数学中的矩阵。以下将从定义、初始化、访问元素、内存布局和使用示例等方面详细介绍 C++ 中的二维数组。
2、定义二维数组
二维数组的一般定义语法如下:
数据类型 数组名[行数][列数];
其中,数据类型 可以是任意有效的 C++ 数据类型,如 int、double、char 等;数组名是用户为数组取的名称;行数 和 列数 分别表示数组的行数和列数,它们必须是常量表达式。
示例:
int matrix[3][4]; // 定义一个3行4列的二维整数数组
3、初始化二维数组
二维数组可以在定义时进行初始化,常见的初始化方式有以下几种:
1.初始化
>int matrix[2][3] = {
> {1, 2, 3},
{4, 5, 6}
};
4、实现需求
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printArray(string array[][4], int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < 4; j++)
{
cout << array[i][j] <<",";
}
cout << std::endl;
}
cout << std::endl;
}
int main()
{
string array[3][4] = { {"学号:","1","姓名:","小明"},
{"语文:","81","数学:","89"},
{"英语:","91","物理:","71"}
};
printArray(array, 3);
}
运行情况:
原来习惯用C的传统数组,现在发现其实在太难用,作为参数时更时难用。
二维数组的参数,必须得指出列的大小,这点,用起来非常的不灵活,因此推荐下面的方法
C++的vector动态数组
1、什么是vector?
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单地认为,向量是一个能够存放任意类型的动态数组。
2、容器特性
1.顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
2.动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。提供了在序列末尾相对快速地添加/删除元素的操作。
3.能够感知内存分配器的(Allocator-aware)
容器使用一个内存分配器对象来动态地处理它的存储需求。
在使用它时, 需要包含头文件vector.
#include<vector>
1.1 向量声明和初始化
vector 型变量的声明以及初始化的形式也有许多, 常用的有以下几种形式:
/* 初始化vector对象的方法 */
vector<T> v1 ; //v1是一个空的vector,它潜在的元素是T类型的,执行默认初始化
vector<T> v2(v1) ; //v2中包含v1中所有元素的副本
vector<T> V2 = V1; //与上等价
vector<T> v3(n, val) ; //声明一个初始大小为10且初始值都为1的向量
vector<T> v4(n) ; //v4包含了n个重复地执行了值初始化的对象
vector<T> v5{a,b,c,...} //v5包含了初始值个数的元素,每个元素给赋予对应的初值
vector<T> v5 = {a,b,c,...} //与上等价
vector<T> v6(v5.begin(), v5.begin()+3) ; //将v5向量中从第0个到第2个(共3个)作为向量v6的初始值
如果vector的元素类型是int,默认初始化为0;如果vector元素类型为string,则默认初始化为空字符串。除此之外, 还可以直接使用数组来初始化向量,例如 :
vector<int> v1;
vector<father> v2;
vector<string> v3;
vector<vector<int> >; //注意空格。这里相当于二维数组int a[n][n];
vector<int> v5 = { 1,2,3,4,5 };//列表初始化,注意使用的是花括号
vector<string> v6 = { "hi","my","name","is","lee" };
vector<int> v7(5, -1); //初始化为-1,-1,-1,-1,-1。第一个参数是数目,第二个参数是要初始化的值
vector<string> v8(3, "hi");
vector<int> v9(10); //默认初始化为0
vector<int> v10(4); //默认初始化为空字符串
/* 直接使用数组来初始化向量 */
int n[] = {1, 2, 3, 4, 5} ;
vector<int> v11(n, n+5) ; //将数组n的前5个元素作为向量a的初值
vector<int> v11(&n[1], &n[4]) ;//将n[1] - n[4]范围内的元素作为向量v11的初值
3、实现需求
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printVecList(vector<vector<string>> &vecList)
{
for (int i = 0; i < vecList.size(); i++)
{
for (int j = 0; j < vecList[i].size(); j++)
{
cout << vecList[i][j] << ",";
}
cout << std::endl;
}
cout << std::endl;
}
int main()
{
vector<vector<string>> vecList = { {"学号:","1","姓名:","小明"},
{"语文:","81","数学:","89"},
{"英语:","91","物理:","71"}
};
printVecList(vecList);
}
运行结果:
总结
数组与vector的对比
1、内存中的位置 C++中数组为内置的数据类型,存放在栈中,其内存的分配和释放完全由系统自动完成;vector,存放在堆中,由STL库中程序负责内存的分配和释放,使用方便。
2、大小能否变化 数组的大小在初始化后就固定不变,而vector可以通过 push_back 或 pop 等操作进行变化。
3、用size获取长度 数组在定义时就确定了长度,不能用size获取长度;vector可以用size 获取长度。
4、初始化 数组不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值;而vector可以。
5、执行效率 数组>vector向量。主要原因是vector的扩容过程要消耗大量的时间。
本质上
静态数组与动态数组,本质是一样的:
就拿上面的举例,逻辑结构是一样的,就是一个二维表格,如下图所示,二维表格逻辑图:
而实际的物理存储是线性的,如图所示:
如果从代码上理解的话,这样理解也可以,就是一维数组的元素又是一维数组,这样就组成二维数组,这样理解vector时更为容易理解;因此,二维数组又可视为数组元素为一维数组的一维数组:
VS里显示的内存布局情况:
vs的布局也体现出来了,一维的数组元素的类型是一维数组,这样就组成了二维。