一:实验内容:
(1) 创建vector类型的容器,用于存放学生信息;
(2) 创建3个学生(值自定义),放入向量中存储;
(3) 编写函数计算所有学生的平均成绩;
(4) 在向量中增加一个学生;
(5) 从向量中删除第3个学生。
二:vector储存结构体类型
1.第一种方法:(不使用指针)
struct stu
{
string name;
int age;
}student;
vector <stu> v;
string name;
int age;
cin>>name;
cin>>age;
student.name = name;
student.age = age;
v.push_back(student);
//使用push_back,当v空间不够时,会给v自动寻找一块更大的内存,所以不需要使用new分配空间
这种方法是将结构体拷贝,将拷贝的结构体赋值给vector,原结构体变量是储存在栈中的
2.第二种方法:(使用指针)
struct stu
{
string name;
int age;
};
vector<stu*> v //这是将stu*类的指针放入容器vector中,但是没有赋值元素,所以没有给vector分配空间
stu* student = new stu();//定于结构体指针,需要手动分配内存
int age;
string name;
cin>>age>>name;
student->age = age;
student->name = name;
v.push_back(student);
这里因为结构体指针使用new分配的内存,所以结构体并用结构体指针来给结构体赋值,所以结构体是储存在堆中的。
补充:结构体或者变量如果在定义时就分配好空间则空间是在栈区
如果时在运行时通过new分配内存,则储存在堆中
注意这两中方法的 v.push_back(student) 虽然代码一样,但是他们有不同的含义。 、
① 传递的是对象,就是将对象拷贝并传递给push_back,如果后续再改变对象的值,vector中的值不会改变。
②传递的是指针,就是将指针拷贝并传给push_back,通过指针改变对象的值,vector中的值也会发生改变。
三:vector容器的遍历
方法一:使用数组元素的类似方式
// vector容器遍历方式1 —— 下标遍历
void traverseVector_1(vector<int> v)
{
for(unsigned int i = 0; i < v.size(); i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
}
// vector容器遍历方式1 —— 下标遍历
void traverseVector_1(vector<int*> v)
{
for(unsigned int i = 0; i < v.size(); ++i)
{
cout<<v[i]<<" ";
}
cout<<endl;
}
方法二:迭代器遍历
// vector容器遍历方式2 —— 迭代器遍历
void traverseVector_2(vector<int> v)
{
// 注:如果参数为const vector<int> 需要用const_iterator
for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout<<(*it)<<" ";
}
cout<<endl;
}
//使用引用
void printVector(vector<int>& v)
{
for (vector<int>::iterator it = v.begin();it != v.end();it++)
{
cout << *it<<" ";
}
cout << endl;
}
//上述方法是当储存的数据是单个的数据类型时
//当储存的是结构体数据类型时,只需使用(*it)指向所要打印的结构体对象
void printVector(vector<int>& v)
{
for (vector<int>::iterator it = v.begin();it != v.end();it++)
{
cout << (*it)->name<<" ";
cout << (*it)->age<<" ";
}
}
for (const auto& student : v)
{
cout << student.name << "\t" << student.no << "\t" << student.score << "\t" << student.sex << endl;
}
const auto& student : v 是一个基于范围的for循环,用于遍历容器v中的元素。
解析如下:
const:表示在循环过程中,student变量的值是不可修改的。
auto:表示编译器会自动推断出student的类型。
&:表示student是一个引用,即student和容器v中的元素共享内存地址。
student : v:表示从容器v中取出一个元素,并将其赋值给student。
这个循环的作用是遍历容器v中的每个元素,并将每个元素的值赋给student变量。
四:给vector赋值
//创建一个函数
creat_vector(vector<stu*>&pv,struct stu* student)
{
//给student开辟空间,不然空指针类型会报错
stu* student = new stu();
//先给struct类型赋值
cin>>student->name;
cin>>student->age;
//然后将struct类型赋给vector
pv.push_back(student);
}
!!!出现问题及原因!!!:
1.student->name的方式为何会出错??
2.vector 下标遍历的越界问题
原因是下标表示没有动态储存,需要手动分配足够的内存
3.vector指针的使用,不然vector的数据在函数之间不传递
在这里再复习一下三种传参方式:
1.引用传参
引用相当于是外部变量的别名,实际操作的就是该变量,即在函数内对该变量进行的话在外 部该变量也会相应被修改
2.赋值传参
实际上是复制了一个外部变量的副本进入函数中,在函数内操作的为该副本,对该变量的修 改并不会实际修改函数外的该变量
3.指针传参
如果传值方式传入的是指针,那么如果单纯修改指针,那么在跳出函数后,该指针指向不受影响,但是如果修改的是指针指向的值,那么外部指针所指向的内容会相应的修改。因为以指针为参数进行传值,也是在函数内部复制了一个指针的副本,因而在内部修改指针本身即修改其副本并不影响外部的指针,但是两个指针都是指向同一个内存空间的,因而如果在函数内部修改了指针指向的内容,外部指针指向的内容也就相应改变了。
正确代码:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct stu
{
string name;
string sex;
string no;
float score;
};
void print_vector(const vector<stu>& v);
void creatVector(vector<stu>& v);
int main()
{
vector<stu> v(3);
creatVector(v);
print_vector(v);
}
void print_vector(const vector<stu>& v)
{
for (const auto& student : v)
{
cout << student.name << "\t" << student.no << "\t" << student.score << "\t" << student.sex << endl;
}
}
void creatVector(vector<stu>& v)
{
for (int i = 1; i <= 3; i++)
{
stu student;
student.name = "name" + to_string(i);
student.no = to_string(i * 111111111);
student.sex = "男";
student.score = i * 67;
v.push_back(student);
}
}
错误代码:
#include <iostream>
#include <vector>
#include <string>
//(1) 创建vector类型的容器,用于存放学生信息;
//
//(2) 创建3个学生(值自定义),放入向量中存储;
//
//(3) 编写函数计算所有学生的平均成绩;
//
//(4) 在向量中增加一个学生;
//
//(5) 从向量中删除第3个学生。
using namespace std;
struct stu
{
string name;
string sex;
string no;
float score;
}*student;
void print_vector(vector<stu*> v);
void creatVector(struct stu* student, vector<stu*> v );
vector <stu*> v;//WHY V[3] BUXING ???
int stu_num = 0;
int main()
{
creatVector(student,v);
print_vector(v);
}
void print_vector(vector<stu*> v)
{
for (vector<stu*>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it)->name << "\t" << (*it)->no << "\t" << (*it)->score << "\t" << (*it)->sex << endl;
}
}
void creatVector(struct stu *student,vector<stu*> v)
{
student = new stu();
stu_num = 3;
for (int i = 0; i < stu_num; i++)
{
student->name = "name" + to_string(i);
student->no = to_string(i*111111111);
student->sex = "男";
student->score = i * 67;
v.push_back(student);
}
for (vector<stu*>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it)->name << "\t" << (*it)->no << "\t" << (*it)->score << "\t" << (*it)->sex << endl;
}
}
出现问题:
1.print_vector无法打印,但是同样的函数再正确的代码中就可以,我猜测是再creat_vector的部分出现了错
2.vector<stu> v(3);
vector<stu*> 类型不存在数组的形式,如果想使用数组就需要创建一个vector<stu>类型的