* C++ 的部分移到 [[C Plus Plus|C++]]。 * 維護 [[wp>C++]] 中文版面。 * 盡可能只紀錄語言層面知識。 * [[wp>Evaluation strategy]] * [[wp>Evaluation_strategy#Call_by_value|Call by value]]: C 只有此種方法。 * In call-by-value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function (frequently by copying the value into a new memory region). * [[wp>Evaluation_strategy#Call_by_reference|Call by reference]]: C++ 另外支援此種方法。C 可以用傳遞指針 (仍為 call by value,value 為位址) 模擬 call by reference 的效果。 * In call-by-reference evaluation (also referred to as pass-by-reference), a function receives an implicit reference to a variable used as argument, rather than a copy of its value. * [[http://blog.tinlans.org/2009/11/29/%E5%82%B3-pointer-%E5%B0%B1%E6%98%AF-pass-by-value-%E9%80%99%E4%BB%B6%E4%BA%8B%E6%98%AF%E8%A6%81%E9%87%8D%E8%A4%87%E8%AC%9B%E5%B9%BE%E9%81%8D/|傳 pointer 就是 pass-by-value 這件事是要重複講幾遍]] ===== 前處理器 ===== * [[https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms|C Preprocessor tricks, tips, and idioms]] * [[http://jhnet.co.uk/articles/cpp_magic|C Pre-Processor Magic]] * What happens is that when RECURSIVE() is expanded, if RECURSIVE appears in its expansion it is 'painted blue' (macro language jargon) which prevents it ever being expanded as a macro. * 在前處理器展開巨集的時候,如果該巨集的定義中又包含其自身,則後者不被視為巨集 ([[wp>painted blue]])。此種處理方式禁止遞迴巨集 (recursive macro)。是否支援遞迴巨集,端看前處理器是否支援。 * [[https://monoinfinito.wordpress.com/2013/08/20/c-preprocessor-just-a-simple-replacer/|C preprocessor internals]] * [[http://stackoverflow.com/questions/5641836/c-preprocessor-recursive-macros|C preprocessor, recursive macros]] * [[http://www.cakoose.com/wiki/c_preprocessor_abuse|C Preprocessor Abuse]] * [[http://stackoverflow.com/questions/6080129/trick-filling-array-values-using-macros-code-generation|Trick : filling array values using macros (code generation)]] * [[http://www.kchodorow.com/blog/2012/08/24/a-neat-c-preprocessor-trick/|A Neat C Preprocessor Trick]] * The X Macro Trick 為常用技巧。 * [[http://stackoverflow.com/questions/2927245/looking-for-a-good-explanation-of-the-table-generation-macro-idiom|Looking for a good explanation of the table generation macro idiom]] * [[http://www.keithschwarz.com/cs106l/spring2009/handouts/080_Preprocessor_2.pdf|Advanced Preprocessor Techniques]] * [[http://stackoverflow.com/questions/650461/what-are-some-tricks-i-can-use-with-macros|What are some tricks I can use with macros?]] * [[http://stackoverflow.com/questions/1067226/c-multi-line-macro-do-while0-vs-scope-block|C multi-line macro: do/while(0) vs scope block [duplicate]]] * [[http://www.geeksforgeeks.org/multiline-macros-in-c/|Multiline macros in C]] ====== 常見問題 ====== * [[http://stackoverflow.com/questions/15638105/accessing-specific-memory-locations-in-c|Accessing Specific Memory Locations in C]] * [[https://paritycheck.wordpress.com/2009/03/27/what-does-this-mean-volatile-unsigned-char-0x22/|What Does This Mean? (*(Volatile Unsigned Char *)(0x22))]] * [[http://stackoverflow.com/questions/3691835/why-uninitialized-global-variable-is-weak-symbol|Why uninitialized global variable is weak symbol?]] * [[http://stackoverflow.com/questions/13596577/multiple-definition-of-value-when-compiling-c-program-with-uninitialized-globa|“multiple definition of value” when compiling C program with uninitialized global in g++ but not gcc]] * [[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16744.html|How does the compiler handle multiple definitions of global variables?]] * GCC 可以加上 ''-fno-common'' 選項,要求將多個且重名的未初始化全域變數產生至 .bss 段,最後交由鏈結器報錯。 $ gcc -fno-common main.c foo.c /tmp/ccBPsu3u.o:(.bss+0x0): multiple definition of `g_val' /tmp/ccf5NmfA.o:(.bss+0x0): first defined here collect2: error: ld returned 1 exit status * [[https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html|3.18 Options for Code Generation Conventions]] * Unix C compilers have traditionally permitted multiple definitions of such variables in different compilation units by placing the variables in a common block. This is the behavior specified by -fcommon, and is the default for GCC on most targets. On the other hand, this behavior is not required by ISO C, and on some targets may carry a speed or code size penalty on variable references. * 注意,ISO C 只是不要求編譯器編譯多個且重名的未初始化全域變數,而非像 C++ 禁止。 * [[https://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html|Re: Automatically initialize all global variables/arrays in GCC.]] * 可以選擇不將全域變數初始化為零。 * [[http://koopman.us/bess/chap19_globals.pdf|Chapter 19 Global Variables Are Evil]] * [[http://electronics.stackexchange.com/questions/97241/use-of-global-variables-in-embedded-systems|Use of global variables in Embedded Systems]] * [[http://www.geeksforgeeks.org/how-linkers-resolve-multiply-defined-global-symbols/|How Linkers Resolve Global Symbols Defined at Multiple Places?]] * 避免使用全域變數。 * [[http://embeddedgurus.com/stack-overflow/2009/08/a-tutorial-on-signed-and-unsigned-integers/|A tutorial on signed and unsigned integers]] ====== C ====== * [[http://c-faq.com/|comp.lang.c Frequently Asked Questions]] * [[https://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298|Expert C Programming: Deep C Secrets]] * Ch1. C Through the Mists of Time * Ch2. It’s Not a Bug, It’s a Language Feature * Ch3. Unscrambling Declarations in C * typedef 閱讀方式和宣告一樣,為已有型別引入別名。 // 看到 string,就是 char *。 typedef char * string; // 常應用於簡化函式指針。 void (*signal(int sig, void (*func)(int)))(int); // sig_t 是一個指針,指向一個參數為 int,返回值為 void 的函式。 typedef void (*sig_t) (int); // signal 接受一個 int 和一個 sig_t, 返回 sig_t。 sig_t signal(int sig, sig_t func); * [[http://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c|Why should we typedef a struct so often in C?]] * 不建議。 * Ch 4. The Shocking Truth: C Arrays and Pointers Are NOT the Same! * 定義 (definition) 確定對象 (object,鏈結器角度) 的型別並分配內存,創建對象。定義只能出現在一個地方。 * [[http://stackoverflow.com/questions/34986335/does-c-have-one-definition-rule-like-c|Does C have One Definition Rule like C++?]] * C 沒有像 C++ 明確定義的 [[wp>One Definition Rule]]。 * 聲明 (declaration,或稱宣告) 描述對象的類型,引用定義在其它檔案的對象。聲明可以出現多次。 ===== 常見問題 ===== * [[http://stackoverflow.com/questions/8106765/using-strtok-in-c|Using strtok in c]] * [[http://stackoverflow.com/questions/6432384/strdup-dumping-core-on-passing-null|strdup dumping core on passing NULL]] * 注意! strtok 會破壞被 tokenize 的字串,使用 strdup 拷貝一份備份供 strtok 使用。 * strdup 參數若為 NULL,其行為未定義。 * [[http://stackoverflow.com/questions/9627962/is-it-possible-to-convert-char-to-char-in-c|Is it possible to convert char[] to char* in C?]] * array 和 pointer 不等價。只有在某些情況下,array 操作會被轉換成 pointer 操作。 * [[https://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/|Myth and reality about inline in C99]] * [[http://stackoverflow.com/questions/25000497/whats-the-difference-between-static-inline-extern-inline-and-a-normal-inline-f|What's the difference between a static inline, extern inline and a normal inline function?]] * [[https://clang.llvm.org/compatibility.html#inline|C99 inline functions]] * [[https://gcc.gnu.org/gcc-5/porting_to.html|Porting to GCC 5]] // lib.h inline double dabs(double x) { return x < 0.0 ? -x : x; } // lib.c #include "lib.h" // 告知編譯器 dabs 的函式定義為何。 // 指示編譯器在 lib.o 產生函式定義。 extern inline double dabs(double x); * 為了讓編譯器能 inline 函式,inline 函式的定義一般都寫在 .h 檔。 * C89 沒有定義 inline,inline 是 GCC 擴展 (GNU89),用於指示編譯器 inline function。 * C99 以後對 inline 的解釋。 * inline: 該函式定義僅用於 inline,不會產生函式定義。如果該函式被引用 (調用),則在其它檔案必須有該函式的定義。No externally visible function is generated. If the function is referenced in this TU, an external definition has to exist in another TU; same as GNU89 extern inline with no redefinition. // 此處的 add 定義只用於 inline function。 inline int add(int i, int j) { return i + j; } int main() { // 如果編譯器無法 inline add 函式 (亦即透過函數調用 add),會產生 undefined symbol 錯誤。 // 嘗試比較 -O0 和 -O2 的差別。 int i = add(4, 5); return i; } * extern inline: 最終會產生函式定義。 * static inline: 不會產生函式定義。此函式只會在該定義所在的檔案被引用。 ===== 語言相關 ===== #include int main() { // 將整型 (int) -1,即 ffffffff,轉型成 size_t,進而得到 size_t 的最大值。 // (~(size_t)0) size_t length = (size_t)-1; printf("max value of size_t: %zu\n", length); printf("sizeof(size_t): %lu\n", sizeof(size_t)); } * [[http://bytes.com/topic/c/answers/614268-finding-max-value-size_t|finding max value of size_t]] * [[http://stackoverflow.com/questions/3472311/what-is-a-portable-method-to-find-the-maximum-value-of-size-t|What is a portable method to find the maximum value of size_t?]] * [[http://stackoverflow.com/questions/3168275/printf-format-specifiers-for-uint32-t-and-size-t|printf format specifiers for uint32_t and size_t]] * [[http://stackoverflow.com/questions/3918384/declaring-the-largest-array-using-size-t|declaring the largest array using size_t]] * [[http://linux.die.net/man/3/printf|printf]] // $ cat /proc/`pidof mmap`/maps // 00000000-100000000 rwxp 00000000 00:00 0 // 100000000-100001000 r-xp 00000000 00:0f 24080529 /nfs_home/chenwj/tmp/mmap #include #include #include #include // 4 * 1024 * 1024 * 1024 的寫法,會因為 4 預設型別為 int 而導致 overflow。 #define DEFAULT_CODE_GEN_BUFFER_SIZE (4UL << 30) int main() { void *ptr; size_t code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE; int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; // gcc -Wl,-Ttext-segment=0x100000000 -fPIE -pie hello.c -o hello // mmap 映射虛擬位址 4G 以下所有空間。 ptr = mmap(0, code_gen_buffer_size, PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0); if (ptr == MAP_FAILED) { printf("mmap failed!\n"); abort(); } printf("ptr: 0x%016lx\n", (unsigned long)ptr); sleep(100); } * [[http://stackoverflow.com/questions/153890/printing-leading-0s-in-c|Printing leading 0's in C?]] * [[http://tw.myblog.yahoo.com/chimei-015/|有關C語言的struct進階初始化]] typedef struct _stu { char name[12]; int id; } stu; stu jenny; strutc _stu zakk; * [[http://stackoverflow.com/questions/18221291/how-to-check-if-plain-chars-are-signed-or-unsigned|How to check if plain chars are signed or unsigned?]] * [[http://stackoverflow.com/questions/1921539/using-boolean-values-in-c|Using boolean values in C]] typedef enum { false, true } bool; int main() { const bool char_is_signed = (char)-1 < 0; if (char_is_signed) { printf("signed char\n"); } else { printf("unsigned char\n"); } } * [[http://blog.3soh.flat1003.com/2013/07/readline-using-fscanf-in-c/|Readline using fscanf in C]] * fscanf 讀取字串以空白為界,欲達到讀取一行的字串。 #include FILE *my_file_ptr = fopen("some/path/file.txt", "r"); if (my_file_ptr != NULL) { char line[300]; // Read anything that is not line end, until line end is encountered. while (fscanf(my_file_ptr, "%[^\n]\n",line) != EOF) { printf("%s", line); } } * [[http://stackoverflow.com/questions/3784263/converting-an-int-into-a-4-byte-char-array-c|Converting an int into a 4 byte char array (C)]] * 透過 shift 和 mask 達成。 unsigned char bytes[4]; unsigned long n = 175; bytes[0] = (n >> 24) & 0xFF; bytes[1] = (n >> 16) & 0xFF; bytes[2] = (n >> 8) & 0xFF; bytes[3] = n & 0xFF; * [[http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/|Low Level Bit Hacks You Absolutely Must Know]] ===== 工作學習 ===== * [[http://stackoverflow.com/questions/4775437/read-unicode-file-into-wstring|read unicode file into wstring]] * [[http://stackoverflow.com/questions/13612340/c-fread-into-a-stdstring|C++ fread() into a std::string]] * [[http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring|Read whole ASCII file into C++ std::string]] * [[http://stackoverflow.com/questions/4786292/converting-unicode-strings-and-vice-versa|Converting unicode strings and vice-versa]] * [[http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring|Read whole ASCII file into C++ std::string]] * [[http://stackoverflow.com/questions/11576846/convert-ascii-string-to-unicode-windows-pure-c|Convert ASCII string to Unicode? Windows, pure C]] * [[http://stackoverflow.com/questions/215963/how-do-you-properly-use-widechartomultibyte|How do you properly use WideCharToMultiByte]] * [[http://www.joelonsoftware.com/articles/Unicode.html|The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets]] * [[http://www.abdullahyahya.com/2011/09/22/find-out-a-files-encoding-on-windows/|Find Out a File’s Encoding On Windows]] * [[http://stackoverflow.com/questions/90838/how-can-i-detect-the-encoding-codepage-of-a-text-file|How can I detect the encoding/codepage of a text file]] * [[http://encodingchecker.codeplex.com/|File Encoding Checker.]] * [[http://code.google.com/p/ude/|C# port of Mozilla Universal Charset Detector]] ==== 轉換編碼 ==== * 如果看到轉碼之後,出現額外的亂碼。要確定拷貝的字串長度是正確的。strlen 是以 '\0'做為字串結尾,計算字串長度。因此,如果字串緩衝區中沒有 '\0',得到的長度不會是正確的。這可能是出現亂碼的原因。 * 不確定欲處理的字串緩衝區是否有 '\0',避免使用 strlen 和 strcpy。改以 memcpy,並在額外配置的結尾處補上 '\0'。 ==== 其它 ==== * [[http://stackoverflow.com/questions/2462951/c-equivalent-of-stringbuffer-stringbuilder|C++ equivalent of StringBuffer/StringBuilder?]] * [[http://www.dreamincode.net/forums/topic/95826-stringstream-tutorial/|Stringstream Tutorial: Using A Stringstream To Read Input From A Csv File]] * [[http://stackoverflow.com/questions/368262/function-call-jumps-to-the-wrong-function|Function call jumps to the wrong function]] * [[http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors|When to use virtual destructors?]] * [[http://stackoverflow.com/questions/13448064/how-to-find-the-intersection-of-two-stdset-in-c|how to find the intersection of two std:set in C++?]] * [[http://stackoverflow.com/questions/22395738/c-wrapping-a-wrapper-macro-with-variable-arguments|C++ Wrapping a wrapper macro with variable arguments?]] * [[http://bytes.com/topic/c/answers/62216-stl-map-two-keys|STL with two keys ?]] * [[http://stackoverflow.com/questions/5058349/is-it-safe-to-use-the-this-pointer-in-an-initialization-list|Is it safe to use the “this” pointer in an initialization list?]] * [[http://stackoverflow.com/questions/4006160/in-c-initialize-a-class-member-with-this-pointer-during-construction|In C++, initialize a class member with 'this' pointer during construction]] * In short. The child CAN NOT use this pointer in its constructor/destructor but otherwise it is OK. * [[http://stackoverflow.com/questions/1112531/what-is-the-best-way-to-use-two-keys-with-a-stdmap|What is the best way to use two keys with a std::map?]] * [[http://stackoverflow.com/questions/16141178/is-it-possible-to-map-string-to-int-faster-than-using-hashmap|Is it possible to map string to int faster than using hashmap?]] * [[http://stackoverflow.com/questions/6371713/c-stl-map-stdpair-as-the-key|C++ STL map , std::pair as the key]] * 使用 typedef 定義 pair 為 map 的鍵值,避免編錯誤。 * [[http://stackoverflow.com/questions/1798112/removing-leading-and-trailing-spaces-from-a-string|Removing leading and trailing spaces from a string]] * 亦可用 Boost 函式庫。 ====== 外部連結 ====== * [[http://www.cplusplus.com/|cplusplus.com]] * [[http://www.cprogramming.com/|cprogramming.com]] * [[http://en.cppreference.com/w/cpp|C++ reference]] * [[http://www.learncpp.com|learncpp]] * [[http://akaedu.github.io/book/|Linux C编程一站式学习 (網頁版)]] * [[http://www.akaedu.org/down/LinuxC.pdf|Linux C编程一站式学习]] * [[http://isocpp.org/|News, Status & Discussion about Standard C++]] * [[http://isocpp.org/tour|Take the Tour]] * [[http://www.mindviewinc.com/Index.php|Thinking in C++, Second Edition (Volumes 1 & 2)]] * [[http://jjhou.boolan.com/|侯捷]] * [[http://www.cpax.org.uk/prg/portable/c/resources.php|C Resources]] * [[http://www.trumphurst.com/cpplibs/cpplibs.php|Available C++ Libraries list]] * [[http://jcatki.no-ip.org/fncpp|##C++]] * [[http://www.goingware.com/tips/member-pointers.html|Pointers to C++ Member Functions]] * [[Boost]] * [[http://www.justsoftwaresolutions.co.uk/|Just Software Solutions]] * [[http://learningcppisfun.blogspot.com/|Learning C++]] * [[http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms|More C++ Idioms]] * [[http://www.agner.org/optimize/optimizing_cpp.pdf|Optimizing software in C++]]