# C language Tutorial ## Basic syntax ```c= #include <stdio.h> int main() { int myNum; scanf("%d", &myNum); printf("Your number is: %d", myNum); return 0; } ``` ### Header Files A header file is considered a standard header file if its name is enclosed in <>. The compiler will look for the header file in a predefined set of locations, which can be changed by setting the search path environment variable or by command line options. If the header file name is contained in " ", it is considered to be a non-system file, and the search for non-system files usually starts from the path where the source file is located. ref: - [#ifndef.#define, #endif 的用法 - Medium](https://medium.com/@nickhuang_1199/ifndef-define-endif-%E7%9A%84%E7%94%A8%E6%B3%95-c7d33d6b1d47) ## Variables - `int`: stores integers (whole numbers), without decimals, such as 123 or -123. (%d) - `float`: stores floating point numbers, with decimals, such as 19.99 or -19.99. (%f) - `char`: stores single characters, such as 'a' or 'B'. Char values are surrounded by single quotes. (%c) ```c= // create variables int myNum = 5; // Integer (whole number) float myFloatNum = 5.99; // Floating point number char myLetter = 'D'; // Character // print variables printf("%d\n", myNum); printf("%f\n", myFloatNum); printf("%c\n", myLetter); ``` ## Data type Common built-in data types in C language | Data type | Name | Format specifier | Bytes | Description | | :-------- | :--- | :--------------- | :---: | :---------- | | short integer | short int | %d | 2* | | | integer | int | %d or %i | 4* | Stores whole numbers, without decimals | | long intege | long int | %ld | 4/8 | | | character | char | %c | 1 | Stores a single character/letter/number, or ASCII values. | | single-precision floating point | float | %f | 4* | Stores fractional numbers, containing one or more decimals. Sufficient for storing 7 decimal digits. | | double-precision floating point | double | %1f | 8* | Stores fractional numbers, containing one or more decimals. Sufficient for storing 15 decimal digits. | | no | void | ? | | | address | pointer | %p | 4/8 | \* means implementation-defined behaviors ### `sizeof()` The "sizeof" operator can find the memory size occupied by a certain value or type on different compilations. ```c= int main(void) { char str[] = "Hello world."; printf("%zu \n", sizeof(str)); printf("%u \n", sizeof(str)); return 0; } ``` ### Constants When we do not want others to override existing variable values, use the const keyword. (this will declare the variable as "constant", which means unchangeable and read-only). It is considered good practice to declare them with uppercase. It is not required, but useful for code readability and common for C programmers. ```c= const float PI = 3.14; PI = 10; // error: assignment of read-only variable 'PI' ``` ## Escape sequence | Character | Description | | --------- |:----------- | | \n | new line | | \\" | " | ## Operators C divides the operators into the following groups: - Arithmetic operators - Assignment operators - Comparison operators - Logical operators - Bitwise operators ### Arithmetic operators | Operator | Name | Description | | -------- |:---- | :---------- | | + | Addition | Adds together two values. | | - | Subtraction | Subtracts one value from another. | | * | Multiplication | Multiplies two values. | | / | Division | Divides one value by another. | | % | Modulus | Returns the division remainder. | | ++ | Increment | Increases the value of a variable by 1. | | -- | Decrement | Decreases the value of a variable by 1. | ### Assignment operators Assignment operators are used to assign values to variables. We use the assignment operator (=) to assign the value 10 to a variable called x. ```c= int x = 10; x += 5; ``` ### Comparison operators | Operator | Name | | -------- |:---- | | == | Equal to | | != | Not equal | | > | Greater than | | < | Less than | | >= | Greater than or equal to | | <= | Less than or equal to | ### Logical operators | Operator | Name | Description | | -------- |:---- | :---------- | | && | Logical and | Returns true if both statements are true. | | \|\| | Logical or | Returns true if one of the statements is true. | | ! | Logical not | Reverse the result, returns false if the result is true. | ### Bitwise operators endian: [Big-Endian 與 Little-Endian](https://blog.gtwang.org/programming/difference-between-big-endian-and-little-endian-implementation-in-c/) ### Operator Precedence ![](https://i.imgur.com/93IfkvU.png) ## Conditions ```c= int time = 22; if (time < 10) { printf("Good morning."); } else if (time < 20) { printf("Good day."); } else { printf("Good evening."); } ``` ### Short Hand If...Else (Ternary Operator) ```c= int time = 20; (time < 18) ? printf("Good day.") : printf("Good evening."); ``` ```c= bool isEmpty(struct Node* node) { return (node == NULL) ? true : false; } ``` ### Switch ```c int day = 4; switch (day) { case 1: printf("Monday"); break; case 2: printf("Tuesday"); break; case 3: printf("Wednesday"); break; case 4: printf("Thursday"); break; case 5: printf("Friday"); break; case 6: printf("Saturday"); break; case 7: printf("Sunday"); break; default: printf("Looking forward to the Weekend"); } ``` If there is no `break` statement then the cases after the matched case, other than default will all get executed. ref: [https://www.studytonight.com/c/programs/basic/switch-case](https://www.studytonight.com/c/programs/basic/switch-case) ## Loop ### While loop ```c= int i = 0; while (i < 5) { printf("%d\n", i); i++; } ``` ```c= int i = 0; do { printf("%d\n", i); i++; } while (i < 5); ``` ### For loop ```c= for (int i = 0; i < 10; i++) { printf("%d\n", i); } ``` ### `break`, `continue` ## Arrays ```c= int myNumbers[] = {25, 50, 75, 100}; ``` ```c= int myNumbers[4]; myNumbers[0] = 25; myNumbers[1] = 50; myNumbers[2] = 75; myNumbers[3] = 100; ``` ```c= int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} }; ``` ## Structure A structure creates a data type that can be used to group items of possibly different types into a single type. Structures (also called structs) are a way to group several related variables into one place. Each variable in the structure is known as a member of the structure. Unlike an array, a structure can contain many different data types (int, float, char, etc.). ```c= struct address { char name[50]; char street[100]; char city[50]; char state[20]; int pin; }; ``` ### Declare structure variables ```c= struct Point { int x, y; } p1; ``` ```c= struct Point { int x, y; }; int main() { struct Point p1; } ``` ### Initialize structure members Structure members cannot be initialized with declaration. For example the following C program fails in compilation. ```c= struct Point { int x = 0; // COMPILER ERROR int y = 0; // COMPILER ERROR }; ``` The reason for above error is simple, when a datatype is declared, no memory is allocated for it. Memory is allocated only when variables are created. Structure members can be initialized using curly braces ‘{}’. ```c= struct Point { int x, y; }; int main() { struct Point p1 = {0, 1}; } ``` ### Access structure elements Structure members are accessed using dot (.) operator. ```c= struct Point { int x, y; }; int main() { struct Point p1 = {0, 1}; p1.x = 20; printf ("x = %d, y = %d", p1.x, p1.y); return 0; } ``` ### Designated initialization Designated Initialization allows structure members to be initialized in any order. ```c= struct Point { int x, y, z; }; int main() { struct Point p1 = {.y = 0, .z = 1, .x = 2}; struct Point p2 = {.x = 20}; printf ("x = %d, y = %d, z = %d\n", p1.x, p1.y, p1.z); printf ("x = %d", p2.x); return 0; } ``` ### Array of structures Like other primitive data types, we can create an array of structures. ```c= struct Point { int x, y; }; int main() { struct Point arr[10]; arr[0].x = 10; arr[0].y = 20; printf("%d %d", arr[0].x, arr[0].y); return 0; } ``` ### Structure pointer Like primitive types, we can have pointer to a structure. If we have a pointer to structure, members are accessed using arrow ( -> ) operator. `ptr -> data` is equivalent to `(*ptr).data`. ```c= struct Point { int x, y; }; int main() { struct Point p1 = {1, 2}; struct Point *p2 = &p1; printf("%d %d", p2->x, p2->y); return 0; } ``` ### Difference between Structure and Union 1) When storing multiple member information, the compiler will automatically allocate storage space to the first member of the struct. A struct can store multiple member information. However, each member of Union uses the same storage space and can only store the information of the last member. 2) Both are composed of multiple members of different data types. But at any one time, the Union only stores one member that was selected first. And all members of the structure are present. 3) For the assignment of different members of Union, other members will be rewritten, and the value of the original member will no longer exist. However, assignments to different members of struct do not affect each other. ```c= #include <stdio.h> struct t_struct { int a; char b; short c; }; union t_union { int a; double b; char c; }; int main() { struct t_struct s; union t_union u; printf("%d \n", sizeof(s)); printf("%d \n", sizeof(u)); s.a = 1; s.b = 'b'; s.c = 3; u.a = 1; u.b = 2; u.c = 'c'; printf("%d %c %d \n", s.a, s.b, s.c); printf("%d %d %c \n", u.a, u.b, u.c); return 0; } ``` #### Memory alignment 1) union takes the largest size of the elements, struct takes the sum of all elements' size 2) struct consider memory discontinuity problems (memory size is alignment size) 3) Align with the largerest size of the elements 4) Only use pack(size) if the largerest size of elements is greater than pack(size) union ```c= union u1 { double a; int b; }; union u2 { char a[13]; int b; }; union u3 { char a[13]; char b; }; int main() { union u1 t1; union u2 t2; union u3 t3; printf("%d \n", sizeof(t1)); printf("%d \n", sizeof(t2)); printf("%d \n", sizeof(t3)); return 0; } ``` ```c= #pragma pack(2) union u1 { double a; int b; }; union u2 { char a[13]; int b; }; union u3 { char a[13]; char b; }; int main() { union u1 t1; union u2 t2; union u3 t3; printf("%d \n", sizeof(t1)); printf("%d \n", sizeof(t2)); printf("%d \n", sizeof(t3)); return 0; } ``` struct ```c= struct s1 { char a; double b; int c; char d; }; struct s2 { char a; char b; int c; double d; }; int main() { struct s1 t1; struct s2 t2; printf("%d \n", sizeof(t1)); printf("%d \n", sizeof(t2)); return 0; } ``` ```c= #pragma pack(2) struct s1 { char a; double b; int c; char d; }; struct s2 { char a; char b; int c; double d; }; int main() { struct s1 t1; struct s2 t2; printf("%d \n", sizeof(t1)); printf("%d \n", sizeof(t2)); return 0; } ``` union and struct ```c= #include <stdio.h> // #pragma pack(1) typedef union { unsigned short v1; struct { unsigned char c1; unsigned char c2; unsigned char c3; } v2; } myUniA; int main() { printf("Size of unsinged char = %d\n", sizeof(unsigned char)); printf("Size of unsigned short = %d\n", sizeof(unsigned short)); printf("Size of myUniA = %d\n", sizeof(myUniA)); myUniA a; a.v1 = 0x1122; a.v2.c3 = 0x33; unsigned char* ptr = (unsigned char*) &a; int i, s = sizeof(myUniA); printf("a = "); for (i = 0; i < s; ++i) printf("%02X ", ptr[i]); printf("\n"); } ``` ### typedef The typedef is a keyword that is used in C programming to provide existing data types with a new name. typedef keyword is used to redefine the name already the existing name. When names of datatypes become difficult to use in programs, typedef is used with user-defined datatypes, which behave similarly to defining an alias for commands. Applications of typedef: - The typedef keyword gives a meaningful name to the existing data type which helps other users to understand the program more easily. - It can be used with structures to increase code readability and we don’t have to type struct again and again. - The typedef keyword can also be used with pointers to declare multiple pointers in a single statement. - It can be used with arrays to declare any number of variables. 1) Using typedef with structures typedef can also be used with structures in the C programming language. A new data type can be created and used to define the structure variable. ```c= #include <stdio.h> #include <string.h> typedef struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } Book; int main( ) { Book book; strcpy( book.title, "C Programming"); strcpy( book.author, "Nuha Ali"); strcpy( book.subject, "C Programming Tutorial"); book.book_id = 6495407; printf( "Book title : %s\n", book.title); printf( "Book author : %s\n", book.author); printf( "Book subject : %s\n", book.subject); printf( "Book book_id : %d\n", book.book_id); return 0; } ``` 2) Using typedef with pointers typedef can also be used with pointers as it gives an alias name to the pointers. Typedef is very efficient while declaring multiple pointers in a single statement because pointers bind to the right on the simple declaration. ```c= #include <stdio.h> typedef int* ptr; int main() { ptr var; *var = 20; printf("Value of var is %d", *var); return 0; } ``` 3) Using typedef with an Array typedef can also be used with an array to increase their count. ```c= int main() { Arr temp = {10, 20, 30, 40}; printf("typedef using an array\n"); for (int i = 0; i < 4; i++) printf("%d ", temp[i]); return 0; } ``` ### enum ```c= enum direction { Direction_North, Direction_South, Direction_East, Direction_West }; typedef enum direction Direction; int main(void) { Direction dest = Direction_East; printf("%d \n", dest); return 0; } ``` ref: - [Structures in C - GeeksforGeeks](https://www.geeksforgeeks.org/structures-c/?ref=gcse) - [C 語言 #pragma pack 預處理指令的意義、用法教學與範例程式碼](https://blog.gtwang.org/programming/c-language-pragma-pack-tutorial-and-examples/) - [C/C++ - struct與union的區別](https://gaexp251546.pixnet.net/blog/post/67520022) - [C - typedef - Tutorialspoint](https://www.tutorialspoint.com/cprogramming/c_typedef.htm) - [typedef in C - GeeksforGeeks](https://www.geeksforgeeks.org/typedef-in-c/) - [C 語言 - 程式設計教學:如何使用列舉 - ](https://opensourcedoc.com/c-programming/enumeration/) ## Pointers Pointers store address of variables or a memory location. ```c int *ptr; ``` ### Ampersand & To access address of a variable to a pointer, we use the unary operator & (ampersand) that returns the address of that variable. ```c= int x = 2; printf("%d", x); printf("%p", &x); ``` ### Asterisk * - To access the value stored in the address we use the unary operator (*) that returns the value of the variable located at the address specified by its operand. ```c= int Var = 10; int *ptr = &Var; printf("Value of Var = %d\n", *ptr); printf("Address of Var = %p\n", ptr); *ptr = 20; printf("After doing *ptr = 20, *ptr is %d\n", *ptr); ``` ### Pointer to array ```c= int main() { int v[5] = {1, 2, 3, 4, 5}; int* v_ptr = v; int (*v_array_ptr)[5] = &v; printf("v_ptr : %p\n", v_ptr); printf("v_ptr + 1 : %p\n", v_ptr + 1); printf("v_array_ptr : %p\n", v_array_ptr); printf("v_array_ptr + 1 : %p\n", v_array_ptr + 1); for(int i = 0; i < 5; i++) printf("%d ", *(v + i)); printf("\n"); for(int i = 0; i < 5; i++) printf("%d ", (*v_array_ptr)[i]); } ``` ```c= int main() { int num[3][4] = {{2, 3, 1, 5}, {1, 4, 6, 7}, {5, 6, 3, 1}}; int counter = 0; printf("num = %p\n", num); printf("num[0] = %p\n", num[0]); printf("num[0][0] = %p\n", &num[0][0]); for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) printf("%d ", *(num[i] + j)); printf("\n"); } printf("\n"); for(int i = 0; i < 3; i++) { for(int j = 0; j < 4; j++) printf("%d ", *(*(num + i) + j)); printf("\n"); } } ``` ```c= int main() { int** a = (int**) malloc(sizeof(int*) * 3); for(int i = 0; i < 4; i++) a[i] = (int*) malloc(sizeof(int) * 2); printf("a[0][0] = %d\n", &a[0][0]); printf("a[0][1] = %d\n", &a[0][1]); printf("a[1][0] = %d\n", &a[1][0]); printf("a[2][0] = %d\n", &a[2][0]); } ``` ref: - [Day-28 Pointer, A Pointer of A Pointer, Function Pointer](https://ithelp.ithome.com.tw/articles/10308649) ## Functions ```c= int myFunction(int x, int y) { return x + y; } int main() { int result = myFunction(5, 3); printf("Result is = %d", result); return 0; } ``` ```c= // Function declaration int myFunction(int, int); // The main method int main() { int result = myFunction(5, 3); // call the function printf("Result is = %d", result); return 0; } // Function definition int myFunction(int x, int y) { return x + y; } ``` ### Call (Pass) by value ```c= void setNum(int* num2) { printf("before setting, num2: %d\n", *num2); *num2 = 5; printf("after setting, num2: %d\n", *num2); } int main() { int num1 = 2; printf("before setNum(), num1: %d\n", num1); setNum(&num1); printf("after setNum(), num1: %d\n", num1); } ``` ref: - [call by value, call by address, call by reference 差別在哪?](https://wayne265265.pixnet.net/blog/post/112556555-%E3%80%90%E6%95%99%E5%AD%B8%E3%80%91call-by-value%2C-call-by-address%2C-call-by-referenc) - [程式設計 微知識(八)C/C++ Call by value、Call by address、Call by reference](https://dotblogs.com.tw/Ace_Dream/2016/06/01/callbyvalue_callbyaddress_callbyreference) - [3](http://eportfolio.lib.ksu.edu.tw/~T093000170/blog?node=000000119) ### Function overloading ```c= int plusFuncInt(int x, int y) { return x + y; } double plusFuncDouble(double x, double y) { return x + y; } int main() { int myNum1 = plusFuncInt(8, 5); double myNum2 = plusFuncDouble(4.3, 6.26); printf("Int: %d\n", myNum1); printf("Int: %1f\n", myNum2); return 0; } ``` ## Static ### Static Variable Static variables have a property of preserving their value even after they are out of their scope! Hence, static variables preserve their previous value in their previous scope and are not initialized again in the new scope. ```c= #include <stdio.h> void func() { int a = 0; static int b = 0; printf("a = %d, b = %d\n", ++a, ++b); } int main() { for(int i = 0; i < 10; i++) func(); return 0; } ``` ### Static Function Static functions in C are functions that are restricted to the same file in which they are defined. The functions in C are by default global. If we want to limit the scope of the function, we use the keyword static before the function. Doing so, restricts the scope of the function in other files, and the function remains callable only in the file in which it is defined. first_file.c : ```c= /* first_file.c */ static int addition(int num1, int num2) { return (num1 - num2); } ``` second_file.c : ```c= /* second_file.c */ #include <stdio.h> #include "test.c" int main() { int num1, num2; printf("Enter two nos: "); scanf("%d %d", &num1, &num2); int sum = addition(num1, num2); printf("Sum is : %d", sum); return 0; } ``` ref: - [Day-27 C 語言, 變數範圍, volatile, inline](https://ithelp.ithome.com.tw/articles/10308388) - [Static Variables in C - GeeksforGeeks](https://www.geeksforgeeks.org/static-variables-in-c/) - [What is a Static Function in C? - SCALER Topics](https://www.scaler.com/topics/static-function-in-c/) ## Scope of variable ### const ### static ### volatile ### inline ### extern ref: - [Day-27 C 語言, 變數範圍, volatile, inline](https://ithelp.ithome.com.tw/articles/10308388) - [C語言語法](https://chenhh.gitbooks.io/parallel_processing/content/cython/c_syntax.html) - [C/C++ 中的 static, extern 的變數](https://medium.com/@alan81920/c-c-%E4%B8%AD%E7%9A%84-static-extern-%E7%9A%84%E8%AE%8A%E6%95%B8-9b42d000688f) ## C standard library (libc) ### limits.h | Macro | Value | Description | | ------ |:------ |:------------ | | INT_MIN | -2147483648 | Defines the minimum value for an int. | | INT_MAX | +2147483647 | Defines the maximum value for an int. | | | || ### time.h | Type | Item | Description | | ---- |:---- |:------------ | | Variable | time_t | This is a type suitable for storing the calendar time. | | Function | time_t time(time_t \*timer) | Calculates the current calender time and encodes it into time_t format. | || || #### Calculate program execution time. ```c #include <stdio.h> #include <time.h> int main() { time_t start = time(NULL); time_t stop = time(NULL); // main body of program comes here double duration = (double) difftime(stop, start); printf("%f \n", duration); return 0; } ``` ### string.h | Type | Item | Description | | ---- |:---- |:----------- | | Variable | size_t | This is the unsigned integral type and is the result of the sizeof keyword. | | Function | size_t strlen(const char\* str) | Computes the length of the string str up to but not including the terminating null character. | | Function | char\* strcpy(char\* dest, const char\* src) | Copies the string pointed to, by src to dest. | | Function | void\* memset(void\* str, int c, size_t n) | Copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str. | | Function | char\* strcpy(char\* dest, const char\* src) | Copies the string pointed to, by src to dest. | | Function | int strcmp(const char\* str1, const char\* str2) | Compares the string pointed to, by str1 to the string pointed to by str2. | | Function | int strncmp(const char\* str1, const char\* str2, size_t n) | Compares at most the first n bytes of str1 and str2. | | Function | void\* memset(void\* str, int c, size_t n) | Copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str. | | Function | void\* memcpy(void\* dest, const void\* src, size_t n) | Copies n characters from src to dest. | | | | | | | | | | | | | | | | | ### stdlib.h | Type | Item | Description | | ---- |:---- |:----------- | | Function | void\* malloc(size_t size) | Allocates the requested memory and returns a pointer to it. | | Function | void free(void\* ptr) | Deallocates the memory previously allocated by a call to calloc, malloc, or realloc. | |||| ### ctype.h | Type | Item | Description | | ---- |:---- |:----------- | | Function | int isdigit(int c) | This function checks whether the passed character is decimal digit. | |||| ### assert.h | Type | Item | Description | | ---- |:---- |:----------- | | Macro | void assert(int expression) | This is actually a macro and not a function, which can be used to add diagnostics in your C program. | |||| ```c= #include <stdio.h> #include <assert.h> void print_number(int* myInt) { assert(myInt != NULL); printf("%d \n", *myInt); } int main () { int a = 10; int* b = &a; int* c = NULL; print_number(b); print_number(c); return 0; } ``` ref: - [C Library](https://www.tutorialspoint.com/c_standard_library/limits_h.htm) - [C library](https://www.cplusplus.com/reference/clibrary/) - [C/C++ strcpy 用法與範例](https://shengyu7697.github.io/cpp-strcpy/) ## Memory Layout A typical memory representation of a C program consists of the following sections. - Text segment (i.e. instructions) - Initialized data segment - Uninitialized data segment (bss) - Heap - Stack ![](https://i.imgur.com/pnyO6G3.png) ![](https://i.imgur.com/qygRKtR.png) ### Text segment A text segment, also known as a code segment or simply as text. - One of the sections of a program in an object file or in memory, which contains executable CPU instructions. - As a memory region, a text segment may be placed below the heap or stack in order to prevent heaps and stack overflows from overwriting it. - Usually, the text segment is sharable so that only a single copy needs to be in memory for frequently executed programs, such as text editors, the C compiler, the shells, and so on. - The text segment is often read-only, to prevent a program from accidentally modifying its instructions. ### Initialized data segment This section stores some initialized variables, such as initialized C language global variables and static variables. The variables in this section can be divided into read-only area and read-write area. - read-only area: const char* string = “hello world” - read-write area: the global string defined by char s[] = “hello world” in C, a C statement like int debug=1 outside the main (i.e. global) , the character pointer variable string ### Uninitialized data segment (bss) This section store global and static variables that have not been initialized, and these variables will be initialized to 0 or null by the system before the program is executed. ### Heap The memory space of the heap segment is used to store dynamically configured variables, such as the variables created by malloc in C language and new in C++ are stored here. The general situation of stacked regions grows from high memory addresses to low memory addresses, and the heap just grows from the opposite side in the opposite direction. ### Stack The stack segment is used to store the local variables of the function and the information that needs to be stored when calling various functions (such as the memory address returned by the function and the state of the caller function, etc.). Each function call will create a stack frame in the stack section to store all the variables and states of the call. In this way, when the same function is called repeatedly, there will be different stack frames without interfering with each other. The recursive function is executed through such a mechanism. ref: - [C 語言程式的記憶體配置概念教學](https://blog.gtwang.org/programming/memory-layout-of-c-program/) - [Memory Layout of C Programs - GeeksforGeeks](https://www.geeksforgeeks.org/memory-layout-of-c-program/) ## Compilation with gcc Compilation allow you to switch from a source code from an executable file. The compilation process has four steps: - preprocessing - compiling - assembling - linking 1) Preprocessor - Removes the comments from the source code - Includes Header files - Replaces macro name by values 2) Compiler The compiler takes the preprocessed file and translates it into assembly code. 3) Assembler The assembler transforms the assembly code into object code, that is code in machine language. 4) Linker The linker connects any libraries, and other C files of the same project into one executable file. ![](https://i.imgur.com/z7cKdTX.png) ref: - [The steps of compilation with gcc… - Medium](https://medium.com/@joel.dumortier/the-steps-of-compilation-with-gcc-60661f66890e) - [Day2.程式運行的基本概念(預處理、編譯、組譯、鏈結)](https://ithelp.ithome.com.tw/articles/10264510?sc=rss.iron) - [C 語言 程式設計教學:如何使用巨集 (macro) 或前置處理器 (Preprocessor)](https://opensourcedoc.com/c-programming/preprocessor/) - [程式設計師的自我修養〈編譯和連結〉](http://jasonchiucc.github.io/2016/09/08/program-self-cultivation-ch2/) - [淺談 c++ 編譯到鏈結的過程](https://medium.com/@alastor0325/https-medium-com-alastor0325-compilation-to-linking-c07121e2803) - [C/C++ 中的 static, extern 的變數](https://medium.com/@alan81920/c-c-%E4%B8%AD%E7%9A%84-static-extern-%E7%9A%84%E8%AE%8A%E6%95%B8-9b42d000688f) ## Preprocessor ### #define ```C= #define MUX(a, b) a * b #define square(x) x * x int main() { printf("%d \n", MUX(10 + 5, 10 - 5)); printf("%d \n", square(3 + 2)); return 0; } ``` ### #ifndef, #endif There two purposes in C. 1. Use ifndef in C language to protect the header file from being included multiple times ```c= #include <stdio.h> #ifndef MY_GUARD #define MY_GUARD 1 #define PER(D) #D #define JOIN(A,B) (A ## B) #define JOINX(A,B) JOIN(A,B) int power(int base, int n) { int p = base; for (size_t i = 0; i < n; i++) { p *= base; } return p; } #endif int main() { printf("%d \n", power(3, 5)); return 0; } ``` 2. Use the ifndef directive to ensure that macros are not defined multiple times in C ```c= #include <stdio.h> #ifndef PI #error First include then compile #else int main() { float a = 1000.999; printf("b = %f\n", a); } #endif ``` ```c= #include <stdio.h> #define PI 3.14159 #ifndef PI #error First include then compile #else int main() { float a = 1000.999; printf("b = %f\n", a); } #endif ``` ### #error The #error preprocessor directive indicates error. The compiler gives fatal error if #error directive is found and skips further compilation process. ```c= #include <stdio.h> #ifndef PI #error First include then compile #else int main() { float a = 1000.999; printf("b = %f\n", a); } #endif ``` ```c= #include <stdio.h> #define PI 3.14159 #ifndef PI #error First include then compile #else int main() { float a = 1000.999; printf("b = %f\n", a); } #endif ``` ref: - [c語言-關於#define用法](https://icodding.blogspot.com/2018/05/c-define.html) - [#ifndef.#define, #endif 的用法 - Medium](https://medium.com/@nickhuang_1199/ifndef-define-endif-%E7%9A%84%E7%94%A8%E6%B3%95-c7d33d6b1d47) - [頭文件重複包含和變量重複定義 - CSDN](https://blog.csdn.net/u014557232/article/details/50354127) - [C 語言中的 #ifndef - DelftStack](https://www.delftstack.com/zh-tw/howto/c/ifndef-in-c/) - [C語言#error指令](https://www.1ju.org/cprogramming/c-preprocessor-error) - [C #error - Javatpoint](https://www.javatpoint.com/c-preprocessor-error) ## Volatile Combining Const and Volatile ref: - [Introduction To The Volatile Keyword In C/C++](https://www.embedded.com/introduction-to-the-volatile-keyword/) - [How to Use C's volatile Keyword](https://barrgroup.com/embedded-systems/how-to/c-volatile-keyword) - [C/C++中的volatile使用時機?](https://freestyler.pixnet.net/blog/post/23872864) - [Day-27 C 語言, 變數範圍, volatile, inline](https://ithelp.ithome.com.tw/articles/10308388) - [C/C++ - Const與Volatile及同時存在狀況](https://gaexp251546.pixnet.net/blog/post/67510755) ## Inline function ![](https://i.imgur.com/rSQURpS.png) - [inline 函式](https://openhome.cc/Gossip/CGossip/InlineFunction.html) - [C - Compiler - Inline、Function、Macro 秒懂神解釋](https://tech.gjlmotea.com/2020/07/ccompilerinlinefunctionmacro.html) - [C++ 內嵌函數(inline function)筆記](https://dotblogs.com.tw/v6610688/2013/11/27/introduction_inline_function) - [面試 - C++ Inline Function & Macro差異](https://medium.com/%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E7%9A%84%E8%B5%B7%E9%BB%9E-%E9%82%81%E5%90%91%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E7%85%89%E9%87%91%E8%A1%93%E5%B8%AB%E4%B9%8B%E8%B7%AF/%E9%9D%A2%E8%A9%A6-c-inline-function-macro%E5%B7%AE%E7%95%B0-b51d7bc9c4e1) ## TBD ### In C language, non-zero(False) is equal to 1(True) ref: [W3schools](https://www.w3schools.com/c/index.php)