C++ 实验一 任务报告

📝实验一 任务报告

✨实验总结

😟遇到的问题:

略.

🧐解决方法:

略.

🤔思考:

略.

✨实验内容

🕐任务一

验证性实验。

使用C++标准库提供的复数模板类complex编码实现简单的复数运算。

在C++编码环境中,输入以下代码,结合运行结果,体验使用C++标准库进行编程的便捷,同时,观察和 理解类、对象、库函数的使用。

📃代码:

#include <complex.h>
#include <iostream>
#include <cmath>

int main()
{
    using namespace std;
    complex<double> c1(3, 4);
    complex<double> c2(4.5);
    complex<double> c3(c2);
    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c3 = " << c3 << endl;
    cout << "c1 + c2 = " << c1 + c2 << endl;
    cout << boolalpha; // 设置bool型值以true/false方式输出
    cout << "c1 == c2 : " << (c1 == c2) << endl;
    cout << "c3 == c2 : " << (c3 == c2) << endl;
    cout << "abs(c1) = " << abs(c1) << endl; // abs()对复数进行取模运算,头文件cmath
    complex<int> c4(3, 4), c5(2, 7);
    cout << "c4 - c5 = " << c4 - c5 << endl;
}

🎨截图:

image-20211024111344662

🤓思考:

(1) 复数模板类complex。由于是模板类,是对于抽象的数据类型,所以,使用时,在语法层面通过<>指 定具体类型。比如,分别指定复数类的实部和虚部是double类型和int类型。

(2) 库函数abs()。对于复数类型,abs()实现的是取模运算。设复数的实部和虚部分别是realimag, 取模 运算规则:sqrt(real2+imag2)

🕑任务二

验证性实验。

设计并实现一个雇员类Employee,满足如下要求:

数据成员

包括员工姓名、薪水、雇佣日期,以及,员工总数

函数成员

包括构造函数、设置员工信息、更新员工信息(薪水、雇佣时间)、打印员工信息、打印员工总数 等。

其中,Employee类定义在文件Employee.hpp中,使用类Employee类的测试代码在文件task2.cpp中。

C++编码环境中,输入以下代码,结合运行结果,理解和巩固C++中类的定义、实现方法,及const 成员、static成员等。

📃代码:

task2.hpp

#ifndef EMPLOYEE_HPP
#define EMPLOYEE_HPP
// Employee类的定义
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;
struct Date
{
    int year;
    int month;
    int day;
};

// Employee类的声明
class Employee
{
public:
    Employee();

    Employee(string name0, double salary0, int y, int m, int d);

    void set_info(string name0, double salary0, int y, int m, int d); // 设置雇员信息
    string get_name() const; // 获取雇员姓名
    double get_salary() const; // 获取雇员薪水
    void display_info() const; // 显示雇员信息
    void update_salary(double s); // 更新雇员薪水
    void update_hire_date(int y, int m, int d); // 更新雇佣日期
    void raise_salary(double by_percent); //
    static void display_count();

private:
    string name; // 雇员姓名
    double salary; // 雇员薪水
    Date hire_date; // 雇员雇佣日期
    static int count; // 用于记录雇员总人数
};

int Employee::count = 0;

// 默认构造函数
Employee::Employee()
{
    ++count;
}

// 带参数的构造函数
Employee::Employee(string name0, double salary0, int y, int m, int d) :
        name{name0}, salary{salary0}, hire_date{y, m, d}
{
    ++count;
}

// 设置员工信息
void Employee::set_info(string name0, double salary0, int y, int m, int d)
{
    name = name0;
    salary = salary0;
    hire_date.year = y;
    hire_date.month = m;
    hire_date.day = d;
}

// 获取员工姓名
string Employee::get_name() const
{
    return name;
}

// 获取员工薪水
double Employee::get_salary() const
{
    return salary;
}

// 显示雇员信息
void Employee::display_info() const
{
    cout << "name: " << name << endl;
    cout << "salary: " << salary << endl;
    cout << "hire_date: " << hire_date.year << "-" << setfill('0') <<
         setw(2) << hire_date.month << "-"
         <<
         setw(2) << hire_date.day;
}

// 更新薪水
void Employee::update_salary(double s)
{
    salary = s;
}

// 更新雇佣日期
void Employee::update_hire_date(int y, int m, int d)
{
    hire_date.year = y;
    hire_date.month = m;
    hire_date.day = d;
}

// 雇员提薪加成
// by_percent是提升比例
void Employee::raise_salary(double by_percent)
{
    double raise = salary * by_percent / 100;
    salary += raise;
}

// 显示雇员总数
void Employee::display_count()
{
    cout << "there are " << count << " employees\n";
}

#endif

task2.cpp

#include "task2.hpp"
#include <iostream>

int main()
{
    using namespace std;
    Employee employee1;
    employee1.set_info("Sam", 30000, 2015, 1, 6);
    employee1.update_hire_date(2017, 6, 30);
    employee1.update_salary(35000);
    employee1.display_info();
    cout << endl << endl;
    Employee employee2("Tony", 20000, 2020, 3, 16);
    employee2.raise_salary(15);
    employee2.display_info();
    cout << endl << endl;
    Employee::display_count();
    return 0;
}

🎨截图:

雇员信息

🤓思考:

略.

🕒任务三

不使用C++标准库,自行设计并实现一个复数类Complex,使其满足如下要求:

数据成员

用来表示复数的实部real和虚部imag,实部、虚部,均为小数形式。

函数成员

构造函数 支持以下方式定义复数对象:

Complex c1; // 不带参数
Complex c2(3); // 只有一个参数,相当于3 + 0i
Complex c3(3, 4); // 两个参数,相当于3 + 4i
Complex c4(c3); // 用c3构造c4

成员函数

  • get_real() 返回复数实部

  • get_imag() 返回复数虚部

  • show() 用于输出复数。要求以 3 + 4i3 - 4i 这样的形式输出 add() 用于把一个复数加到自身,比如 c1.add(c2) ,相当于 c1 += c2

友元函数

  • add() 用于实现两个复数相加,返回复数。比如 c3 = add(c1, c2); is_equal() 用于判断两个复数是否相等,返回true/false。比如 is_equal(c1, c2)

  • abs() 用于对复数进行取模运算 将类Complex的定义及友元函数实现,单独保存在文件Complex.hpp中。

使用task3.cpp中的代码,测试类Complex的各项接口是否正确。

📃代码:

task3.hpp

#ifndef TASK3_HPP
#define TASK3_HPP


#include <iostream>
#include <cmath>

using namespace std;

class Complex
{
private:
    double a;
    double b;
public:
    Complex() : a(0), b(0) {}

    Complex(double num1, double num2 = 0) : a(num1), b(num2) {}

    Complex(const Complex &c) : a(c.a), b(c.b) {}

    friend Complex add(const Complex &c1, const Complex &c2);

    friend bool is_equal(const Complex &c1, const Complex &c2);

    friend double abs(const Complex &c1);

    double get_real() const { return a; }

    double get_imag() const { return b; }

    void show() const
    {
        if (!b)
            cout << a << endl;
        else
            cout << a << " " << (signed int) b << "i" << endl;
    }

    void add(const Complex &c2)
    {
        a += c2.a;
        b += c2.b;
    }

};

Complex add(const Complex &c1, const Complex &c2)
{
    Complex c3(c1.a + c2.a, c1.b + c2.b);
    return c3;
}

bool is_equal(const Complex &c1, const Complex &c2)
{
    if (c1.get_imag() == c2.get_imag() && c1.get_real() == c2.get_real())
        return true;
    else
        return false;
}

double abs(const Complex &c1)
{
    return sqrt((c1.a * c1.a) + (c1.b * c1.b));
}

#endif //TASK3_HPP

task3.cpp

#include "task3.hpp"
#include <iostream>

int main()
{
    using namespace std;
    Complex c1(3, -4);
    const Complex c2(4.5);
    Complex c3(c1);
    cout << "c1 = ";
    c1.show();
    cout << endl;
    cout << "c2 = ";
    c2.show();
    cout << endl;
    cout << "c2.imag = " << c2.get_imag() << endl;
    cout << "c3 = ";
    c3.show();
    cout << endl;
    cout << "abs(c1) = ";
    cout << abs(c1) << endl;
    cout << boolalpha;
    cout << "c1 == c3 : " << is_equal(c1, c3) << endl;
    cout << "c1 == c2 : " << is_equal(c1, c2) << endl;
    Complex c4;
    c4 = add(c1, c2);
    cout << "c4 = c1 + c2 = ";
    c4.show();
    cout << endl;
    c1.add(c2);
    cout << "c1 += c2, " << "c1 = ";
    c1.show();
    cout << endl;
    return 0;
}

🎨截图:

复数运算

🤓思考:

复习了一下条件运算符(?:)
友元函数】在类内部,只能申明函数原型,不能定义函数体,不受访问级别的限制
友元类】友类的每个成员都可以访问另一个类中的保护成员和私有成员

🕓任务四

设计并实现一个用户类User,并在主函数中使用和测试这个类。具体要求如下:

数据成员

每个用户有用户名name、密码passwd、联系邮箱email三个属性。

还有一个类属性,用于记录用户总数n

函数成员

构造函数 如果定义用户对象时未设置密码和邮箱,密码默认为6个1,联系邮箱默认为空串。

User u1("Mary"); // 密码和邮箱,使用默认设置
User u2("John", "112233", "xyz@gmail.com")

成员函数

  • set_email()设置邮箱。提示用户从键盘输入邮箱。

  • change_passwd() 修改密码。修改密码前,要求先输入旧的密码,验证无误后,才允许修改;如果输入旧 密码时,连续三次输入错误,则提示用户稍后再试,暂时退出修改密码程序。

  • print_info() 打印用户名、密码、联系邮箱。其中,密码以6个*方式显示。

User类的定义和实现,保存在文件User.hpp中。 User类的使用和测试,保存在文件task4.cpp中。

📃代码:

task4.hpp

#ifndef TASK4_HPP
#define TASK4_HPP
#include <iostream>
#include <string>

using namespace std;

class User
{
private:
    string name;
    string passwd;
    string email;
public:
    static int num;

    User(string n = "Default", string p = "111111", string e = "") : name(n), passwd(p), email(e) { num++; }

    static void print_n() { cout << "Num of users is: " << num; }

    void print_info() { cout << "Name:" << name << "  Passwd:" << "******" << "  E-mail:" << email << endl; }

    void set_email()
    {
        cout << "Please enter your E-mail:";
        cin >> email;
        cout << "Setting E-mail... Done." << endl;
    }

    void change_passwd()
    {
        string temp, new_passwd;
        cout << "Changing password for " << name << endl;
        cout << "Old password:";
        cin >> temp;
        if (passwd != temp)
        {
            cout << "Wrong password, please try again." << endl;
        }
        else
        {
            cout << "New password:";
            cin >> temp;
            cout << "Ensure password:";
            cin >> new_passwd;
            if (temp != new_passwd)
                cout << "New password doesn't match, please try again." << endl;
            else
            {
                passwd = new_passwd;
                cout << "Changing password... Done." << endl;
            }
        }
    }
};

int User::num = 0;
#endif //TASK4_HPP

task4.cpp

#include "task4.hpp"
#include <iostream>

int main()
{
    using namespace std;
    cout << "testing 1......" << endl;
    User user1("Jonny", "92197", "xyz@hotmail.com");
    user1.print_info();
    cout << endl
         << "testing 2......" << endl
         << endl;
    User user2("Leonard");
    user2.change_passwd();
    user2.set_email();
    user2.print_info();
    User::print_n();
}

🎨截图:

任务4

🤓思考:

User类的完善及拓展丰富*(选做)

  1. 设置邮箱时,对邮箱地址合法性进行检测提示,比如,是否包含@

  2. 设置密码时,对密码的长度、合法性进行校验

    使用正则表达式匹配,如果合法则修改密码或邮箱

#ifndef TASK4_HPP
#define TASK4_HPP

#include <iostream>
#include <string>
#include <regex>

using namespace std;

class User
{
private:
    string name;
    string passwd;
    string email;
public:
    static int num;

    User(string n = "Default", string p = "111111", string e = "") : name(n), passwd(p), email(e) { num++; }

    void change_passwd();

    void set_email();

    static void print_n() { cout << "Num of users is: " << num; }

    void print_info() const { cout << "Name:" << name << "  Passwd:" << "******" << "  E-mail:" << email << endl; }
};

int User::num = 0;

void User::change_passwd()
{
    string temp, new_passwd, str;
    cout << "Changing password for " << name << endl;
    cout << "Old password:";
    cin >> temp;
    if (passwd != temp)
    {
        cout << "Wrong password, please try it again." << endl;
    }
    else
    {
        cout << "New password:";
        cin >> temp;
        cout << "Ensure password:";
        cin >> new_passwd;
        if (temp != new_passwd)
            cout << "New password doesn't match, please try it again." << endl;
        else
        {
            //密码规则:长度>=8,包含大小写和特殊字符
            if (new_passwd.length() >= 8 && regex_search(new_passwd, regex("\\d")) &&
                regex_search(new_passwd, regex("\\W")) && regex_search(new_passwd, regex("[a-z]")) &&
                regex_search(new_passwd, regex("[A-Z]")))
            {
                passwd = new_passwd;
                cout << "Changing password... Done." << endl;
            }
            else
                cout
                        << "Must be 8 characters or more;" << endl
                        << "Needs at least one number,one uppercase letter, one lowercase letter and one symbol."
                        << endl
                        << "Change password failed." << endl;
        }
    }
}

void User::set_email()
{
    string str, temp = email;
    cout << "Please enter your E-mail:";
    cin >> email;
    //邮箱规则: 依次包含`@`和`.`
    if (regex_match(email, regex(".+[@].+[.].+")))
        cout << "Setting E-mail... Done." << endl;
    else
    {
        email = temp;
        cout << "Invalid E-mail. Set E-mail failed." << endl;
    }
}

#endif //TASK4_HPP

合法输入

非法输入

posted @ 2021-10-24 17:41  李柳星  阅读(133)  评论(4编辑  收藏  举报