c++实验二之vector容器的使用

一:实验内容:

(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>类型的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小布丁729

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值