# 函數呼叫&字串函數 2020 Clang, 0w1 --- ### 函數? ![](https://upload.wikimedia.org/wikipedia/commons/0/02/Total_function.svg) ---- > 從輸入值集合 X 到可能的輸出值集合 Y 的函數 f 記作 f : X → Y 是 X 與 Y 的關係,滿足如下條件: > 1. f 是完全的 > 2. f 是多對一的 ---- f 是完全的 -> 對輸入值集合 X 裡的任何元素 x 輸出值集合 Y 裡存在 f(x) ---- f 是多對一的 -> 允許 f(x) = f(y), x $\neq$ y 不允許 f(x) = a, f(x) = b, a $\neq$ b ---- ![](https://i.imgur.com/hcXcoB4.jpg) ---- 想成他是一個黑盒子就好,東西進去,東西出來。 ![](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Function_machine2.svg/220px-Function_machine2.svg.png) ---- 國中數學課本裡的例子: 函數:販賣機 輸入:錢 + 想買的飲料的編號 輸出:飲料 + 找零 or 找零(錢不夠) --- ### Your first function ```c++ int main() { return 0; } ``` --- ### 函數的長相 一般的函數大概會長這樣: ```c++ 回傳的型態 函數名稱(參數 1, 參數 2, ...) { 各種處理 return 回傳值; } ``` ---- ### 函數宣告/呼叫 要使用定義好的函數,我們只要看清楚函數宣告的第一行: ```c++ int add(int a, int b) ... ``` ```c++ int x = add(3, 4); // x = 7 int y = add(3, add(4, 5)); // y = 12 ``` --- ### C++ Library * 裡面有很多常用函數 * 需要你明確引入(include) 才可以使用 * 參閱 https://zh.cppreference.com ---- ### 高中生熟悉的函數們 請 include cmath ```cpp std::log10(100); // 2 std::abs(-3); // 3 std::exp2(10); // 1024 std::pow(3, 2); // 9 std::sqrt(9); // 3 std::sin(0); // 0 std::acos(-1); // 3.14159 ``` ---- ### 好用的函數們 請 include algorithm ```cpp std::min(2, 3); // 2 std::max(2, 3); // 3 std::swap(x, y); ``` --- ### 函數回傳值 ---- * 有些函數沒有回傳值 ```cpp int x = 3, y = 5; std::swap(x, y); // x = 5, y = 3 ``` ---- * 有些函數有回傳值 * 語法上可以直接當他是個值 ```cpp std::min(3, std::max(1, 2)); // == std::min(3, 2) // == 2 ``` ---- * 函數呼叫時參數的處理順序沒有規範 * 避免會相互影響的東西出現在參數欄位 * 否則結果為何端看你的編譯器 ```cpp int x = 3, y = 5; std::min(y = x, x = y); // what happens? ``` --- ### 字串常用函數 這節介紹一些實用的字串相關函數 :P --- ### 字串複習 ---- ```cpp char a; ``` a 是字元,亦是一個 0~255 的整數 ---- ```cpp char a[] = "..."; ``` a 是字串 (C-style),亦是字元的陣列 ---- * C-style 字串結尾是 0 ```c++ char a[] = "ABC"; int x = a[3]; std::cout << x; // 0 ``` ---- ### 輸入 ```cpp char a[10]; std::cin >> a; // 讀到空白字元(會捨棄空白字元) std::cin.getline(a, 10); // 讀到換行字元(會捨棄換行字元) std::cin.getline(a, 10, 'x'); // 讀到x(會捨棄 x) ``` ---- ### 輸出 * 會依序輸出 a 的字元,直到 0 ```cpp char a[] = "ABCD"; std::cout << a; // ABCD a[2] = 0; std::cout << a; // AB ``` ---- * 這裡介紹 C-style 字串的函數 * 可以在 cstring 裡找到 * 勿與 C++ 字串 string 搞混 ---- * C-style string to C++style string ```cpp char a[] = "ABC"; std::string b = string(a); ``` ---- * C++style string to C-style string ```cpp std::string a = "ABC"; std::strlen(a.c_str()); // 3 ``` --- ### 字符分類 * int isXXX(char) * true -> 非零值 ---- ```cpp isalnum() // is alphabet or number islower() // is lowercase isdigit() // is digit isblank() // \n, \t, \0, etc. ``` --- ### 字符操作 * int tolower(int) * int toupper(int) ---- ```cpp char a = std::tolower('A'); // 'a' char b = std::tolower('b'); // 'b' ``` --- ### 數值轉換 * int atoi(char []) * long long atoll(char []) ---- ```cpp int a = std::atoi("34"); // a = 34 int b = std::atoi("3.4b"); // b = 3 int c = std::atoi("abc3"); // c = 0 ``` --- ### 字串操作 * strcpy(dest, src) * strncpy(dest, src, count) * strcat(dest, src) * strncat(dest, src, count) ---- ```cpp char a[5] = "AB"; std::strcpy(a, "CD"); // a = "CD" char b[5] = "AB"; std::strncpy(b, "EFG", 1); // b = "EB" char c[5] = "AB"; std::strcat(c, "CD"); // c = "ABCD" char d[5] = "AB"; std::strncat(d, "EFG", 1); // d = "ABE" ``` ---- * 當 dest 不夠大,行為未定義 --- ### 字串檢測 * int strlen(char a[]) * int strcmp(char l[], char r[]) * int strncmp(char l[], char r[], count) ---- ```cpp std::strlen("ABC"); // 3 std::strcmp("ABC", "AB"); // 1, note that it's > 0 std::strncmp("ABC", "AB", 2); // 0 ``` ---- strlen: * 若 a 所指向的字元數組中無空字元,則行為未定義。 ---- strcmp: * 若 l 或 r 不是指向空終止位元組字元串的指針,則行為未定義。 ---- strncmp: * 若出現越過 l 或 r 結尾的訪問,則行為未定義。 * 若 l 或 r 為空指針,則行為未定義。 --- ### 數組操作 * memset(dest, ch, count) ---- ```cpp int a[5]; // sizeof(a) = 5 * 4 = 20 std::memset(a, 1, sizeof(a)); // a[0..4] = 1465341783 std::memset(a, 256, sizeof(a)); // a[0..4] = 0 std::memset(a, 255, sizeof(a)); // a[0..4] = -1 ``` --- ### 常見不良習慣 ```cpp char s[] = "ABCD..."; for (int i = 0; i < std::strlen(s); ++i) { // ... } ``` --- ### 練習 - NEOJ 894 ![](https://images-cdn.9gag.com/photo/adLOLNj_700b.jpg)
{"metaMigratedAt":"2023-06-15T05:39:33.558Z","metaMigratedFrom":"Content","title":"函數呼叫&字串函數","breaks":true,"contributors":"[{\"id\":\"dec33987-0cd9-4214-9d3e-825262921019\",\"add\":8785,\"del\":4579}]"}
    578 views