对于动,静态数组使用的一些小思考

对于动,静态数组使用的一些小思考

Zephyr

这次C++练手项目是一个通讯录管理系统,跟着以上B站视频教程(P72-P83)进行开发。
但是,这一次练习解答和我大作业的解答格外相似,但是我用的是vector数组,我立马拿去和上一次大作业的对比,
这引发了我思考——vector动态数组静态数组到底该如何做选择?
通过这次练习,这个问题得到解答。
如果想查看之前大作业的代码,可以翻阅之前发布的博客文章。

以下是代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#include "iostream"
using namespace std;
#define MAX 1000

bool flag = false;
char ch;

struct Person{
string m_Name;
string m_Gender;
int m_Age{};
string m_Phone;
string m_Address;
};

struct AddressBook {
Person personArray[MAX];
int currentSize{};
};

void menu() {
cout << "************************************" << endl;
cout << "* 1. add a new contact " << endl;
cout << "* 2. search contact " << endl;
cout << "* 3. show all contacts " << endl;
cout << "* 4. delete a contact " << endl;
cout << "* 5. modify a contact " << endl;
cout << "* 6. clean the contact " << endl;
cout << "* 0. exit " << endl;
cout << "************************************" << endl;
}

void addPerson(AddressBook *abs){
system("cls");
if (abs->currentSize == MAX) {
cout << "通讯录已满,无法继续添加!" << endl;
return;
}else{
string name;
cout << "姓名:";
cin >> name;
//添加判断,判断输入的姓名是否和数组里所储存的姓名重复
while (true){
//每次输入新的姓名之前都要重置 flag.
//ps:我卡在这很久,想不到输入重复的名字后还得重置 flag,最后还是靠chatGPT才解决的 看来控制流程还得好好学习 :(
flag = false;
for (int i = 0; i < abs->currentSize; ++i) {
if (abs->personArray[i].m_Name == name){
flag = true;
cout << "姓名重复,请重新输入:";
cin >> name;
break;
}
}if(!flag) {
abs->personArray[abs->currentSize].m_Name = name;
break;
}
}
string gender;
cout << "性别:";
cin >> gender;
while (true){
if (gender == "男" || gender == "女") { //性别输入约束
abs->personArray[abs->currentSize].m_Gender = gender;
break;
}else {
cout << "输入错误,请重新输入性别:" ;
cin >> gender;
}
}
int age;
cout << "年龄:";
cin >> age;
while(true){
if (age > 0 && age < 125) { //年龄区间约束
abs->personArray[abs->currentSize].m_Age = age;
break;
}else{
cout << "年龄输入区间过于离谱,请重新输入年龄:" ;
cin >> age;
}
}
string phone;
cout << "电话号码:";
cin >> phone;
abs->personArray[abs->currentSize].m_Phone = phone;
string Address;
cout << "地址:";
cin >> Address;
abs->personArray[abs->currentSize].m_Address = Address;
abs->currentSize++;
system("cls");
cout << "添加成功!" << endl;
}
}

void search( AddressBook *abs){
string name;
system("cls");
cout << "请输入要查询的联系人的姓名:";
cin >> name;
for (int i = 0; i < abs->currentSize; ++i) {
if (abs->currentSize == 0){
cout << "当前通讯录记录为空!" << endl;
}else{
if (abs->personArray[i].m_Name == name){
cout << "姓名:" << abs->personArray[i].m_Name << "\t";
cout << "性别:" << abs->personArray[i].m_Gender << "\t";
cout << "年龄:" << abs->personArray[i].m_Age << "\t";
cout << "电话号码:" << abs->personArray[i].m_Phone << "\t";
cout << "地址:" << abs->personArray[i].m_Address << endl;
system("pause");
system("cls");
break;
}else cout << "未找到该联系人!" << endl;
}
}
}

void showAll(AddressBook *abs) {
if (abs->currentSize == 0){
cout << "当前通讯录记录为空!" << endl;
}else{
for (int i = 0; i < abs->currentSize; ++i) {
cout << "姓名:" << abs->personArray[i].m_Name << "\t";
cout << "性别:" << abs->personArray[i].m_Gender << "\t";
cout << "年龄:" << abs->personArray[i].m_Age << "\t";
cout << "电话号码:" << abs->personArray[i].m_Phone << "\t";
cout << "地址:" << abs->personArray[i].m_Address << endl;
}
}
system("pause");
system("cls");
}

void deletePerson(AddressBook *abs){
string name;
system("cls");
cout << "要删除的姓名:";
cin >> name;
for(int i = 0; i < abs->currentSize; i++){
if(abs->personArray[i].m_Name == name){
flag = true;
cout << "确认删除?(y/n)";
cin >> ch;
if(ch == 'y' || ch == 'Y'){
for(int j = i; j < abs->currentSize; j++){
abs->personArray[j] = abs->personArray[j+1]; //顺序表删除操作
}
abs->currentSize--;
cout << "删除成功!" << endl;
}else cout << "已取消删除!" << endl;
}
if (!flag) cout << "未找到此人!" << endl;
}
}

void modifyPerson(AddressBook *abs){
string name;
int selection;
system("cls");
cout << "输入要修改的联系人信息的姓名:";
cin >> name;
for (int i = 0; i < abs->currentSize; ++i) {
if (name == abs->personArray[i].m_Name) {
flag = true; //原本课程里需要重新逐一输入信息,比较麻烦,所以这里添加修改选项
cout << "-----------------------------------------------" << endl;
cout << " 1.姓名 2.电话号码 " << endl;
cout << " 3.性别 4.年龄 " << endl;
cout << " 5.地址 0.返回 " << endl;
cout << " 请输入相应编号做相应修改。 " << endl;
cout << "-----------------------------------------------" << endl;
cin >> selection;
switch (selection) {
case 1: {cout << "新的姓名信息:"; cin >> abs->personArray[i].m_Name; cout << "修改成功" << endl; break;}
case 2: {cout << "新的电话号码信息:"; cin >> abs->personArray[i].m_Phone; cout << "修改成功" << endl; break;}
case 3: {cout << "新的性别信息:"; cin >> abs->personArray[i].m_Gender; cout << "修改成功" << endl; break;}
case 4: {cout << "新的年龄信息:"; cin >> abs->personArray[i].m_Age; cout << "修改成功" << endl; break;}
case 5: {cout << "新的地址信息:"; cin >> abs->personArray[i].m_Address; cout << "修改成功" << endl; break;}
case 0: system("cls"); return;
default:cout << "输入错误!" << endl; break;
}
}
}if (!flag) cout << "查无此人!" << endl;
}

void cleanAll(AddressBook *abs) {
cout << "确认全部清除?(y/n)";
cin >> ch;
if(ch == 'y' || ch == 'Y'){
for (int i = 0; i < abs->currentSize; ++i) {
abs->personArray[i].m_Name.clear();
abs->personArray[i].m_Gender.clear();
abs->personArray[i].m_Age = 0;
abs->personArray[i].m_Phone.clear();
abs->personArray[i].m_Address.clear();
abs->currentSize = 0;
}
cout << "所有联系人信息均已消除!" << endl;
}else cout << "删除取消!" << endl;
}

int main()
{
AddressBook abs;
abs.currentSize = 0;
while(true){
menu();
int selection = 0;
cin >> selection;
switch (selection) {
case 1: addPerson(&abs);
break;
case 2: search(&abs);
break;
case 3: showAll(&abs);
break;
case 4: deletePerson(&abs);
break;
case 5: modifyPerson(&abs);
break;
case 6: cleanAll(&abs);
break;
case 0: cout << "Bye!" << endl; exit(0);
default: cout << "Input Error! Please input a valid number." << endl;
break;
}
}
}

下面是将静态数组换成vector动态数组的码子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#include "iostream"
#include "vector"
using namespace std;
#define MAX 1000

bool flag = false;
char ch;

struct Person{
string m_Name;
string m_Gender;
int m_Age{};
string m_Phone;
string m_Address;
};
vector<Person> persons;
void menu() {
cout << "************************************" << endl;
cout << "* 1. add a new contact " << endl;
cout << "* 2. search contact " << endl;
cout << "* 3. show all contacts " << endl;
cout << "* 4. delete a contact " << endl;
cout << "* 5. modify a contact " << endl;
cout << "* 6. clean the contact " << endl;
cout << "* 0. exit " << endl;
cout << "************************************" << endl;
}

void addPerson(){
Person person;
system("cls");
if (persons.size() == MAX) {
cout << "通讯录已满,无法继续添加!" << endl;
return;
}else{
string name;
cout << "姓名:";
cin >> name;
while (true){
flag = false;
for (int i = 0; i < persons.size(); ++i) {
if (person.m_Name == name){
flag = true;
cout << "姓名重复,请重新输入:";
cin >> name;
break;
}
}if(!flag) {
person.m_Name = name;
break;
}
}
string gender;
cout << "性别:";
cin >> gender;
while (true){
if (gender == "男" || gender == "女") {
person.m_Gender = gender;
break;
}else {
cout << "输入错误,请重新输入性别:" ;
cin >> gender;
}
}
int age;
cout << "年龄:";
cin >> age;
while(true){
if (age > 0 && age < 125) {
person.m_Age = age;
break;
}else{
cout << "年龄输入区间过于离谱,请重新输入年龄:" ;
cin >> age;
}
}
string phone;
cout << "电话号码:";
cin >> phone;
person.m_Phone = phone;
string Address;
cout << "地址:";
cin >> Address;
person.m_Address = Address;
persons.push_back(person);
system("cls");
cout << "添加成功!" << endl;
}
}

void search(){
string name;
system("cls");
cout << "请输入要查询的联系人的姓名:";
cin >> name;
for (const auto& person : persons) {
if (persons.empty()){
cout << "当前通讯录记录为空!" << endl;
}else{
if (person.m_Name == name){
cout << "姓名:" << person.m_Name << "\t";
cout << "性别:" << person.m_Gender << "\t";
cout << "年龄:" << person.m_Age << "\t";
cout << "电话号码:" << person.m_Phone << "\t";
cout << "地址:" << person.m_Address << endl;
system("pause");
system("cls");
break;
}else cout << "未找到该联系人!" << endl;
}
}
}

void showAll() {
if (persons.empty()){
cout << "当前通讯录记录为空!" << endl;
}else{
for (const auto& person : persons) {
cout << "姓名:" << person.m_Name << "\t";
cout << "性别:" << person.m_Gender << "\t";
cout << "年龄:" << person.m_Age << "\t";
cout << "电话号码:" << person.m_Phone << "\t";
cout << "地址:" << person.m_Address << endl;
}
}
system("pause");
system("cls");
}

void deletePerson(){
string name;
system("cls");
cout << "要删除的姓名:";
cin >> name;
for(int i = 0; i < persons.size(); i++){
if(persons[i].m_Name == name){
flag = true;
cout << "确认删除?(y/n)";
cin >> ch;
if(ch == 'y' || ch == 'Y'){
persons.erase(persons.begin() + i);
cout << "删除成功!" << endl;
}else cout << "已取消删除!" << endl;
}
if (!flag) cout << "未找到此人!" << endl;
}
}

void modifyPerson(){
string name;
int selection;
system("cls");
cout << "输入要修改的联系人信息的姓名:";
cin >> name;
for (auto &person : persons) {
if (name == person.m_Name) {
flag = true;
cout << "-----------------------------------------------" << endl;
cout << " 1.姓名 2.电话号码 " << endl;
cout << " 3.性别 4.年龄 " << endl;
cout << " 5.地址 0.返回 " << endl;
cout << " 请输入相应编号做相应修改。 " << endl;
cout << "-----------------------------------------------" << endl;
cin >> selection;
switch (selection) {
case 1: {cout << "新的姓名信息:"; cin >> person.m_Name; cout << "修改成功" << endl; break;}
case 2: {cout << "新的电话号码信息:"; cin >> person.m_Phone; cout << "修改成功" << endl; break;}
case 3: {cout << "新的性别信息:"; cin >> person.m_Gender; cout << "修改成功" << endl; break;}
case 4: {cout << "新的年龄信息:"; cin >> person.m_Age; cout << "修改成功" << endl; break;}
case 5: {cout << "新的地址信息:"; cin >> person.m_Address; cout << "修改成功" << endl; break;}
case 0: system("cls"); return;
default:cout << "输入错误!" << endl; break;
}
}
}if (!flag) cout << "查无此人!" << endl;
}

void cleanAll() {
cout << "确认全部清除?(y/n)";
cin >> ch;
if(ch == 'y' || ch == 'Y'){
persons.clear();
cout << "所有联系人信息均已消除!" << endl;
}else cout << "删除取消!" << endl;
}

int main()
{
while(true){
menu();
int selection = 0;
cin >> selection;
switch (selection) {
case 1: addPerson();
break;
case 2: search();
break;
case 3: showAll();
break;
case 4: deletePerson();
break;
case 5: modifyPerson();
break;
case 6: cleanAll();
break;
case 0: cout << "Bye!" << endl; exit(0);
default: cout << "Input Error! Please input a valid number." << endl;
break;
}
}
}

静态数组和vector动态数组各有千秋:

Vector动态数组:

  1. 动态大小:Vector 是一个动态容器,可以根据需要在运行时调整大小。它能够自动处理内存管理和扩展,而无需显式指定初始大小(与静态数组不同)。这使得 Vector 更加灵活,能够适应动态的数据需求。

  2. 安全性:Vector 具有边界检查功能,可以确保访问元素时不会越界,减少了程序崩溃或发生其他错误的风险。而静态数组没有内置的边界检查机制,如果不小心越界访问,可能会导致未定义的行为。

  3. 方便的操作和函数:Vector 对象提供了方便的成员函数和算法,如插入、删除、排序等操作。而静态数组通常需要手动编写这些操作的代码,相对来说更加繁琐。

  4. 可以返回长度:Vector 有 size() 成员函数用于获取当前容器中元素的数量,而对于静态数组,需要使用额外变量或固定长度进行追踪。

  5. 可以作为函数参数和返回值:Vector 可以直接作为函数的参数和返回值传递,而静态数组传递时需要指定数组大小,且容易造成内存浪费或限制传递的数组大小。

静态数组:

  1. 内存效率:静态数组在编译时就分配了连续的内存空间,并且没有额外的运行时开销。这使得静态数组在内存访问方面更加紧凑和高效,能够提高数据访问的局部性和缓存命中率,从而提升访问性能。
  2. 简单和直观:静态数组是一种基本的数据结构,使用起来非常简单和直观。只需声明数组并指定大小,即可直接访问和操作数组元素。
  3. 编译时确定大小:静态数组的大小在编译时确定,无法动态改变。这可以作为一种约束,确保不会超出预期的数组范围,并在编译时发现潜在的错误。
  4. 不涉及动态内存管理:由于静态数组在编译时分配了固定大小的内存,因此不存在动态内存管理的问题。这样可以避免动态内存分配和释放带来的开销和内存碎片问题。
  5. 适用于小规模数据集:对于小规模的数据集,静态数组的性能优势通常是微不足道的。与 Vector 数组相比,静态数组可能具有更低的内存开销和更高的执行效率。

在选择使用静态数组还是 Vector 数组时,需要综合考虑具体场景、数据规模和操作需求,并权衡各自的优缺点。

开发截图

On this page
对于动,静态数组使用的一些小思考