Advanced Search
Search Results
56 total results found
6-4 將陣列傳入函數
傳址呼叫(call by address) 除了「傳值呼叫」、「傳參考呼叫」外,還有一種參數傳遞方式叫「傳址呼叫」。 為什麼叫「傳址」呢?因為這種方式是直接把變數在記憶體中的 「位址(address)」 傳進去給函數,在函數裡我們直接到記憶體中的相應位置去操作這個變數的值。所以傳址呼叫和傳參考呼叫一樣可以動到外面變數的值。 關於傳址呼叫,因為會接涉到記憶體位置和指標(pointer),比較複雜,我們會稍後再來看這個主題。 不過由於大家可能會有需要把一個陣列傳入函數裡,所以我們先來看要如何做到。 一個陣列裡面的元素可...
6-5 全域變數與靜態變數
全域變數(Global variable) 一般來說,我們使用函數時會將操作到的變數限制在函數裡,也就是以區域變數的方式使用。如有需要操作到函數外面的變數,我們會用傳參考或傳址的方式來處理。 我們以一個抽號碼牌的程式來示範。 練習:抽號碼牌(1) #include <iostream> using namespace std; int getTicket(int &num) // 以傳參考方式遞增外面的 num 變數值 { num++; return num; } int main() { ...
*2.4 C 語言的 printf( ) 格式化輸出函數
為什麼需要「格式化」輸出? 想像一下,如果你的程式計算出圓周率是 3.1415926,但你只想在螢幕上顯示 3.14;或者你希望輸出的成績單欄位能夠像表格一樣文字靠左對齊,數值靠右對齊。 這些都無法單純地將變數丟出來就辦到,我們需要「告訴」printf 應該用什麼「格式」來呈現資料,這就是格式化輸出的精髓。 標頭檔 要使用 printf,請務必在程式開頭引用標頭檔: #include <cstdio> cstdio 是指 C語言的標準輸入輸出(c standard input output)。 printf 語法...
*2.5 C 語言的 scanf( ) 格式化輸入函數
我們已經學會如何用 printf 讓程式輸出精美的訊息。但一個真正有用的程式,不僅要會「說」,更要會「聽」。它需要接收使用者的指令、數據,才能進行下一步的處理。 scanf (scan formatted) 就是這座溝通的橋樑。它會暫停程式的執行,靜靜地等待使用者從鍵盤輸入資料,然後依照我們指定的「格式」去解析這些輸入,並將它們存放到對應的變數中。 同樣地,要使用 scanf,請務必在程式開頭引用標頭檔: #include <cstdio> 2.5.1- scanf 的核心語法與「&」的秘密 scanf 的語法看...
3.5 三元運算子 ? :
3.5.1 三元運算子? : 在 C++ 中,三元運算子(Ternary Operator)是唯一一個需要三個運算元的運算子。它的符號是 ? 和 :。 這個運算子主要用來取代簡單的 if-else 判斷式,讓程式碼在一行內就能完成條件判斷與賦值,非常方便。 語法 三元運算子的基本語法結構如下: 條件式 ? 運算式1 : 運算式2; 條件式 (Condition): 這是一個會回傳 true (真) 或 false (假) 的布林表達式。 ? : 這是三元運算子的核心符號。 運算式1 (Expression1...
7-1 指標(pointer)
記憶體-位址 當宣告一個變數並賦予它初值後,我們可以確定這個值一定存放在電腦記憶體的某個地方,問題是它到底放在哪裡呢 ? 在地球表面上我們可以用經緯度來標定一個位置,而在電腦裡要標定記憶體中的某個位置則是要靠「位址(address)」 我們在寫程式時可以用 cout << a 來印出變數 a 的值,但大家必須了解背後的實際動作是將儲存 a 的那塊記憶體內容印出來。 眼尖的同學應該注意到了上圖中的位址每一個相差 4,這是因為我們以 int 型別的變數為例,而 int 的大小是 4 byte,所以每個 int 都要在...
8-1 struct
1. 自訂型別 struct 在 C++ 中,我們可以把多個彼此相關的資料包在一起,創造出一個全新的型別。 例如,一位學生可能有以下資料: 姓名 年齡 成績 如果分別用三個變數來表示,資料容易分散,必須想辦法維持追蹤同一個學生的姓名、年齡和成績。 struct 是一種自訂型別,可以把多個彼此相關的資料包在一起,創造出一個全新的型別。 struct Student { string name; int age; double score; }; 這表示我們建立了一個名為 Student ...
8-2 小專案參考解答
#include <iostream> #include <ctime> using namespace std; struct Item { string name; double price; int quantity; }; struct Date { int year; int month; int day; }; struct Time { int hh; int mm; int ss; }; struct Invoice ...
9-1 vector
1. 為什麼需要 vector? 1.1 傳統陣列的限制 在 C++ 中,我們熟悉的傳統陣列有一個根本的問題:大小必須在編譯時決定,且無法改變。 int scores[100]; // 固定 100 格,多了浪費,少了不夠用 傳統陣列的痛點: 宣告時必須給定大小(或使用 new,但要自己管理記憶體) 不知道目前有幾個元素(需要額外的變數追蹤) 插入、刪除元素需要手動搬移資料 忘記 delete[] 就記憶體洩漏(memory leak) // 傳統做法:又長又容易出錯 int* scores = new ...
9-2 vector 的基礎操作
vector 基礎操作 1. 引入標頭檔與宣告 使用 vector 前,需要引入標頭檔: #include <iostream> #include <vector> using namespace std; 2. 宣告與初始化 // 方式一:宣告空的 vector // capacity:0, size: 0 vector<int> v1; // 方式二:指定初始大小(元素值為 0) // capacity:5, size: 5 vector<int> v2(5); // [0, 0, 0,...
9-3 走訪 vector
走訪 vector 1. 方法一:下標 for 迴圈 最直覺的方式,適合需要使用索引時: vector<int> v = {10, 20, 30, 40, 50}; for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } // 輸出:10 20 30 40 50 v.size() 回傳型別為 size_t(無號整數),若用 int i = v.size() - 1 倒著走時要小心,空 vector 的 0 - 1 會變成一個很大的數。 2...
9-4 常用成員函數
其他常用成員函數 1. front() 與 back() vector<int> v = {10, 20, 30, 40, 50}; cout << v.front(); // 10:第一個元素 cout << v.back(); // 50:最後一個元素 v.front() = 99; // 可以修改 v.back() = 1; // v 現在是 {99, 20, 30, 40, 1} 2. insert():在指定位置插入 vector<int> v = {1, 2, 3, 4, 5}; ...
9-5 實作練習
練習一:成績管理系統(基礎操作) 題目敘述 請你撰寫一個程式,功能如下: 讀入 N 筆學生成績(整數,0~100) 輸出所有成績 輸出最高分、最低分、平均分數(取到小數點後兩位) 刪除最後一筆成績後,再輸出一次所有成績 範例輸入 5 90 75 88 62 95 範例輸出 成績:90 75 88 62 95 最高分:95 最低分:62 平均:82.00 刪除最後一筆後:90 75 88 62 提示 使用 push_back 加入一筆成績 善用 size()、pop_back() 參考解答(請先自己嘗...
10-1 類別(class)與物件(object)
一、物件(object)與類別(class) 在 C++ 中物件和類別有很嚴謹的定義,我們在這裡僅使用簡單例子來做介紹。 什麼是物件(Object)?你的iPhone是個物件、你現在坐著的這張椅子是個物件,小狗小黃也是個物件。 那類別呢(Class)?你的iPhone是個物件,隔壁同學的HTC One也是個物件,而它們同屬於「手機」這個類別。小黃是個物件、小黑也是個物件,牠們同屬於「狗」這個類別。 二、建立類別與產生物件 在產生物件之前必須先建立類別,在C++中建立類別要使用到 class 這個關鍵字,一個最簡單的...
10-2 存取控制——public 與 private
一、class 裡的東西,不是誰都可以動的 先看一個銀行帳戶的例子。 #include <iostream> using namespace std; class BankAccount { public: string owner; int balance; }; int main() { BankAccount acc; acc.owner = "小明"; acc.balance = 1000; acc.balance = -99999; // 沒...
10-3 如何建立複雜的類別
一、成員函數可以定義在 class 之外 我們可以只在 class body 中 宣告 member function,再將它 定義 在 class body 之外。 class sprite { private: string name; public: sprite(string _name); // 只有宣告 string getName(); // 只有宣告 }; // 定義 sprite 類別的 sprite 成員函數 sprite::sprite(string _n...
10-4 Class 練習題
練習一:電影票券(Ticket) 情境說明 你正在設計一套電影院售票系統。每張票券記錄了電影名稱、座位號碼、票價,以及是否已被使用。票券一旦使用就不能再次入場;票價不能設為負數。 規格列表 成員變數(皆為 private) 變數名稱 型態 說明 movieName string 電影名稱 seatNumber int 座位號碼 price int 票價(元) used bool 是否已使用 建構子 建構子 初始值 Ticket() movieName="未命名"、se...
11-1 規劃我們的 Vec 類別
一、Vec 類別需要什麼? 在這個章節裡,我們嘗試自己建立一個簡單版的 vector,一個叫做 Vec 的類別。 我們至少需要以下三項屬性: data: 指向一塊儲存資料的記憶體空間 size: 記錄目前 Vec 裡的元素數量 capacity: 記錄目前 Vec 裡己向作業系統要求配置的空間大小 接下來考慮需要對外公開的成員函數。 Vec(): 建構函數 ~Vec(): 解構函數 size(): 回傳目前 Vec 裡有幾個元素 capacity(): 回傳目前 Vec 配置的記憶體大小最多可...
11-2 實作 Vec 的細節
一、建構與解構函數 在建構函數中,我們要初始化 Vec 的 data member。因為剛建立好的 Vec 會是一個空的容器,所以一開始 m_size 和 m_capacity 都是 0。而 m_data 則先賦予它 nullptr 值,表示目前沒有指向任何記憶體。 Vec::Vec() { m_data = nullptr; m_size = 0; m_capacity = 0; } 在解構函數部分,我們先檢查是不有向作業系統要求配置記憶體,若有的話 m_data 將不會是 nullpt...
11-3 測試 Vec 類別
目前我們的 Vec 類別如下: [vec.h] #ifndef VEC_H_INCLUDED #define VEC_H_INCLUDED class Vec { private: int *m_data; int m_size; int m_capacity; public: Vec(); ~Vec(); int size(); int capacity(); void push_back(int val); void pop_back()...