{"id":19524431,"url":"https://github.com/sepgh/remember-c","last_synced_at":"2026-06-30T15:32:11.016Z","repository":{"id":214720994,"uuid":"737202949","full_name":"sepgh/remember-c","owner":"sepgh","description":"A notebook to gather what I learn about C programming language in one place.","archived":false,"fork":false,"pushed_at":"2024-04-15T07:41:48.000Z","size":130,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-08T03:33:52.489Z","etag":null,"topics":["c"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sepgh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-30T06:57:56.000Z","updated_at":"2024-06-21T07:44:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"2cc1a649-f66a-47fe-911e-b30c7807fc19","html_url":"https://github.com/sepgh/remember-c","commit_stats":null,"previous_names":["sepgh/remember-c"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sepgh/remember-c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sepgh%2Fremember-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sepgh%2Fremember-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sepgh%2Fremember-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sepgh%2Fremember-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sepgh","download_url":"https://codeload.github.com/sepgh/remember-c/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sepgh%2Fremember-c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34973611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c"],"created_at":"2024-11-11T00:48:37.588Z","updated_at":"2026-06-30T15:32:10.991Z","avatar_url":"https://github.com/sepgh.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Remember C\n\nI'm very new to C programming language. Well, here I am trying to note down some concepts as I am learning them so that I remember them better (hopefully) :thinking:.\n\n\n## Intro\n\nSince I was familiar with programming (mostly in Java) the basic syntax of C wasn't hard to follow.\n\nThe playlist below was how I refreshed my memory of C syntax (plus introdution to `\u0026`address, `*`pointers and `struct`).\n\n[C Programming Tutorials - Caleb Curry](https://www.youtube.com/playlist?list=PL_c9BZzLwBRKKqOc9TJz1pP0ASrxLMtp2)\n\nNext playlist that I am going through right now is called [The C programming language made easy - Code Vault](https://www.youtube.com/watch?v=ypG9W33LOTk\u0026list=PLfqABt5AS4FmErobw8YyTwXDUE5nPH5lH\u0026index=1)\nI was introduced to the playlist when I wanted to learn more about memory management in C and I found it to be facinating.\n\nThere are more playlists that I will check out next (or maybe sooner), but of course I will skip what I already know. Here they are:\n\n- https://www.youtube.com/playlist?list=PLLh1tBHv1CiVpzohtrp7YCSpY9wlJxCQs\n- [Stanford University - C programming](https://www.youtube.com/playlist?list=PLjn3WmBeabPOUzxcCkzk4jYMGRZMZ6ylF)\n\n---\n\n## Custom Content\n\n### Decimal representation of a binary number\n\nGet a binary number as input (ex: `1001`) and print the decimal value (ex: `9`).\n\nFile: [binary_conversion.c](files/binary_conversion.c)\n\n[Hex to decimal](https://www.youtube.com/watch?v=pg-HEGBpCQk)\n\n\n### Header files\n\n__note__: `#inclue \u003csomething.h\u003e` works for external files and `#include \"something.h\"` works for local project files.\n\nIn a single compilation unit, all c files are compiled, so you can use a function from another c file in the file with `main` method. But then if you use `#include 'util.c'` it will try act as copying the content of that file into your current file, and as a result the function will be declared twice which results as a problem.\n\nHeader files only contain _signature_ of declaraions such as functions. Therefore when they are included in another file, they only define signature of functions and not implement them. This is the difference between declare and define. Declare means the signature is there, define means the implementation is there. Example:\n\n```c\n//Declare:\nvoid func(int a);\n\n//Define\nvoid func(int a){\n    return a + 1;\n}\n```\n\n#### Pragma once\n\nYou may see/use `#pragma once` or below code in a header file:\n\n```c\n#ifndef SOMEFILE_H\n#define SOMEFILE_H\n\n// code (declarations) here\n\n#endif\n```\n\nThis prevents the file to be redeclared, or better say this file will only be included once.\n\n\nVideo: https://www.youtube.com/watch?v=u1e0gLoz1SU\n\n\n#### Sharing functions between C files\n\nVideo: https://www.youtube.com/watch?v=8tRQ96W4g84\n\n\n### Macros\n\nReadings:  https://stackoverflow.com/questions/1358232   https://stackoverflow.com/questions/66618214/\n\nVideo: https://www.youtube.com/watch?v=JqN4uVgCTWE\n\n\n## Strings\n\n### Decleration\n\nBy using `char[]` we can later manipulate the characters of a string. But if we use `char*` the behaviour would be undetermined by C if we want to change it later (Segmentation fault). Another solution is to use `malloc` to use pointer.\n\nVideo: https://www.youtube.com/watch?v=gTXRfETK3z4\n\nFile: [string_1.c](files/string_1.c)  (misses `malloc` implementation cause I havent yet learned that completely :D)\n\n### String Array Declerations\n\nVideo: https://www.youtube.com/watch?v=ly66E_LGubk\n\nFile: [string_2.c](files/string_2.c) \n\n\n### String storage\n\nStrings are usually neither stored on heap or stack. They are stored in [Data Segments](https://en.wikipedia.org/wiki/Data_segment). Later we will see that creating a variable within a function and returning it, or pointing a pointer to a new variable within functions may not work on some data types, such as arrays (check [Arrays \u003e Returning an array from a function] section). But that doesn't apply to strings even though you may think its just a char array.\n\n[More info](https://stackoverflow.com/questions/4970823/)\n\n\n### String copy\n\nFunctions used: `strcpy` and `strncpy`\n\nImportance of the video: getting length of a string, having the `\\0` at end of strings and what happens if we don't pay attention to that.\n\nAdditinally it helps to copy strings in safe way. Basically, using `strncpy` we can pass `length of the string + 1` (`strlen(x) + 1`) to always assure that we allocate enough memory to the string we are copying into. Alternatively, we could always set last item of char array (string) to `\\0` for assurance.\n\nVideo: https://www.youtube.com/watch?v=R5Xk5N9-rno\nFile: [string_3.c](files/string_3.c)\n\n\n### Pointer assignment vs strcpy \n\nIf we assign value to a pointer (char pointer) - which had initial value using `malloc`- inside a function, the memory it's refering to will be deallocated after function exits, which means we can no longer get that value outside the function (in the example file, we can no longer print `str` in main function if we have used `str=example` in `process` function).\n\n\nVideo: https://www.youtube.com/watch?v=VQHK2EZZHb8\nFile: [string_4.c](files/string_4.c)\n\n\n### Comparing strings\n\nIntro to `strcpy` and `strncpy`. Additionally you can use `memcmp`.\n\n\nVideo: https://www.youtube.com/watch?v=Y4OABXkRSEA\nFile: [string_5.c](files/string_5.c)\n\n\n### Finding a character in a string (checking if character exists)\n\nIntro to `strchr` and `strrchr`. Additionally explains how to get the position of found character.\n\n**Fun point!** Both of these functions return pointer of the found character, and since a string is a \"contiguous\" array of characters, subtracting these pointer addresses will return you the position of which the character was found in a string.\n\n\nVideo: https://www.youtube.com/watch?v=SLUEfPKR91U\nFile: [string_6.c](files/string_6.c)\n\n\n### Finding words in a sentence\n\nIntro do `strstr`.\n\nVideo: https://www.youtube.com/watch?v=8A3Zycio0W4\nFile: [string_10.c](files/string_10.c)\n\n\n\n### Return a string from a function\n\nThe best way to do so is to allocate the memory of the string we \"expect to be returned\" before calling the function and pass the memory of that string to the function so it fills it.\n\nVideo: https://www.youtube.com/watch?v=A8IkGIqZoLQ\nFile: [string_7.c](files/string_7.c)\n\n\n### Splitting strings\n\nIntro to `strtok` (String token). Importance:\nThis function returns a char* to next occurrence of each piece. Also modifies the input (str) and adds \"String terminator character\" at each piece.\n\nVideo: https://www.youtube.com/watch?v=34DnZ2ewyZo\nFile: [string_8.c](files/string_8.c)\n\n\n### String parsing\n\nIntro to `sscanf` (different from `scanf`). Scans a string.\n\nVideo: https://www.youtube.com/watch?v=-7cSmcdMryo\nFile: [string_9.c](files/string_9.c)\n\nAdditional note: `scanf` is a family of functions in C that not only work from standard input from keyboard, it works with strings and files.\n\nAdditional note: `%s` reads anything until `\\n`, `space` or a tab. So we can't use `%s` (format specifier) for some cases in `sscanf`. Instead we can do something like `%[a-zA-Z ]` for example. If we want to read anything we can use `%[^]`.\n\nSame thing works with `scanf`, so `sscanf` is for scanning and parsing strings, and you could use `fscanf` to do the same with files and pass a \"file handle\".\n\n\n### String to number\n\nIntro to `strtol` and `strtof`. Read like `str  to  L` (long) or `str  to  F` (float). They return a number, but takes more parameters. Second parameter takes a pointer to set it to where it stopped reading the number. Third parameter is the base we want to read the number in.\n\nAlso, `atoi` is introduced, which is not the right way to do because: A) has undefined behavior if you try to convert a string larger than expected. B) Doesn't tell you when it stopped converting a number. C) Can't convert numbers from other bases (like base 16).\n\nVideo: https://www.youtube.com/watch?v=UQ5INK_pXCI\nFile: [string_11.c](files/string_11.c)\n\n\n### Parsing a string of numbers\n\nIntro to `strtol`, which takes out numbers (long int) from a string. It takes the string, the pointer of the string we are in, and the base we read the number in. If you use `0` as base it detects base-16 itself.\n\nVideo: https://www.youtube.com/watch?v=L8hVbPIVE0U\nSource:\n\n```c\n//char str[] = \"200, 22, 111 \";\nchar str[] = \"200, 0xf \";\nchar* cursor = str;\nlong int sum = 0;\nwhile (cursor != str + strlen(str)) {\n    // long int x = strtol(cursor, \u0026cursor, 10);\n    long int x = strtol(cursor, \u0026cursor, 0);\n    while (*cursor == ' ' || *cursor == ',') {\n        cursor++;\n    }\n    sum += x;\n}\nprintf(\"Sum is %ld\\n\", sum);\n```\n\n## Arrays\n\n### Iterating over an array using pointers\n\nIf we declare a pointer to the first element of an array (Example:  `int* p = \u0026arr[0]`), we can access the value using `*p`. But also, if we increment the pointer by the `sizeof` the array type (in this example, `int` which is 4 bytes) then we can get the next item in the array.\n\nVideo: https://code-vault.net/course/ar67avx6hk:1610029043923/lesson/qjp3te6iyf:1603733521836\n\n\n### Iterating main parts of a matrix\n\nVideo: https://code-vault.net/course/ar67avx6hk:1610029043923/lesson/rrpv5yuflb:1603733521478\n\n\n### Returning an array from a function\n\nAn array which is declared within a function can not be returnes since the memory is in the stack and is removed when the function exits. The right way to do it is either accept the array address as input, return void, and manipulate the array in the function, or use `malloc` and return the address of the array which then will require a call to `free` whenever the function is called.  This is the same practice from __Strings: Pointer assignment vs strcpy__ section.\n\nVideo: https://code-vault.net/course/ar67avx6hk:1610029043923/lesson/iyvrv54u8e:1603733520962\n\n\n### Difference between arrays and pointers\n\nVideo: https://www.youtube.com/watch?v=iSZLE9qPN14\n\n\n### Dynamically allocated arrays\n\nIntro to `calloc`. From man page:\n\n\u003e The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory.  The memory is set to zero.  If nmemb or size is 0, then calloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().  If the multiplication of nmemb and size would result in integer overflow,  then  calloc()  returns an error.  By contrast, an integer overflow would not be detected in the following call to malloc(), with the result that an incorrectly sized block of memory would be allocated:\n\u003e\n\u003e           malloc(nmemb * size);\n\nIf calloc returns NULL it means it failed to allocate the memory (maybe no memory was left for example). We can gracefully handle the error. Same principle applies to realloc (read below).\n\nIntro to `size_t`:\n\n\u003e size_t is a special unsigned integer type defined in the standard library of C and C++ languages. It is the type of the result returned by the sizeof and alignof operators. The size_t is chosen so that it can store the maximum size of a theoretically possible array or an object.\n\nVideo for `size_t`: https://www.youtube.com/watch?v=gWOeL1oymrc\n\nIntro to `realloc`, which gets a pointer and allocates a chunk of memory to it again. It may return a new pointer, since it may not just simply be able to expand the memory and have to move it.\n\n\nVideo: https://www.youtube.com/watch?v=6Ir4l0VuI7Y\n\n\n**Bonus**: Dynamically allocated multi-dimensional arrays!\n\nVideo: https://www.youtube.com/watch?v=-y8FUvRq_88\nFile: [array_1.c](files/array_1.c)\n\n\n### The address of an array\n\nMost important lesson: Arrays decay to a pointer whenever they are passed to a function.\n\nVideos: https://www.youtube.com/watch?v=ToPkRyNOBZ8 | https://www.youtube.com/watch?v=pBPrWFhVNL4\n\n\n### Passing arrays to a function (tricky with multidimensional arrays)\n\nVideo: https://www.youtube.com/watch?v=Cfm4D_Mxpiw\nFile: [array_2.c](files/array_2.c)\n\n\n## Void pointer\n\nImagine we have a function that takes in \"an int array\" and \"int of length of the array\" to represent each array element in hex format. How can we modify this function to accept other types like `long long` or `short` instead of only `int array`.\n\nVideo: https://www.youtube.com/watch?v=k3DbBOZRvRs\n\nFile: [void_pointers.c](files/void_pointers.c)\n\nImportant note:  if you convert int array to char array (for example), the conversion is a byte conversion. An int is 4 bytes while a char is 1 byte. So if `int_arr[0]` is `64`, the converted `char_arr` will have `char_arr[0], char_arr[1], char_arr[2], char_arr[3]` to hold all of the values, and in this case only `char_arr[0]` will have a value.\n\nThats why in the above file if we want to present hexadeimal of an integer, we use `%08x` since each byte requires 2 hexadecimal spaces to be shown and we have 4 bytes. But after we convert the `int` or `long long` array to `char` array (through accepting it using `void*`) then to represent char array using hexadecimal we use `%02` since a char is single byte.\n\nFile: [void_pointers_2.c](files/void_pointers_2.c)\n\nBonus videos:\n\n- https://www.youtube.com/watch?v=t7CUti_7d7c\n\n## Functions\n\n### Func Pointers\n\nVideo: https://www.youtube.com/watch?v=ewBBRaF0oEA\nFile: [function_1.c](files/function_1.c)\n\n\n## Data types\n\n### typedef\n\nUsing `typedef` you can define a name for a data type. It can be a data type you create (like struct) or even built in types.\n\nVideo: https://www.youtube.com/watch?v=9guJVmDyFmE\nFile: [data_type_1.c](files/data_type_1.c)\n\n\n### Defining a data type (struct)\n\nExample:\n\n```c\ntypedef struct Point {\n    double x;\n    double y;\n} Point;\n\nint main(int argc, char* argv[]) {\n    Point p = {\n        .x = 0.25,\n        .y = 0.78\n    };\n    \n    printf(\"%lf %lf\\n\", p.x, p.y);\n    \n    return 0;\n}\n```\n\n**Important note:** even though struct is usually stored in a contiguous memory, the value of `sizeof(structInstance)` may not be equal to the sum of the struct attributes.\nThis has to do with memory padding.\n\n### Return and pass a struct to a function\n\n1. Passing struct to a function is pass-by-value (copy), which is not optimized.\n2. As solution for 1, arguments can accept pointers to the structs.  `void x(Point* p)`\n3. To prevent modification, arguments can also be set as `const`.  `void x(const Point* p)`\n4. Accessing struct attributes when passed as a pointer needs `-\u003e` instead of `.`. So: `p-\u003ex` over `p.x`.\n\nVideo: https://www.youtube.com/watch?v=XreVazVRQEI\n\n\n### Static\n\nThe `static` keyword makes variables be treated specially: To be initialized when program starts, and during execution don't reinitialize it, therefore it's value and state doesn't refresh when stack of a function is cleaned. **This is not a global variable though. They are accessible only in their own scope.**\n\nVideo: https://www.youtube.com/watch?v=OngGUoENgWo\nFile: [data_type_2.c](files/data_type_2.c)\n\n\n### Union\n\nInside a Union all the members share the exact same memory. It's a simple way to interprete exact same memory in different ways.\n\nVideo: https://www.youtube.com/watch?v=BFDUeEVxUok\nFile: [data_type_3.c](files/data_type_3.c)\n\n\n#### Bonus (Anonymous Unions)\n\nVideo: https://www.youtube.com/watch?v=ICbLwg0Pgz0\nFile: [data_type_4.c](files/data_type_4.c)\n\n\n### Integer type conversion\n\n\nWhen we are __extending__ the variables we take the 'sign bit' and copy it into everywhere we have to pad the larger variable. \nAnd when we are trying to assign a smaller variable a larger amount in size, we actually trim the first least significant bytes from the larger value.\n\nVideo: https://www.youtube.com/watch?v=am183PVCn7U\n\n\n### Enum\n\nIn C, the enum can only store signed int values. The int value of each enum element will be \"last value + 1\" if not defined, and if no elements have any value first one begins with 0.\n\nVideo: https://www.youtube.com/watch?v=lWzZ2l5n81c\n\n\n### Integer overflow and underflow\n\nVideo: https://www.youtube.com/watch?v=JNu_9U4qq8E\nFile: [data_type_5.c](files/data_type_5.c)\n\n\n### Infinite loop through integer overflow\n\nIf for optimizing loop index we choose a type which may overflow or underflow during the loop then we will enter an infinite loop.\n\nVideo: https://www.youtube.com/watch?v=uZf_5JQXoU8\n\n\n### Generic data type\n\n(Checkout 'Void pointer' section first)\n\nThere is actually no \"Generic type\" like in OOP languages. It's all about using `malloc` within a struct that keeps the type as an enum.\n\n\nVideo: https://www.youtube.com/watch?v=RG7D2_pay0U\nFile: [data_type_6.c](files/data_type_6.c)\n\n\n### Difference between macros and constants\n\nMacros are processed before compilation. Their value is literally replaced in the source code as if its like a text editor is replacing them.\n\nVideo: https://www.youtube.com/watch?v=TfJHlez7bek\nFile: [data_type_7.c](files/data_type_7.c)\n\n\n## File and Terminal IO\n\n### Reading input from terminal\n\nCan use `scanf`, but also `fgets` which accepts 3 parameters: \n\n1. the string we want to write into\n2. how many characters we accept\n3. where do we read from, which could be a file or `stdin` to read from terminal input\n\nVideo: https://www.youtube.com/watch?v=Lksi1HEMZgY\n\n\n### Printing a struct memory to console\n\nExample code:\n\n```c\nunsigned char data;\n    for (i = 0; i \u003c sizeof(t); i++) {\n        if (i % 4 == 0) {\n            printf(\"\\n\");\n        }\n        data = *(((unsigned char*) \u0026t) + i);\n        printf(\"%02x \", data);\n    }\n```\n\nVideo: https://www.youtube.com/watch?v=a3ropbfIpw4\n\n\n### Printf variants\n\nExamples:\n\n- `sprintf(buff, format string, args)`, example `sprintf(buf, \"Example\\n\");`: writes the formatted value into the buffer input (`char buffer[200]`)\n- `snprintf(buff, max, format string, args)`: which accepts the maximum size to write into buffer, in case format string is longer than buffer\n- `fprintf(stream, format string, args)`: writes to a stream, like a file or `stdout` or `stderr`\n- `fprintf_s(stream, format string, args)`: safer version, checks for NULL in args to prevent crash\n- `fwprintf_s(stream, format string, args)`: uses wide char for fstring\n- `vfprintf_s(stream, format string, list_args)`: accepts list of args (`va_list` type)\n\nActually these are prefixes before `printf` func:\n\n- `s` buffer\n- `n` buffer size\n- `f` stream (file)\n- `_s` safer version\n- `w` wide char\n- `v` var args list (va_list)\n\nVideo: https://www.youtube.com/watch?v=VA22ESilQO0\n\n\n### Binary representation of an Integer  (print in binary)\n\nVideo: https://youtu.be/Kj3iboADvUc?si=wuCvCqibsh07-uA-\nFile: [io_1.c](files/io_1.c)\n\n\n### File IO\n\n#### Write (basics)\n\nIn short, we use `FILE* out` to create a file pointer, and then using `fopen` or `fopen_s` we assign a handler to it. Then using `fwrite` function we can write a string buffer into that handler. To fill the buffer we can choose from _Printf variants_, like `sprintf_s`. Using `fclose` we can close the file.\n\nFile: [io_2.c](files/io_2.c)\nVideo: https://www.youtube.com/watch?v=da9D4Bcsrgc\n\nThe example file writes binary data into a file. Although, its only a string.\n\n#### Write in binary:\n\nThe handler needs to be called with `wb` flag, of course. Example: `fopen(\"point.bin\", \"wb\")`\n\nFile: [io_4.c](files/io_4.c)\nVideo: https://www.youtube.com/watch?v=P-fWNCF7Wx8\n\n#### Read (basics)\n\nPretty much like write in terms of opening and closing. We use `fgets` to read file content into a buffer. We can then use `sscanf` to format the buffer.\n\nFile: [io_3.c](files/io_3.c)\nVideo: https://www.youtube.com/watch?v=k3gSBljW-OE\n\n\n#### Read in binary\n\nLike normal reading but with `rb` flag. We can use `fread_s` to read binary data from the file. In the example, we pass the address of `p2` to `fread_s` which is a Point struct so the binary data is written there!\n\nFile: [io_5.c](files/io_5.c)\nVideo: https://www.youtube.com/watch?v=dDjfaA9Q3n8\n\n\n#### Read/Write improvements\n\nUsing `fprintf` and `fscanf` to reduce the need of extra buffers. Also using `w+` flag to open the file.\n\nFile: [io_6.c](files/io_6.c)\nVideo: https://www.youtube.com/watch?v=COypelJNUYY\n\n### fseek\n\nUsing fseek we can move the cursor where we start reading/writing into a file.\n\n\n### getc, getch, getche and getchar\n\nThese function reads a single character from console input.\n\n- `getch` doesnt print the character to the console. Returns an int so it can store `EOF`. Not a C standard function, and only compatibel with Windows. Also, no enter needed to send the character into console.\n- `getche` is same as `getch` but prints the character to console.\n- `getc` expects enter to be pressed. Its a macro on some platforms.\n- `getchar` equal to getc but works with `stdin` by default.\n- `fgetc` is like `getc` but its a function and not a macro.\n\n\n## Pointers and Memory management\n\n\n### Memory paddings\n\nPadding is something that is used to add a couple of bytes to the memory allocate so that the CPU can get it in a much faster way and in some cases don't give out errors.\n\nThe compiler tries to align every single address of every single element (element of a struct in this example) at 8 bytes. Because we dont want an element (a pointer for instance) to start in a 64 bit of a memory and end in another one, because while it may be more memory efficient, the CPU has to do more work by taking one byte into CPU and then another one and make them up together in order to find the value of that pointer. But when its aligned in the CPU architecture then it'll be easier.\n\nThis behavior can change by using `#pragma pack(1)` _before the line you want the alignment to start changing_. It basically says align everything at 1 byte, which means don't align anything. But you can also use this to align things for other CPU architectures. So for example `#pragma pack(1)` can act like 32bit architecture alignment.\n\n\nVideo: https://www.youtube.com/watch?v=8wHoI-6R0CQ\n\n\n#### Additional on memory paddings:\n\nProcessor doesn't read 1 byte at time from memory. It reads 1 \"word\" at a time. A word for 32 bit processor is 4 bytes for example.\n\nAdditional video: https://www.youtube.com/watch?v=aROgtACPjjg\n\n\n### add or subtract two pointers\n\nGiving\n\n```c\nlong long c[] = {1,2,3};\n```\n\n  a pointer like `long long* p = c + 1` gets the address of c and **adds 1 times of `sizeof(type of c)`. So `c + 1` doesn't add just one byte to the address, but 8 bytes in this case.\n\nGeneral rule: pointer arithmetics are done at the size of the pointer type.\n\nNote: in stack, the pointer value of a variable that is defined last is lower than the one that is defined first. While in heap this may not be true.\n\n\n### Memory manipulation\n\nFunctions (all work on arrays):\n\n- `memcmp`: memory comparing\n- `memcp`: memory copy\n- `memset`: set value in memory\n- `memchr`: find byte in memory\n\nVideo: https://www.youtube.com/watch?v=ypG9W33LOTk\n\nFiles: [memory_manipulation.c](files/memory_manipulation.c)  [memory_manipulation_2.c](files/memory_manipulation_2.c)  [memory_manipulation_3.c](files/memory_manipulation_3.c)  [memory_manipulation_4.c](files/memory_manipulation_4.c) \n\n\n### Memory allocaction\n\n`malloc` allocates memory for given size and returns `void*` to the initial byte of the allocated memory. **important:** `malloc` DOES NOT set the memory to 0; In fact the allocated memory may have some values in it since `free()` only tells OS to let go of a memory for the process and doesn't tell it to set it to 0. `malloc` needs a check if returned pointer is NULL.\n\nUsing `memset` we can set everything to something (example `0`), for example the result of the `malloc`.\n\nAlternatively we can allocate an array using `calloc` and it'll create an array with initial values of `0`.\n\n`realloc` can be used to shrink/expand allocated memory. Lets say we `malloc`'d 256 bytes and organized some values to take only `64` byte. Instead of allocating a new 64 byte memory and move/copy the organized memory there we can shring the already allocated 256 bytes of memory. **important**: `realloc` may have to move the data to somewhere else, therefore it returns a new pointer. We can do something like `p = realloc(p, 64 * sizeof(int))` so our previous pointer will eventually point to the new location in case `realloc` moved the data. It still needs a check if returned pointer is NULL.\n\n\n### Pointer declarion quirks\n\nTo declare multiple pointers in same line, doing this is wrong: `int* a, b` and makes `b` just an `int` and not a pointer. Doing this is right: `int *a, *b`.\n\n`char* str[20]` creates 20 character pointers.\n\n\n### Function pointers\n\nTo declare a function pointer we use something like: `{RETURN TYPE} (*{POINTER NAME})({ARG 1 TYPE}, {ARG 2 TYPE})`, for example: `long long (*func)(int, int)` would be a pointer named `func` to a function that returns `long long` and has 2 arguments both of type `int`.\n\nTo make the pointer point to a function we can do `{POINTER NAME} = \u0026{FUNCTION NAME}` like `func = \u0026sum` where `func` is the pointer name and `sum` is name of the function.\n\nThe notation (`{RETURN TYPE} (*{POINTER NAME})({ARG 1 TYPE}, {ARG 2 TYPE})`) can be used as a function argument itself, for passing a function to another function.\n\n\nfile: [memory_management.c](files/memory_management.c)\nvideo: https://www.youtube.com/watch?v=cwvdT-4HT9o\n\n\n### Pointer address of an array\n\nConsidering we have `char str[20] = \"Example string\";`, to get the pointer to the beginning of the variable, our best choice can be `str` or `\u0026str[0]`. If we -_wrongly_- use `\u0026str`, our pointer arithmetics will be messed with, since `str + 1` or `\u0026str[0] + 1` will return address of the second element, but `\u0026str + 1` will return address of `20 + 1` memory after the first element (not that the size of `str` is `20`). \n\n\n### Offset\n\n`offsetof(TYPE, MEMBER)` returns `size_t` of the _MEMBER_ offset from initial position of a _TYPE_. If we have the struct below for example:\n\n```c\ntypedef struct Example {\n    int x; // 4 bytes\n    char y; // 1 byte\n    // 3 bytes pad\n    int z; // 4 bytes\n} Example;\n```\n\nWe can get `offsetof(Example, y)` which will be equal to `4`. We can also get offset of nested members from a nested struct by using `.` delimiter to move between members.\n\nfile: [memory_management_2.c](files/memory_management_2.c)\nvideo: https://www.youtube.com/watch?v=txf92femaGM\n\n\n### Difference between memmove and memcpy\n\n`memmove` is safe to use when you have overlapping memory between the source and destination. It will first copy the source into a buffer and then replace the destination. But `memcpy` is not safe _(in some compilers)_ for copying overlapping memory since it doesn't first copy the memory into a buffer.\n\nvideo: https://www.youtube.com/watch?v=nFl1cNXk85s\n\n\n### Double pointer (or more!)\n\nThey are just pointers to another pointer. We can derefrence them (get the value) using a astricks, and you need (N-1) astricks where N is number of pointers.\n\nExample:\n\n```c\nvoid display(char********* output) {\n    printf(\"%s\\n\", *output);\n}\n\nint main(int argc, char* argv[]) {\n    char* str = \"This is a test\";\n    char** str2 = \u0026str;\n    char*** str3 = \u0026str2;\n    char**** str4 = \u0026str3;\n    char***** str5 = \u0026str4;\n    char****** str6 = \u0026str5;\n    char******* str7 = \u0026str6;\n    char******** str8 = \u0026str7;\n    char********* str9 = \u0026str8;\n    \n    display(str9);\n    return 0;\n}\n```\n\n_Why to use double pointer at all?_ The nice part of it is that you can change the value we are pointing at.\n\n\n### Why is it useful to hexadecimal to represent memory\n\nSince hexadecimal is 2 to the power of 4, and binary is base 2, we can easily imagine representation of a hexadecimal number by extracting each digit and representing it as binary.\n\nFor example:\n\n- Binary representation of number 23 is `00010111`\n- The hexadecimal value is `17`\n- Extract each digit of hexadecimal value, so we have `{1, 7}` and represent each digit as binary, so we have: `{0001, 0111}`, and merge them together to have a single byte: `00010111`.\n\n\nVideo: https://www.youtube.com/watch?v=lvjW-aUcbF0\nfile: [operators_1.c](files/operators_1.c)\n\n### const\n\nI already understand const. The only note: The valid way to use it for a pointer is to use it after the pointer:\n\n```c\nint * const x = \u0026n;\n```\n\nThe code below is a pointer to a constant int:\n\n```c\nconst int *x;\n```\n\n## Operators\n\n### bit-shift operation\n\n- `Left shift`\n\nIt takes a binary number and moves it to left for one bit (filling the remaining with 0). So if `int a = 5` and 5 is `0101` in binary, `a \u003c\u003c 1` will result in: `1010` which is 10. Doing it again gives us 20, 40, 80, ...  so all in all it multiplies a number by 2. If we shift too much, the binary numbers can disapear and get out of boundry and can even go over the sign bit and make the number negative.\n\n- `Right shift`\n\nSame thing happens with right shift. The number will be devided by 2. **The right shift takes a look at sign bit** and fills the shifted bits with sign bit (in most compilers).\n\n### Bitwise operators\n\nWell they simply apply `and`/`or`/`xor`/`not` operations at bit level!\n\n```\n5   -\u003e   0 1 0 1\n9   -\u003e   1 0 0 1\n\n5\u00269 -\u003e   0 0 0 1   -\u003e 1\n5|9 -\u003e   1 1 0 1   -\u003e 13\n5^9 -\u003e   1 1 0 0   -\u003e 12   (XOR)\n```\n\n```\n5   -\u003e   0 1 0 1\n~5  -\u003e   1 0 1 0\n\n9   -\u003e   1 0 0 1\n~9  -\u003e   0 1 1 0 \n```\n\n#### Practical example: flag system\n\nIf we assume we want to store 32 flags in a single int, since an int has 32 bits then we can use each bit as a on/off flag.\n\nIf we want to see the \"first\" flag is \"ON/true\", we can do a bitwise \u0026 operation of the number with `1` and assure its not 0;\nOr generally:\n\n\u003e If we want to see the nth flag is \"ON/true\", we can do a bitwise \u0026 operation of the number with n in binary and assure its not 0;\n\nAdditionally, to enable flags on the `int` number we had, we can use bitwise or operation between binary representation of numbers to turn on those flags (bits): `unsigned int flag = 0b1 | 0b10 | 0b1001`.\n\nThe code example explains it even better.\n\nfile: [operators_2.c](files/operators_2.c)\nvideo: https://www.youtube.com/watch?v=6hnLMnid1M0\n\n\n## UNIX\n\n- [Process](unix/UNIX_PROCESS.md)\n- [Threads](unix/UNIX_THREAD.md)\n---\n\n\n## Resources (+Additional)\n\n- (Binary Numbers and Data Representation)[https://www.youtube.com/playlist?list=PLbtzT1TYeoMgzLyE9n-pJrTFZX18EUKw_]\n- (Code Vault)[https://code-vault.net]\n- (Signed representation of binary numbers)[https://youtu.be/-CEJXDeDsAQ?si=OeG2PcYKywU-uU9q\u0026t=692]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsepgh%2Fremember-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsepgh%2Fremember-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsepgh%2Fremember-c/lists"}