# C Note ## Header - Some useful functions are provided by this file - use "#include" to import header file - .h is the file extension for header file #### Example ```c= #include <stdio.h> // provide some function like: printf(), scanf() ``` Actually, it is legal to compile code without including any header ```c= int main() { int a = 0, b = 1; int sum; sum = a + b; } // In this case, using scanf() or printf() is not allowed // because we don't include <stdio.h>. ``` ## A Simple Code Structure ```c= #include <stdio.h> // include header file // main function: compiler will run your code from this function int main() { // declaration int a, b, sum; // input scanf("%d %d", &a, &b); // operation sum = a + b; // output printf("%d\n", sum); // return return 0; } ``` ## Variable - Something with a specific name and type that can store value - ***Please assign meaningful name to variables*** - ***Note that all types of variables are numbers but with different size of memory*** - 1 byte = 8 bits - There are some basic variable type defined by C as below. ### int - Name: integer - Size: 4 bytes - Format specifier: %d ### long long - Name: long integer - Size: 8 bytes - Format specifier: %lld ### char - Name: character - Size: 1 bytes - Format specifier: %c - Encode by ASCII: [ASCII - 維基百科,自由的百科全書](https://zh.wikipedia.org/zh-tw/ASCII) ### float - Name: float number - Size: 4 bytes - Format specifier: %f ### double - Name: double float number - Size: 8 bytes - Format specifier: %lf ### usigned - Name: nonnegative integer - Size: 4 bytes - Format specifier: %u ### pointer - Name: pointer - Size: 4 bytes - Format specifier: %p ### Example ```c= #include <stdio.h> int main() { int a = 1; long long b = 2; char c = 'A'; float d = 2.3; double e = 4.5; unsigned f = -1; printf("%d, %lld, %c, %f, %lf, %u\n", a, b, c, d, e, f); } // output: 1, 2, A, 2.300000, 4.500000, 4294967295 ``` ### Global Variables / Local Variables - Global Variables: variables declared outside functions and loops, which can be accessed by all functions and loops - Local Variables: variables declared inside functions or loops, which can only be accessed by some functions and loops ```c= #include <stdio.h> int globalVariable; int main() { int localVariable; } ``` --- ### Reference [Data Types in C](https://www.geeksforgeeks.org/data-types-in-c/?ref=lbp) ## Format String ### Intro Format string is a type of string with some notation in it in order to make this string like a template, which help us input or output something formatted. For example: ```c= #include <stdio.h> int main() { char h[6] = "hello"; char w[6] = "world"; printf("h is %s.\n", h); printf("w is %s.\n", w); } // output: h is hello. // w is world. ``` ### Format Specifier It is a notation that tell the computer what it should regard this variable as. For example: ```c= #include <stdio.h> int main() { int a = 48; printf("As an integer, a is %d.\n", a); printf("As a character, a is %c.\n", a); printf("%c + %d = %d\n", a, a, a); } // output: As an integer, a is 48. // As a character, a is 0. // 0 + 48 = 48 // Note that in ASCII code table, '0' is 48. ``` #### Basic Format Specifier For Different Types of Variables | int | char | string | float | long long | double | usigned | |:---:|:----:|:------:|:-----:|:---------:|:------:|:-------:| | %d | %c | %s | %f | %lld | %lf | %u | --- ### Reference [printf() 格式字串的使用方法](https://dev.to/codemee/printf-ge-shi-zi-chuan-de-shi-yong-fang-fa-n8f) ## Output ### printf() Why is printf() called printf() instead of printl() or printj()? Because "f" means format, printf() means print something formatted. How do we use it? ```c= printf(format string, variable1, variable2, ...); ``` #### Example ```c= #include <stdio.h> int main() { printf("Zero is %d.\nOne is %d.\n", 0, 1); } // output: Zero is 0. // One is 1. ``` ### putchar() A function to output character. ```c= #include <stdio.h> int main() { putchar('a'); putchar(' '); putchar(48); } // output: a 0 // Recall that all types of variables are numbers. // In ASCII code, '0' is 48. ``` ## Input ### scanf() It is similar to printf(), but it is for input. ```c= scanf(format string, address of variable1, address of variable2, ...); ``` #### Example ```c= #include <stdio.h> int main() { int a, b; scanf("%d %d", &a, &b); // & is used to get variable's address printf("%d %d\n", a, b); } // input: 12 13 // output: 12 13 ``` ### getchar() Same as scanf("%c"). ```c= #include <stdio.h> int main() { char c = getchar(); putchar(c); } // input: ABC // output: A ``` ### gets() / fgets() If we want to get an input string with space, we can use these two functions. --- ### Reference [fgets函數及其用法,C語言fgets函數詳解](https://tw511.com/a/01/1045.html) ## Operators ### Mathematical Operators #### + : add ```c= #include <stdio.h> int main() { int a = 20, b = 3; printf("%d\n", a + b); } // output: 23 ``` #### - : subtract ```c= #include <stdio.h> int main() { int a = 20, b = 3; printf("%d\n", a - b); } // output: 17 ``` #### * : multiply ```c= #include <stdio.h> int main() { int a = 20, b = 3; printf("%d\n", a * b); } // output: 60 ``` #### / : devide ```c= #include <stdio.h> int main() { int a = 20, b = 3; printf("%d\n", a / b); } // output: 6 ``` #### % : mod ```c= #include <stdio.h> int main() { int a = 20, b = 3; printf("%d\n", a % b); } // output: 2 ``` ### Comparison Operators #### == : equal ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a == b, b == c); } // output: (0, 1) ``` #### != : not equal ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a != b, b != c); } // output: (1, 0) ``` #### < : less than ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a < b, b < c); } // output: (1, 0) ``` #### > : more than ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a > b, b > c); } // output: (0, 0) ``` #### <= : no more than ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a <= b, b <= c); } // output: (1, 1) ``` #### >= : no less than ```c= #include <stdio.h> int main() { int a = 10, b = 20, c = 20; printf("(%d, %d)\n", a >= b, b >= c); } // output: (0, 1) ``` ### Bitwise Operators Regard each number in binary #### & : AND ##### Value table | AND | 1 | 0 | |:-----:|:---:|:---:| | **1** | 1 | 0 | | **0** | 0 | 0 | ```c= #include <stdio.h> int main() { int a = 0, b = 1, c = 3; printf("(%d, %d)\n", a & b, b & c); } // output: (0, 1) // In binary, a is 00000000, b is 00000001 and c is 00000011. // In binary, 0 is 00000000 and 1 is 00000001. ``` #### | : OR ##### Value table | OR | 1 | 0 | |:-----:|:---:|:---:| | **1** | 1 | 1 | | **0** | 1 | 0 | ```c= #include <stdio.h> int main() { int a = 0, b = 1, c = 3; printf("(%d, %d)\n", a | b, b | c); } // output: (1, 3) // In binary, a is 00000000, b is 00000001 and c is 00000011. // In binary, 1 is 00000001 and 3 is 00000011. ``` #### ^ : XOR ##### Value table | XOR | 1 | 0 | |:-----:|:---:|:---:| | **1** | 0 | 1 | | **0** | 1 | 0 | ```c= #include <stdio.h> int main() { int a = 0, b = 1, c = 3; printf("(%d, %d)\n", a ^ b, b ^ c); } // output: (1, 2) // In binary, a is 00000000, b is 00000001 and c is 00000011. // In binary, 1 is 00000001 and 2 is 00000010. ``` #### ~ : one's complement Ex: 101101 -> 010010 ```c= #include <stdio.h> int main() { int a = 1, b = 2; printf("(%d, %d)\n", ~a, ~b); } // output: (-2, -3) // In binary, a is 00000001 and b is 00000010. // In binary, -2 is 11111110 and -3 is 11111101. ``` #### << : left shift ```c= #include <stdio.h> int main() { int a = 3; printf("%d\n", a << 2); } // output: 12 // In binary, a is 00000011. // In binary, 12 is 00001100. ``` #### >> : right shift ```c= #include <stdio.h> int main() { int a = 12; printf("%d\n", a >> 2); } // output: 3 // In binary, a is 00001100. // In binary, 3 is 00000011. ``` ### Assign #### = : assign ```c= #include <stdio.h> int main() { int a; printf("%d\n", a = 2); } // output: 2 ``` #### += : add asign ```c= a += 1 is equal to a = a + 1 ``` ```c= #include <stdio.h> int main() { int a = 0, b = 0; a + 1; b += 1; printf("(%d, %d)\n", a, b); } // output: (0, 1) ``` #### we can also use -=, *=, /=, &=, |=... as above ### Logical Operators Note that 0 is false and other numbers are true. Default value for true and false are 1 and 0 repectively. #### && : logic AND ##### Truth table | AND | true | false | |:---------:|:-----:|:-----:| | **true** | true | false | | **false** | false | false | ```c= #include <stdio.h> int main() { int a = 0, b = 3; printf("%d\n", a && b); } // output: 0 ``` #### || : logic OR ##### Truth table | OR | true | false | |:---------:|:----:|:-----:| | **true** | true | true | | **false** | true | false | ```c= #include <stdio.h> int main() { int a = 0, b = 3; printf("%d\n", a || b); } // output: 1 ``` #### ! : logic NOT ```c= #include <stdio.h> int main() { int a = 0, b = 3; printf("(%d, %d)\n", !a, !b); } // output: (1, 0) ``` ### ++ / -- -- #### Intro It is same as += 1 / -= 1. However, it can be place before a variable or after a variable with different usage. **After a variable** Read the value before ++ / -- -- ```c= #include <stdio.h> int main() { int a = 0; while (a < 5) printf("%d ", a++); printf("\n"); } // output: 0 1 2 3 4 ``` **Before a variable** Read the value after ++ / -- -- ```c= #include <stdio.h> int main() { int a = 0; while (a < 5) printf("%d ", ++a); printf("\n"); } // output: 1 2 3 4 5 ``` ## if / else ### Intro We can use if / else to do something in specific condition. ```c= if (condition) { TODO } else if (condition) { TODO } . . . else { TODO } ``` ### Example ```c= #include <stdio.h> int main() { int a = 4; if (a > 4) { printf("a > 4\n"); } else if (a < 4) { printf("a < 4\n"); } else { printf("a == 4\n"); } } // output: a == 4 ``` If there is only a single line expression after if / else, we can omit { } ```c= #include <stdio.h> int main() { int a = 4; if (a > 4) printf("a > 4\n"); else if (a < 4) printf("a < 4\n"); else printf("a == 4\n"); } // output: a == 4 ``` ## switch ### Intro Similar to if / else, but it is faster. ***"break" is very important*** ```c= switch(parameter) { case constant1: TODO break; case constant2: TODO break; . . . default: TODO break; } ``` ### Example ```c= #include <stdio.h> int main() { int a = 4; switch(a) { case 2: printf("two\n"); break; case 4: printf("four\n"); break; default: printf("default\n"); } } // output: four ``` If we omit "break", it will be like below: ```c= #include <stdio.h> int main() { int a = 4; switch(a) { case 2: printf("two\n"); case 4: printf("four\n"); default: printf("default\n"); } } // output: four // default ``` ## ? : Expression ### Intro ```c= condition ? TODO_if_true : TODO_if_false; ``` ### Example ```c= #include <stdio.h> int main() { int a = 1, b = 0; printf("%d\n", a + b ? a : b); } // output: 1 ``` ## Loop ### Intro We can use loop to implement some repeated operations inorder to simplify our code. ### While Loop If the present condition fits in the loop condition you set up, then while loop will run again and again. Otherwise, it will stop. ```c= while (loop condition) { TODO } ``` #### Example ```c= #include <stdio.h> int main() { int i = 0; while (i < 5) { printf("%d ", i); i++; } } // output: 0 1 2 3 4 ``` ### For Loop It is similar to while loop. In addition, we can set initial value and some operations that computer will automatically do them after each loop. ```c= for (initial value; loop condition; operation after each loop) { TODO } ``` #### Example ```c= #include <stdio.h> int main() { for (int i = 0; i < 5; i++) { printf("%d ", i); } } // output: 0 1 2 3 4 ``` If there is only a single line expression after for / while, we can omit { } ```c= #include <stdio.h> int main() { for (int i = 0; i < 5; i++) printf("%d ", i); } // output: 0 1 2 3 4 ``` ### break Jump out of the loop immediately ```c= #include <stdio.h> int main() { for (int i = 0; i < 5; i++) { if (i == 3) break; printf("%d\n", i); } } // output: 0 // 1 // 2 ``` ### continue Jump into next loop immediately ```c= #include <stdio.h> int main() { for (int i = 0; i < 5; i++) { if (i == 3) continue; printf("%d\n", i); } } // output: 0 // 1 // 2 // 3 ``` ## Array A sequence that can store several value of the same type ### Declaration - Index start with 0 ```c= type array_name[length] = {element0, element1, ...}; ``` #### Example ```c= int int_arr[10] = {0}; char str[10] = {'\0'}; void* ptr[10] = {NULL}; // and so on... ``` ### Initialization All element will be set to 0 automatically only if declaring array as global variable. If we initialize some elements of an array, the other elements will be set to 0. #### Example ```c= #include <stdio.h> int global_arr[5]; int main() { int local_arr_init[5] = {1, 2, 3}; int local_arr_Noinit[5]; for (int i = 0; i < 5; i++) printf("%d ", global_arr[i]); printf("\n"); for (int i = 0; i < 5; i++) printf("%d ", local_arr_init[i]); printf("\n"); for (int i = 0; i < 5; i++) printf("%d ", local_arr_Noinit[i]); printf("\n"); } // output: 0 0 0 0 0 // 1 2 3 0 0 // random value... ``` ### Access Specific Element - We use [ ] to access specific element - Index starts with 0 ```c= array_name[index] ``` #### Example ```c= #include <stdio.h> int main() { int arr[3] = {0, 1, 2}; for (int i = 0; i < 3; i++) { printf("%d ", arr[i]); } } // output: 0 1 2 ``` ### Fibonacci Sequence Note that Fibonacci sequence: $a_n = a_{n-1} + a_{n-2}$ ; $a_{1} = a_{2} = 1$ #### Example ```c= #include <stdio.h> int main() { // declare int arr[10]; // give the initial value of Fibonacci sequence arr[0] = arr[1] = 1; // count each element of Fibonacci sequence for (int i = 2; i < 10; i++) { arr[i] = arr[i - 1] + arr[i - 2]; } // output for (int i = 0; i < 10; i++) { printf("%d", arr[i]); printf(i == 9 ? "\n" : " "); } } // output: 1 1 2 3 5 8 13 21 34 55 ``` ### 2D array ```c= type name[row_len][col_len] = { {Element00, Element01, ...}, {Element10, ...}, ... }; ``` | | Column 0 | Column 1 | | -------- | -------- | -------- | | **Row 0**| arr[0][0]| arr[0][1]| | **Row 1**| arr[1][0]| arr[1][1]| #### Example ```c= #include <stdio.h> int main() { int arr[5][5]; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { arr[i][j] = i * 10 + j; } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { printf("%02d", arr[i][j]); printf(j == 4 ? "\n" : " "); } } } // ij ij ij ij ij // -------------- // output: 00 01 02 03 04 // 10 11 12 13 14 // 20 21 22 23 24 // 30 31 32 33 34 // 40 41 42 43 44 ``` ## Function Actually we have learned it before in the beginning. ```c= #include <stdio.h> // declare the function called "main" int main() { printf("hello world!\n"); // call the function called "printf()" } // output: hello world! ``` ### Declaration Note that we can also pass no parameter into function like what we do to main function. ```c= return_type function_name(parameter1, parameter2, ...) { TODO return; // depend on your return_type } ``` ### Call Function ```c= function_name(parameter1, parameter2, ...); ``` #### Example ```c= #include <stdio.h> // times 10 int MulBy10(int para) { return para * 10; } int main() { int a = 2; a = MulBy10(a); printf("%d\n", a); } // output: 20 ``` ### Daclaration Order Problem... #### An Error Example ```c= #include <stdio.h> // count doesn't know who are add and minus. // This causes an error. int count(int op, int a, int b) { if (op == 1) return add(a, b); else return minus(a, b); } int add(int a, int b) { return a + b; } int minus(int a, int b) { return a - b; } int main() { int op, a, b; scanf("%d %d %d", &op, &a, &b); printf("%d\n", count(op, a, b)); } ``` ***Recommend that declare the function first and then write the implement below*** #### Solution ```c= #include <stdio.h> // Declare functions first. int count(int op, int a, int b); int add(int a, int b); int minus(int a, int b); int main() { int op, a, b; scanf("%d %d %d", &op, &a, &b); printf("%d\n", count(op, a, b)); } // Write functions' implement below int count(int op, int a, int b) { if (op == 1) return add(a, b); else return minus(a, b); } int add(int a, int b) { return a + b; } int minus(int a, int b) { return a - b; } ``` ### Pass Value? Pass Address? Let's look at the example below ```c= #include <stdio.h> void add(int a, int b); int main() { int x = 2, y = 3; add(x, y); printf("x = %d\n", x); } void add(int a, int b) { a += b; printf("a = %d\n", a); } // output: a = 5 // x = 2 ``` You may wonder why x's value doesn't change after running add function. For this example, we only pass the values of x and y to the add function. The compiler copies the value of x to a and the value of y to b, and then assign a + b to a. For this example, we can regard it as below: ```c= #include <stdio.h> int main() { int x = 2, y = 3; int a = x, b = y; a += b; printf("a = %d\n", a); printf("x = %d\n", x); } // output: a = 5 // x = 2 ``` So how do we deal with this problem? Here are two ways to solve it. - **Solution 1:** Use global variables (Recommend if you don't know pointer) ```c= #include <stdio.h> int x = 2, y = 3; void add(); int main() { add(); printf("x = %d\n", x); } void add() { x += y; printf("x = %d\n", x); } // output: x = 5 // x = 5 ``` - **Solution 2:** Use pointer ```c= #include <stdio.h> void add(int* a, int* b); int main() { int x = 2, y = 3; add(&x, &y); // use & can get the variable's address printf("x = %d\n", x); } void add(int* a, int* b) { *a += *b; // use * can get the pointer's value printf("a = %d\n", *a); } // output: a = 5 // x = 5 ``` ## Recursion ### Intro A function calls itself again and again. ![](https://hackmd.io/_uploads/rJjn8jzdn.png) ### Example ```c= #include <stdio.h> void func_f(int a) { if (a > 0) func_f(a - 1); printf("%d ", a); } int main() { func_f(5); } // output: 0 1 2 3 4 5 ``` ### Count factorial Note that $n! = n(n-1)(n-2)... 2*1$ ```c= #include <stdio.h> int countFactorial(int a) { if (a <= 1) return 1; // stop condition return a * countFactorial(a - 1); // call itself recursively } int main() { printf("%d\n", countFactorial(5)); } // output: 120 // Note that 5 * 4 * 3 * 2 * 1 == 120 ``` ### Fibonacci sequence Note that Fibonacci sequence: $a_n = a_{n-1} + a_{n-2}$ ; $a_{1} = a_{2} = 1$ ```c= #include <stdio.h> int rec(int a, int b, int k); int main() { int k = 10; printf("arr[%d] = %d\n", k, rec(0, 1, k)); } int rec(int a, int b, int k) { if (k == 1) return b; // stop condition return rec(b, a + b, k - 1); // call itself recursively } // output: arr[10] = 55 ``` ### Prefix Calculator What is prefix calculator? If we put operator to the front, and we call it prefix expression For example: (1 + 2) * 4 => * + 1 2 4 ![](https://hackmd.io/_uploads/Skpu9EQuh.png) ```c= #include <stdio.h> int count() { char c; scanf("%c", &c); if (c == '+') return count() + count(); if (c == '-') return count() - count(); if (c == '*') return count() * count(); if (c == '/') return count() / count(); return c - '0'; } int main() { printf("%d\n", count()); } // input: *+124 // output: 12 ``` ### Minimum Step Given a maze with '#', '.', 'S', 'E'. '#': wall '.': path 'S': start point 'E': end point Please count the minimum steps to reach the end point from the start point. **Input** First row will have two integer H, W, which means the height and the width of the map repectively. And then there will be H rows, W columns characters with only '#', '.', 'S', 'E'. It guarantees that the maze will be surrounded by '#'. 5 <= H, W <= 100000 **Output** Please output the minimum steps from 'S' to 'E'. Please output '\n' in the end. **Sample Input** ```= 6 7 ####### ##S...# #...#.# #.##E.# #.....# ####### ``` **Sample Output** ```= 6 ``` **Sample Code** ```c= #include <stdio.h> #include <limits.h> int R, C, Start[2], min_distance = INT_MAX; char map[10001][10001]; // 1 <= R, C <= 10000 void walk(int row, int col, int distance); int main() { // get the range of map scanf("%d %d", &R, &C); // get the map and the index of start for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { scanf(" %c", &map[i][j]); if (map[i][j] == 'S') { Start[0] = i; Start[1] = j; } } } // recursion walk(Start[0], Start[1], 0); // output printf("%d\n", min_distance == INT_MAX ? 0 : min_distance); } void walk(int row, int col, int distance) { // more than the result we count before if (distance > min_distance) return; // reach the end point if (map[row][col] == 'E') { min_distance = distance; return; } // try four directions for (int i = -1; i <= 1; i += 2) { for (int j = 0; j <= 1; j++) { if (map[row + i * j][col + i * (1 - j)] != '#') { map[row][col] = '#'; walk(row + i * j, col + i * (1 - j), distance + 1); map[row][col] = '*'; } } } } ``` ## Pointer A type of variables that store variable's ```c= #include <stdio.h> int main() { int a = 5; int* ptr = &a; printf("The value of a is %d.\n", a); printf("The address of a is %p\n", &a); printf("The value of ptr is %p\n", ptr); printf("The value store in %p is %d\n", ptr, *ptr); printf("The address of ptr is %p\n", &ptr); } // output: The value of a is 5. // The address of a is 0061FF1C // The value of ptr is 0061FF1C // The value store in 0061FF1C is 5 // The address of ptr is 0061FF18 ``` ## struct ### Intro We can use struct to define our own data types ```c= struct structure_name { // data }; ``` ### Example ```c= #include <stdio.h> struct _student { int number; int age; int height; }; int main() { struct _student s; // declaration s.number = 1; // use '.' to access specific data in the structure you defined s.age = 13; s.height = 176; printf("Number %d is %d years old and %d centimeters tall.\n", s.number, s.age, s.height); } // output: Number 1 is 13 years old and 176 centimeters tall. ``` ## typedef ### Intro Assign a name for a specific data type. ```c= typedef data_type_name your_own_name; ``` ### Example ```c= #include <stdio.h> typedef int Integer; typedef struct _node { int value; struct _node* next; } Node; int main() { Integer a = 5; Node n; n.value = 5; n.next = NULL; printf("%d, %d\n", a, n.value); } // output: 5, 5 ``` ## sizeof() ### Intro Get how many bytes a variable or a data type is ```c= sizeof(data_type); sizeof(variable_name); ``` ### Example ```c= #include <stdio.h> int main() { int a, arr[5]; printf("%d, %d, %d\n", sizeof(a), sizeof(arr), sizeof(int)); } // output: 4, 20, 4 ``` ## malloc() ### Intro Allocate memories with given size and return the head address back ```c= malloc(how_many_bytes_of_memories_you_want_to_allocate); ``` ### Example ```c= #include <stdio.h> #include <stdlib.h> int main() { int* ptr = (int*) malloc(sizeof(int)); *ptr = 20; printf("%d\n", *ptr); } // output: 20 ```