Try   HackMD

實習課第八次作業

tags: NTOU CSE C++ Programming

教學文件和作業說明文件: https://hackmd.io/@kogiokka/ntou-cse-cpp-nav

範例程式和範例專案:Google Drive

本次作業目標為熟悉 class、constructor 和 destructor(類別、建構子和解構子)。

參考資料

13.2 — Classes and class members, LEARN C++

題目

實作一個 Stack 類別(儲存 int 型別)。Stack 類別應包含下列成員函式(member function):

函式名稱 回傳值型別 回傳值意義
push bool 代表成功或失敗
pop bool 代表成功或失敗
isEmpty bool 代表 stack 是否為空
isFull bool 代表 stack 是否滿了
printStack void 無回傳值

參考範例程式:class.cpp

需求

一、檔案

  1. 使用一個 header file
    stack.h
  2. main 函式以及 Stack 類別分別放在不同檔案:
    main.cpp
    stack.cpp

二、程式碼

  1. 不可用 global variables
  2. 定義 class Stack
  3. class Stack 定義放在 stack.h
  4. class Stack 的 member functions 定義放在 class 外 (stack.cpp內)
  5. 不再使用的 memory 必須全部釋放(freedelete)。

範例

用陣列(malloc 和 pointer)實作 class Stack(第五次版本二),包含下面功能:

成員函式 說明
constuctor 一個參數設定 stack 大小(預設值為 10)使用 malloc 分配記憶體給陣列(allocate memory)。
destructor 使用 free 釋放記憶體(deallocate meory)。
push 回傳成功或失敗
pop 回傳成功或失敗
isEmpty 回傳 stack 是否為空
isFull 回傳 stack 是否滿了
printStack 列印出 stack 中儲存的所有資料
stackInitial 接受一個參數設定堆疊的大小。如果 Stack 物件中的陣列已經持有記憶體,則分配參數指定的大小的記憶體給它,並且釋放舊的(一樣使用mallocfree)。回傳成功或失敗

注意事項

在 C++ 程式碼中使用 malloc 時請加入<cstdlib> 標頭檔。

程式中使用 malloc 分配記憶體時 C++ 編譯器可能會報錯。例如:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

因為 malloc 的回傳值是 void* 型別,而 C++ 對於型別的轉換有較嚴格的規定。所以請利用C++的static_castmalloc回傳值 cast 到變數的型別。範例:

#include <cstdlib> int main() { int* x = static_cast<int*>(malloc(10 * sizeof(int))); free(x); return 0; }

參考文件:https://en.cppreference.com/w/cpp/memory/c/malloc

參考程式架構

Stack.h

// Stack.h #ifndef STACK_H #define STACK_H class Stack { public: Stack(); Stack(int size); ~Stack(); bool push(int value); bool pop(); bool isEmpty(); bool isFull(); void printStack(); bool stackInitial(int size); }; #endif

Stack.cpp

// Stack.cpp #include "Stack.h" #include <cstdlib> /** * Default Constructor. Allocate memory for the stack. The size of stack is * default to 10. */ Stack::Stack() { /* TODO */ } /** * Constructor. Allocate memory for the stack. * * @param size The initial size of the stack. */ Stack::Stack(int size) { /* TODO */ } /** * Destructor. Deallocate the memory of the stack. */ Stack::~Stack() { /* TODO */ } /** * Member function. Push a value onto the stack. * * @param value The value to be pushed onto the stack. * @return Success or failure. */ bool Stack::push(int value) { /* TODO */ } /** * Member function. Pop the top value from the stack. * * @return Success or failure. */ bool Stack::pop() { /* TODO */ } /** * Member function. Check if the stack is empty. * * @return Whether the stack is empty or not. */ bool Stack::isEmpty() { /* TODO */ } /** * Member function. Check if the stack is full. * * @return Whether the stack is full or not. */ bool Stack::isFull() { /* TODO */ } /** * Member function. Print the whole stack. */ void Stack::printStack() { /* TODO */ } /** * Member function. Reset the stack and give it a new size. * * @param size The new stack size. * @return Success or failure. */ bool Stack::stackInitial(int size) { /* TODO */ }

測試案例

int main()
{
    Stack s(5);
    for (int i = 0; i < 5; i++)
        s.push(i);
    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 3; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 2; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    //--------------------------------------
    s.stackInitial(10);
    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 10; i++)
        s.push(i);
    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 5; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 5; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    //--------------------------------------
    s.stackInitial(15);
    for (int i = 0; i < 15; i++)
        s.push(i);
    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 5; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    for (int i = 0; i < 5; i++)
        cout << s.pop();

    cout << s.isEmpty();
    cout << s.isFull();

    return 0
}