林允文
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
--- tags: note, book section, c/c++, concept --- # C/C++ Concept ## argc/argv ```cpp int main(int argc, char *argv[]) {... or int main(int argc, char **argv) {... ``` ```cpp int main(int argc, char * argv[]) { if (argv[1] == "yes"); // Wrong, compares two pointers if (strcmp(argv[1], "yes") == 0); // This compares what the pointers point to if (std::string(argv[1]) == "yes"); // Works fine if (argv[1] == std::string("yes")); // Works fine // Easy-mode std::vector<std::string> args(argv, argv+argc); for (size_t i = 1; i < args.size(); ++i) { if (args[i] == "yes") { // do something } } } ``` ### Reference - [C/C++ 程式設計教學:main 函數讀取命令列參數,argc 與 argv 用法](https://blog.gtwang.org/programming/c-cpp-tutorial-argc-argv-read-command-line-arguments/ "C/C++ 程式設計教學:main 函數讀取命令列參數,argc 與 argv 用法") - [Checking argv\[\] against a string? (C++)](https://stackoverflow.com/questions/5183203/checking-argv-against-a-string-c) ## error > - 要注意到 exception 要 include \<exception> ,但是 runtime_error 等其他的衍生 error 是要 include \<stdexcept> > - errno 要 #include \<errno.h> > - strerror 要 #include \<cstring> - errno - 是一個共用變數,存放錯誤代碼 - [errno.h](https://zh.wikipedia.org/wiki/Errno.h) ```c printf("something went wrong with! (%d)\n", errno); ``` - strerror() ```c printf("something went wrong with! %s\n", strerror(errno)); ``` - [How to know what the 'errno' means?](https://stackoverflow.com/questions/503878/how-to-know-what-the-errno-means) - %m - 也可以直接用這個,不用帶參數 ```c printf("something went wrong with! %m\n"); ``` - throw - how to ```cpp #include <stdexcept> char const * configfile = "hardcode.cfg"; std::string const anotherfile = get_file(); throw std::runtime_error(std::string("Failed: ") + configfile); throw std::runtime_error("Error: " + anotherfile); ``` ```cpp // 也可以直些丟 string ... throw "Division by zero condition!"; ... // 但是 catch 就要對應 } catch (const char* msg) { cerr << msg << endl; } ``` ```cpp // 可以分別 catch } catch( const std::invalid_argument& e ) { // do stuff with exception... } catch( const std::runtime_error& e ) { // do stuff with exception... } // 也可以抓所有 exception 或 type } catch (const std::exception& e) { } catch( ... ) { }; ``` - reference - [How to throw std::exceptions with variable messages?](https://stackoverflow.com/questions/12261915/how-to-throw-stdexceptions-with-variable-messages) - [C++ Exception Handling](https://www.tutorialspoint.com/cplusplus/cpp_exceptions_handling.htm) - [How to throw a C++ exception](https://stackoverflow.com/questions/8480640/how-to-throw-a-c-exception) - use e.what get message ```cpp } catch (std::exception &e) { cout << "exception: " << e.what() << "\n"; } ``` - 沒辦法直接丟 exception ```cpp throw new exception("queue is empty"); // error: no matching function for call to 'std::exception:exception(const char[15])' // solution #include <stdexcept> std::logic_error e("queue is empty"); throw std::exception(e); ``` - reference - [error: no matching function for call to 'std::exception:exception(const char[15])'](https://www.programmersought.com/article/24443125477/) - multiple catch ```cpp try { // throws something } catch ( const MostSpecificException& e ) { // handle custom exception } catch ( const LessSpecificException& e ) { // handle custom exception } catch ( const std::exception& e ) { // standard exceptions } catch ( ... ) { // everything else } ``` - reference - [Multiple Catch Block Example](https://www.decodejava.com/cpp-multiple-catch.htm) - [Catch Multiple Custom Exceptions? - C++](https://stackoverflow.com/questions/2512931/catch-multiple-custom-exceptions-c) - 自己建立一個 - class - struct - 繼承 runtime_error,當然也可以是其他的,不過不建議直接寫 exception 因為這樣要自己實作比較多東西 (e.g. what()) - create constructor with 你想要的參數 - 並且這個 constructor 也繼承 parent constructor 同時去呼叫他 - errorCode 以 member 的方式取用 ```cpp struct CSVException : std::runtime_error { CSVException(const std::string &msg, const WEBAPI_ERR &err) : std::runtime_error{msg}, errorCode{err} { } WEBAPI_ERR errorCode; }; ``` - reference - [Custom C++ Exceptions for Beginners](http://peterforgacs.github.io/2017/06/25/Custom-C-Exceptions-For-Beginners/) - [Custom exception](https://riptutorial.com/cplusplus/example/23640/custom-exception) ## header file ### "", <> - In practice, the difference is in the location where the preprocessor searches for the included file. - For `#include <filename>` the preprocessor searches in an implementation dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files. - For `#include "filename"` the preprocessor searches first in the same directory as the file containing the directive, and then follows the search path used for the `#include <filename>` form. This method is normally used to include programmer-defined header files. ### reference - [(c + +) 的標頭檔](https://docs.microsoft.com/zh-tw/cpp/cpp/header-files-cpp?view=msvc-160) - [c++ - What is the difference between #include \<filename> and #include "filename"? - Stack Overflow](https://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename) ## initialize ### (), {}, = - 它是統一的初始化,用標準術語來說是直接括號初始化。 - 除非存在接受`std::initializer_list`的建構函式,否則使用大括號構造物件等效於使用括號。 - 使用大括號的優點是語法不受[Most Vexing Parse](https://en.wikipedia.org/wiki/Most_vexing_parse)問題的影響: ```cpp struct Y { }; struct X { X(Y) { } }; // ... X x1(Y()); // MVP: Declares a function called x1 which returns // a value of type X and accepts a function that // takes no argument and returns a value of type Y. X x2{Y()}; // OK, constructs an object of type X called x2 and // provides a default-constructed temporary object // of type Y in input to X's constructor. ``` - 對於C++初學者來說,認為採用等號=的賦值初始化是調用賦值函數,其實不是這樣的。 ``` Widget w1; // call default constructor Widget w2 = w1; // not an assignment; calls copy ctor w1 = w2; // an assignment; calls copy operator= ``` - 大括號{}禁止內置數據類型從高類型轉向低類型,而小括號()和等號=則不會做這種檢查。 ``` double x, y, z; int sum1{ x + y + z }; // error! sum of doubles may not be expressible as int int sum2(x + y + z); // okay (value of expression truncated to an int) int sum3 = x + y + z; // ditto ``` - 不允許拷貝的對象可以用大括號{}和小括號()來初始化,但是不能採用等號=初始化。 ``` std::atomic<int> ai1{ 0 }; // fine std::atomic<int> ai2(0); // fine std::atomic<int> ai3 = 0; // error! ``` :::warning C++匹配std::initializer_list的優先級太高,以至於只要有可能,編譯器寧願報錯,也不願繼續尋找更加精確的匹配。 ::: - 大括號{}初始化是應用場景最廣泛最通用的初始化方式,它阻止高類型向低類型轉換,並且可以解決C++優先把表達式語句解析為聲明的問題。 - 重載構造函數時,大括號{}初始化只要有可能就會被匹配到std::initializer_list構造函數,即使其它構造函數可以提供更加精確的匹配。 ### constructor 後面的 ":" > - 如果您使用衍生類別生成物件,則建構函式的執行順序會從基底類別的建構函式開始執行起,這是可以理解的,因為基底類別是衍生類別的基礎,一些基礎的參數或 初始狀態必須先完成,再來再完成衍生類別中的建構函式。 > - 而在物件被消滅時,解構函式的執行順序則正好相反,是從衍生類別的解構函式開始執行,再來才是基礎類別的建構函式,因為若基底類別的解構函式如果先執行, 則衍生類別相依於基底類別的一些狀態也會被解構(例如指標),則此時再行衍生類別的解構函式,將存在著相依問題而造成錯誤。 - constructor 的初始化列表 ```cpp class myClass { public : myClass();// 構造函數,無返回類型,可以有參數列表,這裏省去 ~myClass();// 析構函數 int a; const int b; } myClass::myClass():a(1),b(1)// 初始化列表 { } ``` - 上面的例子展示了冒號的這個用法,下面對這個用法進行幾點說明: - 初始化列表的作用相當於在構造函數內進行相應成員變量的賦值,但兩者是有差別的。 - 在初始化列表中是對變量進行初始化,而在構造函數內是進行賦值操作。兩都的差別在對於像const類型數據的操作上表現得尤為明顯。 - const類型的變量必須在定義時進行初始化,而不能對const型的變量進行賦值,因此const類型的成員變量只能(而且必須)在初始化列表中進行初始化 - 這意味著您在建構函式主體中所做的分配將不是初始化,而是值的更改 ``` myClass::myClass() { a = 1;// 沒錯,效果相當於在初始化列表中進行初始化 b = 1;// 出錯,const變量不能進行賦值操作; } 2)初始化的順序與成員變量聲名的順序相同。 先看一下下面的程序: myClass::myClass():b(1),a(b) { } ``` - 這樣的執行結果a,b各是多少呢?b=1,a=1?不是,b=1而a是個隨機數。這一點是相當重要的哦,一般在初始化列表中進行初始化時,初始化的順序應與聲明的順序保持一致,防止出現不必要的錯誤。 - reference - [【C++】用大括號呼叫建構函式](https://www.796t.com/post/M2VsbmU=.html) - [C++編程之路(4)-小括號()與大括號創建對象的區別](https://kknews.cc/zh-tw/code/xenypr8.html) - [繼承後的建構函式與解構函式](https://openhome.cc/Gossip/CppGossip/ConDesAfterInheritance.html) - [C++ 冒號(:) 雙冒號(::) 的定義與應用](http://chiustin.blogspot.com/2017/02/c.html) ## forward reference - [潮.C++11 | Perfect Forwarding std::forward 完美轉發你的需求](https://tjsw.medium.com/%E6%BD%AE-c-11-perfect-forwarding-%E5%AE%8C%E7%BE%8E%E8%BD%89%E7%99%BC%E4%BD%A0%E7%9A%84%E9%9C%80%E6%B1%82-%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90-f991830bcd84) - [潮.C++11 | Universal Reference, Rvalue Reference, Move Semantics](https://tjsw.medium.com/%E6%BD%AE-c-11-universal-reference-rvalue-reference-move-semantics-1ea29f8cabdc) - [Reference declaration](https://en.cppreference.com/w/cpp/language/reference) - [[C++] rvalue reference 初入門](https://shininglionking.blogspot.com/2013/06/c-rvalue-reference.html) ## CRPT (Curiously Recurring Template Pattern) > - 一般地被稱作F-bound polymorphism 1. 一個衍生類別必須繼承一個樣版類別。 2. 該樣版類別必須使用該衍生類別做為其樣版參數。 - [潮.C++ | CRTP 和靜態多型](https://tjsw.medium.com/%E6%BD%AE-c-crtp-%E5%92%8C%E9%9D%9C%E6%85%8B%E5%A4%9A%E5%9E%8B-96a91b9e4db6) ## traits - traits,又被叫做特性萃取技術,說得簡單點就是提取“被傳進的對象”對應的返回類型,**讓同一個接口實現對應的功能**。 - 因為STL的算法和容器是分離的,兩者通過叠代器鏈接。算法的實現並不知道自己被傳進來什麽。萃取器相當於在接口和實現之間加一層**封裝**,來隱藏一些細節並協助調用合適的方法,這需要一些技巧(例如,偏特化)。最後附帶一個小小的例子,應該能更好地理解 特性萃取。 - 在 STL 中,容器与算法是分开的,彼此独立设计,容器与算法之间通过迭代器联系在一起 ### reference - [C++ traits技術淺談 - IT閱讀](https://www.itread01.com/articles/1488168040.html) - [细说 C++ Traits Classes_Leo的博客-CSDN博客_c++ traits](https://blog.csdn.net/lihao21/article/details/55043881) ## RAII, finally - 資源取得即初始化(英語:Resource Acquisition Is Initialization) - 直接的意思是:「資源獲得即初始化」。意即:一旦在程式中有「資源配置」的行為,也就是一旦有「配置、釋放」的動作,就讓「配置」成為一個初始化的動作,如此,釋放動作就變成自動的了(依物件的 scope 決定)。 - 簡單地說,RAII 就是善用 C++ class 的解構式(destroctor),來達成 資源自動管理的目的。簡單應用如下: ```cpp void f() // 一、使用 auto\_ptr 避免手動 delete { // 假設由於某種原因,TMemoryStream 必須以 new 的方式建立 std::auto\_ptr<TMemoryStream> p(new TMemoryStream); ... if (...) { throw 1; } ... } // OK, 沒問題,一旦碰到右大括號,即使發生異常,p 也會正確被釋放。 void g() // 二、使用 vector 取代手動配置 array { int N; std::cin >> N; std::vector<int> v(N); ... if (...) { throw 1; } ... } // OK, 沒問題,即使發生異常,也不必操心 v 內部的記憶體管理 std::string g2() // 三、以回傳物件的方式,取代回傳函式內部 new 的物件的指標 { std::string s; ... return s; } // OK, 外部模組不必擔心忘記釋放記憶體的問題。 ``` ### reference - [RAII - 維基百科,自由的百科全書](https://zh.wikipedia.org/wiki/RAII) - [[心得] The RAII Idiom - 精華區 C_and_CPP - 批踢踢實業坊](https://www.ptt.cc/man/C_and_CPP/D8D2/DA94/DDBB/M.1127480790.A.3B6.html) - [exception - Does C++ support 'finally' blocks? (And what's this 'RAII' I keep hearing about?) - Stack Overflow](https://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about) ## regex - 在C++11中,要使用正規表達式之前必須要先引入正規表達式的函式庫,記得要先加入下面這行: ``` #include <regex> ``` - regex_match: 比對字串是否符合正規表達式所定義之格式 - regex_search: 搜尋字串中所有符合正規表達式所定義之格式的子字串 - regex_replace: 取代字串中所有符合正規表達式所定義之格式的子字串為別的字串 ### reference - [#C++11:正規表達式(Regular Expression)的使用 - 翼世界夢想領域](https://knightzone.studio/2015/05/10/2756/c11%EF%BC%9A%E6%AD%A3%E8%A6%8F%E8%A1%A8%E9%81%94%E5%BC%8Fregular-expression%E7%9A%84%E4%BD%BF%E7%94%A8/) ## chrono - C++11 提供了 \<chrono> 作為時間的 library,除了能夠獲取時間,且可以在多個單位轉換。 - 這個 Library 是只有時間 e.g. 小時、分鐘、秒..等,如果要日期則要使用其他 Library e.g. [HowardHinnant/date](https://github.com/HowardHinnant/date) 或是 `ctime()` - 所有的東西在 std::chrono 這個 namespace 底下。 ### introduce - `duration` - 時間的長度,可自由決定儲存的單位 - `time_point` - 時間點,相減會得到時間長度(`duration`) - Clocks - 根據物理時間回傳時間點(`time_point`) - 提供不同精度的 clock ### duration - `count()` 獲得 duration 的值(時間長度) - `duration_cast<T>()` 轉換時間長度單位 - 轉換是透過一開始定義的 `ratio` - `std::ratio<N, D>` 比例(用來表示分數的 class) - `N` 是分子(numerator),`D` 是分母(denominator) ```cpp typedef std::ratio<1,3> one_third; // one_third::num == 1 // one_third::den == 3 ``` ### clock * system_clock * 系統時間 * steady_clock * 單調:下一個時間點永遠不會小於上一個 * high_resolution_clock * 更高精度 * 有些平台上就是 steady_clock - `now()` 可以獲得現在時間,會回傳 `time_point` ```cpp auto a = system_clock::now(); auto b = steady_clock::now(); auto c = high_resolution_clock::now(); ``` ### time_point - 儲存著時間點(相對於時鐘的開始時間),內部會儲存著 duration。幾乎不會有需要自己 contruct time_point 的機會,通常都是使用 clock 的 alias,例如: ```cpp // ignore std::chrono:: system_clock::time_point today = system_clock::now(); steady_clock::time_point t1 = steady_clock::now(); high_resolution_clock::time_point t1 = high_resolution_clock::now(); ``` - `time_point` 運算後會得到 `duration`,time_point 可以跟 duration 做運算 ```cpp auto n = steady_clock::now(); auto fu = n + minutes(10); ``` - STL 的 chrono 並沒有定義 time_point 的輸出方式,所以我們並不能直接透過 output stream 來輸出 time_point 的資料,所以如果要把他輸出成字串的話,其實還有點麻煩… - 如果想要輸出的話,一個方法是透過 clock 提供的 to_time_t() 這個函式,把 time_point 先把他轉換成 C-style 的 time_t,然後再透過 ctime() 這類的函式做輸出;下面是一個簡單的範例: ### reference - [std::chrono::duration - cppreference.com](https://en.cppreference.com/w/cpp/chrono/duration) - [C++ - chrono 計時 | r0yblog](http://blog.roy4801.tw/2020/07/20/c++/chrono/) - [C++11 STL 的時間函式庫:chrono – Heresy's Space](https://kheresy.wordpress.com/2013/12/27/c-stl-chrono/) ## c/c++ true and false - definition - true evaluates to 1, false evaluates to 0 - but any int that is not 0 evaluates to true but is not equal to true since it isn't equal to 1. - e.g. ```clike if(0) // false if(1) // true if(2) // true if(0 == false) // true if(0 == true) // false if(1 == false) // false if(1 == true) // true if(2 == false) // false if(2 == true) // false cout << false // 0 cout << true // 1 ``` ### reference - [boolean - c++ bool question - Stack Overflow](https://stackoverflow.com/questions/5189072/c-bool-question) ## size_t - According to the 1999 ISO C standard (C99), `size_t` is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3). - `size_t`is an unsigned data type defined by several C/C++ standards, e.g. the C99 ISO/IEC 9899 standard, that is defined in `stddef.h`.[1](http://en.wikipedia.org/wiki/Size_t) It can be further imported by inclusion of `stdlib.h` as this file internally sub includes `stddef.h`. - This type is used to represent the size of an object. Library functions that take or return sizes expect them to be of type or have the return type of `size_t`. Further, the most frequently used compiler-based operator sizeof should evaluate to a constant value that is compatible with `size_t`. - others - the return type of `sizeof()` is `size_t` and it is an _unsigned integer_ - `operator new()` takes the number of bytes to allocate as a `size_t` parameter - `size_t` is defined in `<cstddef>` - `SIZE_MAX` is defined in `<limits.h>` in C99 but not mentioned in C++98?! - `size_t` is not included in the list of _fundamental integer types_ so I have always assumed that `size_t` is a type alias for one of the fundamental types: `char`, `short int`, `int`, and `long int`. :::info - Fortunately for us, the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#arithmetic "github.com") have a whole section on advising how to deal with arithmetic. The linked section will take you through programming examples that demonstrate where using signed types (like `int`) are preferred, and where unsigned types (like `size_t`) are acceptable. ::: ### reference - [int - What is size_t in C? - Stack Overflow](https://stackoverflow.com/questions/2550774/what-is-size-t-in-c) - [size_t vs int in C++ and/or C - Stack Overflow](https://stackoverflow.com/questions/994288/size-t-vs-int-in-c-and-or-c) - [Why do some C++ programs use size_t instead of int? What are the advantages? - Quora](https://www.quora.com/Why-do-some-C-programs-use-size_t-instead-of-int-What-are-the-advantages) ## Use of (void) before a function call - It prevents warning if some function are declared with attribute : "Warn if return value not used/checked" ### reference - [c++ - Use of (void) before a function call - Stack Overflow](https://stackoverflow.com/questions/13954517/use-of-void-before-a-function-call) - [c++ - Why cast unused return values to void? - Stack Overflow](https://stackoverflow.com/questions/689677/why-cast-unused-return-values-to-void) - [c - Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result - Stack Overflow](https://stackoverflow.com/questions/7271939/warning-ignoring-return-value-of-scanf-declared-with-attribute-warn-unused-r) ## NULL == nullptr - In C++11 and beyond, a pointer that is == NULL will also == nullptr and vice versa. - Uses of NULL other than comparing with a pointer (like using it to represent the null byte at the end of a string) won't work with nullptr ### reference - [Is C NULL equal to C++11 nullptr - Stack Overflow](https://stackoverflow.com/questions/36484473/is-c-null-equal-to-c11-nullptr) - [C++ nullptr 與 NULL 的差異 | ShengYu Talk](https://shengyu7697.github.io/cpp-nullptr/) ## C++ Reference Variables - `int &var = <some-variable>;` ```clike int main(void) { int a = 10; int &var = a; var = var + 1; std::cout<< "\na = "<< a <<"\n"; return 0; } ``` ### reference - [How to Use C++ Reference Variables (C++ Reference Vs Pointer Example)](https://www.thegeekstuff.com/2013/05/cpp-reference-variable/) ## 函式原型 (function prototype) - 在撰寫函式原型時,參數不需加名稱,只要寫入型別標註 (annotation) 即可;有些 C 程式碼會在函式原型加參數名稱,基本上僅是為了閱讀方便,函式原型的參數名稱不需和函式實作的參數名稱相同。 - e.g. ```clike /* Declare function prototype. */ char * hello(char []); int main(void) { /* Implement main program here. */ } char * hello(char name[]) { /* Implement function `hello()` here. */ } ``` ### reference - [[C 語言] 程式設計教學:如何撰寫函式 (Function) | 開放原始碼技術文件網](https://opensourcedoc.com/c-programming/function/) ## c string - ![](https://i.imgur.com/2DVfxlx.png) ### Declaration - `char str_name[size];` ### Initializing ```clike char str[] = "GeeksforGeeks"; char str[50] = "GeeksforGeeks"; char str[] = {'G','e','e','k','s','f','o','r','G','e','e','k','s','\0'}; char str[14] = {'G','e','e','k','s','f','o','r','G','e','e','k','s','\0'}; char first_name[15] = "ANTHONY"; char first_name[15] = {'A','N','T','H','O','N','Y','\0'}; // NULL character '\0' is required at end in this declaration char string1 [6] = "hello";/* string size = 'h'+'e'+'l'+'l'+'o'+"NULL" = 6 */ char string2 [ ] = "world"; /* string size = 'w'+'o'+'r'+'l'+'d'+"NULL" = 6 */ char string3[6] = {'h', 'e', 'l', 'l', 'o', '\0'} ; /*Declaration as set of characters ,Size 6*/ ``` ### Passing strings to function - As strings are character arrays, so we can pass strings to function in a same way we pass an array to a function ```clike void printStr(char str[]) { printf("String is : %s",str); } ``` ### string pointer ```c char s[] = "string"; char* s = "string\0"; ``` - No, those two lines do not achieve the same result. * char s[] = "string" results in a modifiable array of 7 bytes, which is initially filled with the content 's' 't' 'r' 'i' 'n' 'g' '\0' (all copied over at runtime from the string-literal). * char *s = "string" results in a pointer to some read-only memory containing the string-literal "string". * If you want to modify the contents of your string, then the first is the only way to go. * If you only need read-only access to a string, then the second one will be slightly faster because the string does not have to be copied. * In both cases, there is no need to specify a null terminator in the string literal. The compiler will take care of that for you when it encounters the closing ". ### initialize for 0 - Global variables and static variables are automatically initialized to zero. If you have simply ```c char ZEROARRAY[1024]; static int myArray[10]; ``` - at global scope it will be all zeros at runtime. But actually there _is_ a shorthand syntax if you had a local array. - If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type. You could write: ```c char ZEROARRAY[1024] = {0}; ``` - The compiler would fill the unwritten entries with zeros. - Alternatively you could use `memset` to initialize the array at program startup: ```c memset(ZEROARRAY, 0, 1024); ``` - That would be useful if you had changed it and wanted to reset it back to all zeros. ### reference - [Strings in C - GeeksforGeeks](https://www.geeksforgeeks.org/strings-in-c-2/) - [Strings in C: How to Declare Variable, Initialize, Print, Example](https://www.guru99.com/c-strings.html) - [In C, can I initialize a string in a pointer declaration the same way I can initialize a string in a char array declaration? - Stack Overflow](https://stackoverflow.com/questions/4051347/in-c-can-i-initialize-a-string-in-a-pointer-declaration-the-same-way-i-can-init) - [在 C 語言中將陣列初始化為 0 | D棧 - Delft Stack](https://www.delftstack.com/zh-tw/howto/c/c-initialize-array-to-0/) - [How to initialize array to 0 in C? - Stack Overflow](https://stackoverflow.com/questions/2589749/how-to-initialize-array-to-0-in-c/2589751) ## bzero vs memset - I don't see any reason to prefer bzero over memset. - memset is a standard C function while bzero has never been a C standard function. The rationale is probably because you can achieve exactly the same functionality using memset function. - Now regarding efficiency, compilers like gcc use builtin implementations for memset which switch to a particular implementation when a constant 0 is detected. Same for glibc when builtins are disabled. ### reference - [c - Why use bzero over memset? - Stack Overflow](https://stackoverflow.com/questions/17096990/why-use-bzero-over-memset/17097088) - [In C, what is the difference between bzero() and memset()? - Quora](https://www.quora.com/In-C-what-is-the-difference-between-bzero-and-memset)

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully