一、实验目的
- 掌握 string 类和 vector 模板的基本用法
- 掌握动态内存分配
- 理解浅复制和深复制
- 掌握指针和引用的基础用法
- 灵活应用上述内容编程解决实际问题
二、实验准备
实验前,请围绕以下内容复习/学习指定内容
- string 类和 vector 模板的基本用法
- 学习教材 6.4 节、6.6 节及微视频(二维码见第 6 章课件)
- 关于 string 类和 vector 更丰富的用法,请自行查阅参考资料和工具书
new 和 delete 用法、指针及浅复制、深复制
结合教材示例 6-18,6-21,6-22,理解相关知识在这些示例中的应用三、实验内容
- string 类和 vector 模板基本用法
- 自行练习第 6 章课件中关于 string 类和 vector 模板的基本用法
- 阅读程序,理解程序功能,观察 vector 在其中的简单应用。
- 运行 ex1.cpp,输入任意整数,运行观察结果。
- 运行 ex2.cpp,分别输入 20,50,100 运行程序三次,结合运行结果,理解程序功能。
- 编程练习
根据注释,补足程序 ex3.cpp,并运行查看结果
- 指针基础知识
- 习题 6-17
- 习题 6-18
- 实现一个动态矩阵类 Matrix(类的声明见 matrix.h)。实现 Matrix 类,并编写代码完
成测试。
提示:- 相关例题参考:教材例 6-22,例 7-9
- 注意浅复制、深复制问题
期中考试 3 道编程题(考试时未完成或编写存在不完善的部分,请在本次实验中补上,题目见课程公共邮箱)
四、实验结论
1. 实验内容 1
#include <iostream>
#include <vector>
#include <string>
#define rap(a,b)for(int a=0;a<b;++a)
using namespace std;
// 函数声明
void output1(vector<string> &);
void output2(vector<string> &);
int main()
{
vector<string>likes, dislikes; // 创建vector<string>对象likes和dislikes
string sekil[]={"book", "music", "film", "paintings","anime","sport","sportsman"};
string sekilsid[]={"hana","dori","kaze","tsuki","doki","wutsirori"};
// 为vector<string>数组对象likes添加元素值 ( favorite book, music, film, paintings,anime,sport,sportsman,etc)
// 补足代码
// 。。。
rap(i,7)likes.push_back(sekil[i]);
cout << "-----I like these-----" << endl;
// 调用子函数输出vector<string>数组对象likes的元素值
// 补足代码
// 。。。
output1(likes);
// 为vector<string>数组对象dislikes添加元素值
// 补足代码
// 。。。
rap(i,6)dislikes.push_back(sekilsid[i]);
cout << "-----I dislike these-----" << endl;
// 调用子函数输出vector<string>数组对象dislikes的元素值
// 补足代码
// 。。。
output2(dislikes);
// 交换vector<string>对象likes和dislikes的元素值
// 补足代码
// 。。。
swap(likes,dislikes);
cout << "-----I likes these-----" << endl;
// 调用子函数输出vector<string>数组对象likes的元素值
// 补足代码
// 。。。
output1(likes);
cout << "-----I dislikes these-----" << endl;
// 调用子函数输出vector<string>数组对象dislikes的元素值
// 补足代码
// 。。。
output2(dislikes);
return 0;
}
// 函数实现
// 以下标方式输出vector<string>数组对象v的元素值
void output1(vector<string> &v) {
rap(i,v.size())cout<<v[i]<<endl;
// 补足程序
// 。。。
}
// 函数实现
// 以迭代器方式输出vector<string>数组对象v的元素值
void output2(vector<string> &v) {
for(vector<string>::iterator it = v.begin();it!=v.end();++it)cout<<(*it)<<endl;
// 补足程序
// 。。。
}
2. 实验内容 2
- 6-17
错误原因:指针没有赋予初值地址,便改变所指向地址的值
#include<bits/stdc++.h>
using namespace std;
int main(){
int *p;
p=new int (1);
*p=9;
cout<<"The value at p:"<<*p;
delete p;
return 0;
}
- 6-18
错误原因:给指针分配的内存没有被释放
#include<bits/stdc++.h>
using namespace std;
int fn1(){
int *p=new int(5);
return *p;
}
int main(){
int a=fn1();
cout<<"the value of a is:"<<a;
delete a;
return 0;
}
3. 实验内容 3
- Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
class Matrix {
public:
Matrix(int n); // 构造函数,构造一个n*n的矩阵
Matrix(int n, int m); // 构造函数,构造一个n*m的矩阵
Matrix(const Matrix &X); // 复制构造函数,使用已有的矩阵X构造
~Matrix(); //析构函数
void setMatrix(const float *pvalue); // 矩阵赋初值,用pvalue指向的内存块数据为矩阵赋值
void printMatrix() const; // 显示矩阵
inline float &element(int i, int j){return *(p+((i-1)*cols)+j-1);} //返回矩阵第i行第j列元素的引用
inline float element(int i, int j) const{return *(p+((i-1)*cols)+j-1);}// 返回矩阵第i行第j列元素的值
void setElement(int i, int j, int value); //设置矩阵第i行第j列元素值为value
inline int getLines() const{return lines;} //返回矩阵行数
inline int getCols() const{return cols;} //返回矩阵列数
private:
int lines; // 矩阵行数
int cols; // 矩阵列数
float *p; // 指向存放矩阵数据的内存块的首地址
};
#endif
- Matrix.cpp
#include<bits/stdc++.h>
#include "matrix.h"
#define rap(a,b) for(int a=0;a<b;++a)
using namespace std;
Matrix::Matrix(int n){ // 构造函数,构造一个n*n的矩阵
cols=lines=n;
float **mat= new float *[lines];
rap(i,lines)mat[i]=new float[cols];
p=new float[n*n];
rap(i,lines)memcpy(p+(i*cols),mat[i],cols*sizeof(float));
}
Matrix::Matrix(int n, int m){// 构造函数,构造一个n*m的矩阵
lines=n;
cols=m;
float **mat= new float *[lines];
rap(i,lines)mat[i]= new float[cols];
p=new float[n*m];
rap(i,lines)memcpy(p+(i*cols),mat[i],cols*sizeof(float));
}
Matrix::Matrix(const Matrix &X){ // 复制构造函数,使用已有的矩阵X构造
cols=X.cols;
lines=X.lines;
p=new float[cols*lines];
memcpy(p,X.p,cols*lines*sizeof(float));
}
void Matrix::setMatrix(const float *pvalue){ // 矩阵赋初值,用pvalue指向的内存块数据为矩阵赋值
rap(i,lines)
rap(j,cols)*(p+(i*cols)+j)=*(pvalue+(i*cols)+j);
}
void Matrix::printMatrix() const{
rap(i,lines)
{
rap(j,cols)
cout<<*(p+(i*cols)+j)<<" ";
cout<<endl;
}
}
Matrix::~Matrix(){
delete p;
}
void Matrix::setElement(int i, int j, int value){
*(p+((i-1)*cols)+j-1)=value;
}
- Main.cpp
#include<bits/stdc++.h>
#include"matrix.h"
#define rap(a,b) for(int a=0;a<b;++a)
using namespace std;
int main(){
float **mat= new float *[4];
rap(i,4) mat[i]=new float [5];
rap(i,4)rap(j,5)mat[i][j]=i*5+j;
float *tmp=new float[4*5];
rap(i,4)memcpy(tmp+(i*5),mat[i],5*sizeof(float));
Matrix c(2);
cout<<"Testing PrintMatrix Func"<<endl;
c.printMatrix();
Matrix a(4,5);
a.setMatrix(tmp);
cout<<"Testing setMatrix Func"<<endl;
a.printMatrix();
Matrix b(a);
cout<<"Testing CopyMatrix Func"<<endl;
b.printMatrix();
cout<<"Testing setElement Func"<<endl;
a.setElement(1,1,666);
a.printMatrix();
cout<<"Testing whether B's data changes after changing A's data:"<<endl;
b.printMatrix();
cout<<"Testing Print element func:"<<endl;
cout<<a.element(1,1)<<endl;
cout<<"Testing Print element's path func:"<<endl;
float *tmp2=&a.element(1,1);
cout<<tmp2<<endl;
cout<<"Testing Print A's line num"<<endl;
cout<<a.getLines()<<endl;
cout<<"Testing Print A's cols num"<<endl;
cout<<a.getCols()<<endl;
delete tmp;
rap(i,4)delete mat[i];
delete []mat;
return 0;
}
- Output:
4. 期中考试
- Dice:
- Dice.cpp
#include<bits/stdc++.h> #define rap(a,b) for(int a=0;a<b;++a) using namespace std; class Dice { private: int sides; public: Dice(int n):sides(n) { } int cast(); }; int Dice::cast() { return rand()%sides+1; } int main() { srand(time(NULL)); Dice mine(40); rap(j,5) { double p=0; int co=0; rap(i,500) { if (mine.cast()==26)co++; } p=(double)co/500.0; cout<<"第"<<j<<"次学号 20161334026 被抽中的概率是:"<<p<<endl; } return 0; }
- Output:
- Users:
- Users.h
#ifndef _User_h #define _User_h #include<bits/stdc++.h> using namespace std; class User{ private: int id; string name; string password; static int CurrentID; static User *nowID; public: User(string a,string b="111111"){ name=a; password=b; CurrentID++; id=CurrentID; nowID=this; } void PrintInfo(){ cout<<"ID: "<<id<<" Name: "<<name<<" Password: "<<password<<endl; } bool ChangePassword(); static void ShowCurrent(){ cout<<"CurrentID: "<<CurrentID<<" "; nowID->PrintInfo(); } }; #endif
- Users.cpp
#include"User.h" int User::CurrentID=999; User User::nowID=User("1"); bool User::ChangePassword(){ cout<<"Plz input old password!"<<endl; string tmp; int i=0; while(i++!=3) { cin>>tmp; if(tmp==password){ cout<<"Plz input new password!"<<endl; cin>>tmp; password=tmp; cout<<"Change Successfully"<<endl; return 1; } else cout<<"Wrong Input"<<endl; } cout<<"Wront Input more than 3 times, Plz try again!"<<endl; return 0; }
- Main.cpp
#include<bits/stdc++.h> #include"User.h" int main(){ cout<<"新建用户shy,密码20161334026"<<endl; User a("shy","20161334026"); cout<<"打印新建用户的信息`"<<endl; a.PrintInfo(); cout<<"新建用户shy2,密码4026"<<endl; User b("shy","4026"); User c("shy","4026"); b.PrintInfo(); b.ShowCurrent(); return 0; }
- Output
- Book:
- Book.cpp
#include "book.h" #include <iostream> #include <string> using namespace std; Book::Book(string isbnX, string titleX, float priceX){ isbn=isbnX; title=titleX; price=priceX; } void Book::print(){ cout<<"Isbn: "<<isbn<<" Title: "<<title<<" Price: "<<price<<endl; }
- Book.h
#ifndef BOOK_H #define BOOK_H #include <string> using std::string; class Book { public: Book(string isbnX, string titleX, float priceX); //构造函数 void print(); // 打印图书信息 private: string isbn; string title; float price; }; #endif
- Main.cpp
#include "book.h" #include <vector> #include <iostream> using namespace std; int main() { vector<Book>a; string isbn, title; float price; while(1){ cin>>isbn>>title>>price; if(isbn=="0"&&title=="0"&&price==0) break; Book tmp(isbn,title,price); a.push_back(tmp); } cout<<"Data\n"; for(int i=0;i<a.size();++i)a[i].print(); return 0; } /*input 978-7-302-22798-4 cp 56.00 978-7-302-22798-5 cpa 53.00 978-7-302-22798-3 cpb 54.00 978-7-302-22798-2 cpc 55.00 0 0 0 */
- Output: