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

合法輸入

非法輸入


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM