{"id":35102459,"url":"https://github.com/monadplus/learning-c","last_synced_at":"2026-05-18T20:03:25.621Z","repository":{"id":128354946,"uuid":"549552434","full_name":"monadplus/learning-c","owner":"monadplus","description":"Introduction to C","archived":false,"fork":false,"pushed_at":"2025-04-01T20:30:12.000Z","size":4694,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-29T10:56:34.764Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/monadplus.png","metadata":{"files":{"readme":"README.markdown","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}},"created_at":"2022-10-11T11:10:14.000Z","updated_at":"2025-04-01T20:30:16.000Z","dependencies_parsed_at":"2024-06-03T08:55:22.151Z","dependency_job_id":"b7e6ac90-ba34-4473-b48a-d84b3cccfad9","html_url":"https://github.com/monadplus/learning-c","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/monadplus/learning-c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Flearning-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Flearning-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Flearning-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Flearning-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monadplus","download_url":"https://codeload.github.com/monadplus/learning-c/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Flearning-c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33189279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-18T09:27:30.708Z","status":"ssl_error","status_checked_at":"2026-05-18T09:27:28.300Z","response_time":71,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-12-27T17:03:06.724Z","updated_at":"2026-05-18T20:03:25.614Z","avatar_url":"https://github.com/monadplus.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tutorial: C\n\nSources:\n\n- \u003chttps://www.tutorialspoint.com/cprogramming/index.htm\u003e\n- \u003chttps://www.geeksforgeeks.org/c-programming-language\u003e\n- \u003chttps://www.cplusplus.com/reference\u003e\n\nThe GNU C Library: \u003chttps://www.gnu.org/software/libc/manual/html_mono/libc.html\u003e\n\n## Compiling\n\nCompiling `hello.c`:\n\n```bash\n$ gcc hello.c\n$ ./a.out\n```\n\n## Types\n\nInteger/Float Types:\n\n| type           | storage size | value range                                 | precision         |\n| -------------- | ------------ | ------------------------------------------- | ---------         |\n| char           | 1 byte       | -128 to 127 or 0 to 255                     | -                 |\n| unsigned char  | 1 byte       | 0 to 255                                    | -                 |\n| signed char    | 1 byte       | -128 to 127                                 | -                 |\n| short          | 2 bytes      | -32,768 to 32,767                           | -                 |\n| unsigned short | 2 bytes      | 0 to 65,535                                 | -                 |\n| int            | 4 bytes      | -2,147,483,648 to 2,147,483,647             | -                 |\n| unsigned int   | 4 bytes      | 0 to 4,294,967,295                          | -                 |\n| long           | 8 bytes      | -9223372036854775808 to 9223372036854775807 | -                 |\n| unsigned long  | 8 bytes      | 0 to 18446744073709551615                   | -                 |\n| float          | 4 bytes      | 1.2E-38 to 3.4E+38                          | 6 decimal places  |\n| double         | 8 bytes      | 2.3E-308 to 1.7E+308                        | 15 decimal places |\n| long double    | 10 bytes     | 3.4E-4932 to 1.1E+4932                      | 19 decimal places |\n\n\nExact size use `sizeof(type)`:\n\n```bash\n# limits.h defines some ergonomic constants\n$ gcc limits.c\n```\n\nVoid type:\n\n- void exit (int status);\n- int rand(void);\n- void *malloc( size_t size );\n\n## Variables\n\n```c\nchar c, ch;\nint i,j, k;\ndouble d;\nfloat f = 3.0, f2 = 5.0;\nbyte z = 22;\n```\n\nUse `extern` to share variables between source files.\n\n## Constants and Literals\n\nLiterals:\n\n```c\n// Integer literals\n85         // decimal\n0213       // octal\n0x4b       // hexadecimal\n30         // int\n30u        // unsigned int\n30l        // long\n30ul       // unsigned long\n\n// Floating ponts\n3.14159\n314159E-5L\n\n// Character constants\n'x'\n'\\t'\n'\\u02C0'\n```\n\nConstants:\n\n```c\n#define LENGTH 50 // Preprocessor\nconst int LENGTH = 50; // const keyword\n```\n\n## Storage Classes\n\nscope and life-time of variables and/or functions:\n\n- auto\n- register\n- static\n- extern\n\n__auto__ (default): functions and local variables.\n\n```c\nint mount;            // auto\nauto int month;       // auto\n```\n\n__register__: stored in a register, max size = 1 WORD, and can't have the \u0026 operator applied (it does not have a memory location).\n\n```c\nregister int miles;   // register\n```\n\n__static__:\n\n- local variables: keep the value between functions calls.\n- global variables: restrict the scope to the file.\n\n```c\nstatic int count = 5; // static\n```\n\n__extern__: global variable visible to all the program files.\n\n```c\n// compile: $gcc main.c support.c\n\n// main.c\n#include \u003cstdio.h\u003e\n\nint count ;\nextern void write_extern();\n\nmain() {\n   count = 5;\n   write_extern();\n}\n\n// support.c\n#include \u003cstdio.h\u003e\n\nextern int count;\n\nvoid write_extern(void) {\n   printf(\"count is %d\\n\", count);\n}\n```\n\n## Operators\n\n```c\nmodulus: %\n\n// bitwise\nbitwise and: p \u0026 q\nbitwise or: p | q\nbitwise xor: p ^ q\nbitwise complement: ~p\nbitwise left shift: \u003c\u003c\nbitwise right shift: \u003e\u003e\n\n// assignment operators\n+=\n-=\n*=\n/=\n%=\n\u003c\u003c=\n\u003e\u003e=\n\u0026=\n|=\n^=\n\n// Misc\nsizeof()\n\u0026a; // address\n*a; // pointer\nb ? a : b // conditional operator\n```\n\n## Loops\n\nwhile loop:\n\n```c\nwhile(condition) {\n   statement(s);\n}\n```\n\nfor loop:\n\n```c\nfor ( init; condition; increment ) {\n   statement(s);\n}\n```\n\ndo while loop:\n\n```c\ndo {\n   statement(s);\n} while( condition );\n```\n\nInfinite loop:\n\n```c\nfor( ; ; ) {\n  printf(\"This loop will run forever.\\n\");\n}\n```\n\nloop control statement:\n\n```c\nbreak      // terminate the loop\ncontinue   // go to next iteration\ngoto\n       LOOP:do {\n          if( a == 15) {\n             goto LOOP;\n          }\n          printf(\"value of a: %d\\n\", a);\n          a++;\n       }while( a \u003c 20 );\n```\n\n## Functions\n\n```c\nint max(int x, int y) {\n  return (x \u003c= y) ? y : x;\n}\n```\n\nCall by value: copies the actual value of the arguments\n\n```c\nvoid swap(int x, int y) {\n   int temp;\n   temp = x;\n   x = y;\n   y = temp;\n   return;\n}\n\nint a = 100;\nint b = 200;\nswap(a, b);\n// a = 100\n// b = 200\n```\n\nCall by reference:\n\n```c\nvoid swap(int *x, int *y) {\n   int temp;\n   temp = *x;\n   *x = *y;\n   *y = temp;\n   return;\n}\n\nint a = 100;\nint b = 200;\nswap(\u0026a, \u0026b);\n\n// a = 200\n// b = 100\n```\n\n## Scope Rules\n\n- local\n- global\n- formal: function arguments, they take precedence over global variables.\n\n## Arrays\n\n```c\ndouble balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};\ndouble salary = balance[0];\nint matrix[10][10];\nint matrix[3][2] = { {0,1}, {2,3}, {4,5} };\nint a = matrix[0][0];\n```\n\n### Passing arrays as function arguments\n\n```c\nvoid myFunction(int *param) {..}\nvoid myFunction(int param[10]) {..}\nvoid myFunction(int param[]) {..}\n```\n\n```c\ndouble average(int arr[], int size) {\n  double sum = 0;\n\n  for(i = 0; i \u003c size;  ++i){\n    sum += arr[i]\n  }\n\n  int avg = sum / size;\n\n  return avg;\n}\n\nint main () {\n  int balance[5] = {1, 2, 3, 4, 5}\n  double avg = average(balance, 5);\n}\n```\n\n### Return array from function in C\n\nThe local variable that you are going to return __must__ be declared static.\n\n```c\n#include \u003cstdio.h\u003e\n\nint * getRandom( ) {\n\n   static int  r[10];\n   int i;\n\n   srand( (unsigned)time( NULL ) );/* set the seed */\n\n   for ( i = 0; i \u003c 10; ++i) {\n      r[i] = rand();\n   }\n\n   return r;\n}\n\nint main () {\n\n   int *p;\n   int i;\n\n   p = getRandom();\n\n   for ( i = 0; i \u003c 10; i++ ) {\n      printf( \"*(p + %d) : %d\\n\", i, *(p + i));\n   }\n\n   return 0;\n}\n```\n\n### Pointer to an Array in C\n\nAn array name is a constant pointer to the first element of the array.\n\nFor example, `double balance[50];` balance points to `\u0026balance[0]`:\n\n```c\ndouble *p;\ndouble balance[10];\n\np = balance;\np[0];\n*(balance + 1);\n```\n\n## Pointers\n\n```c\nint    *ip;    /* pointer to an integer */\ndouble *dp;    /* pointer to a double */\nfloat  *fp;    /* pointer to a float */\nchar   *ch     /* pointer to a character */\n```\n\n```c\nint  var = 20; // \u0026var = bffd8b3c\nint  *ip = NULL; // NULL = 0 address\nip = \u0026var;\nip // bffd8b3c = \u0026var\n*ip // 20\n\nif (ptr) // succeeds if p is not null\nif (!ptr) // succeeds if p is null\n```\n\n### Arithmetic operations\n\n```c\n#include \u003cstdio.h\u003e\n\nconst int MAX = 3;\n\nint main () {\n\n   int  var[] = {10, 100, 200};\n   int  i, *ptr;\n   ptr = var;\n\n   for ( i = 0; i \u003c MAX; i++) {\n      ptr++;\n   }\n\n   while ( ptr \u003c= \u0026var[MAX - 1] ) {\n      ptr--;\n   }\n\n   return 0;\n}\n```\n\n### Array of pointers\n\n```c\n#include \u003cstdio.h\u003e\n\nconst int MAX = 3;\n\nint main () {\n\n   int  var[] = {10, 100, 200};\n   int i, *ptr[MAX];\n\n   for ( i = 0; i \u003c MAX; i++) {\n      ptr[i] = \u0026var[i];\n   }\n\n   for ( i = 0; i \u003c MAX; i++) {\n      printf(\"Value of var[%d] = %d\\n\", i, *ptr[i] );\n   }\n\n   return 0;\n}\n```\n\n```c\nchar *names[] = {\n  \"Zara Ali\",\n  \"Hina Ali\",\n  \"Nuha Ali\",\n  \"Sara Ali\"\n};\n\nint i = 0;\n\nfor ( i = 0; i \u003c MAX; i++) {\n  printf(\"Value of names[%d] = %s\\n\", i, names[i] );\n}\n```\n\n### Passing pointers to functions\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003ctime.h\u003e\n\nvoid getSeconds(unsigned long *par);\n\nint main () {\n   unsigned long sec;\n   getSeconds( \u0026sec );\n\n   return 0;\n}\n\nvoid getSeconds(unsigned long *par) {\n   *par = time( NULL );\n   return;\n}\n```\n\n```c\n#include \u003cstdio.h\u003e\n\ndouble getAverage(int *arr, int size);\n\nint main () {\n\n   int balance[5] = {1000, 2, 3, 17, 50};\n   double avg;\n\n   avg = getAverage( balance, 5 ) ;\n\n   return 0;\n}\n\ndouble getAverage(int *arr, int size) {\n\n   int  i, sum = 0;\n   double avg;\n\n   for (i = 0; i \u003c size; ++i) {\n      sum += arr[i];\n   }\n\n   avg = (double)sum / size;\n   return avg;\n}\n```\n\n### Returning pointers from functions\n\nSee [return array from function in C](#return-array-from-function-in-c)\n\n### Passing functions as function parameters\n\n```c\n#include \u003cstdio.h\u003e\n\nvoid print(int x);\nvoid func(void (*f)(int));\n\nvoid print ( int x ) {\n  printf(\"%d\\n\", x);\n}\n\nvoid func ( void (*f)(int) ) {\n  for ( int ctr = 0 ; ctr \u003c 5 ; ctr++ ) {\n    (*f)(ctr);\n  }\n}\n\nint main() {\n\n  func(print);\n\n  return 0;\n}\n```\n\n## Strings\n\n```c\nchar greeting[6] = {'H', 'e', 'l', 'l', 'o', '\\0'};\nchar greeting[] = \"Hello\";\n```\n\n```c\nstrcpy(s1,s2); // copies string s2 into string s1\nstrcat(s1, s2); // concatenates s1 ++ s2\nstrlen(s1);\nstrcmp(s1,s2); // \u003c 0 if s1 \u003c s2\n               // 0   if s1 == s2\n               // \u003e 0 if s1 \u003e s2\nstrchr(s1, ch); // returns a pointer to the first occurrence of 'ch' in s1.\nstrstr(s1, s2); // returns a pointer to the first occurence of string s2 in string s1.\n```\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\nint main () {\n\n   char str1[12] = \"Hello\";\n   char str2[12] = \"World\";\n   char str3[12];\n   int  len ;\n\n   /* copy str1 into str3 */\n   strcpy(str3, str1);\n   printf(\"strcpy( str3, str1) :  %s\\n\", str3 );\n\n   /* concatenates str1 and str2 */\n   strcat( str1, str2);\n   printf(\"strcat( str1, str2):   %s\\n\", str1 );\n\n   /* total lenghth of str1 after concatenation */\n   len = strlen(str1);\n   printf(\"strlen(str1) :  %d\\n\", len );\n\n   return 0;\n}\n```\n\n## Structures\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\nstruct Books {\n   char  title[50];\n   char  author[50];\n   char  subject[100];\n   int   book_id;\n};\n\nvoid printBook( struct Books book );\nvoid printBook2( struct Books *book );\n\nint main( ) {\n\n   struct Books Book1;\n   struct Books Book2;\n\n   strcpy( Book1.title, \"C Programming\");\n   strcpy( Book1.author, \"Nuha Ali\");\n   strcpy( Book1.subject, \"C Programming Tutorial\");\n   Book1.book_id = 6495407;\n\n   strcpy( Book2.title, \"Telecom Billing\");\n   strcpy( Book2.author, \"Zara Ali\");\n   strcpy( Book2.subject, \"Telecom Billing Tutorial\");\n   Book2.book_id = 6495700;\n\n   printf( \"Book 1 title : %s\\n\", Book1.title);\n   printf( \"Book 1 author : %s\\n\", Book1.author);\n   printf( \"Book 1 subject : %s\\n\", Book1.subject);\n   printf( \"Book 1 book_id : %d\\n\", Book1.book_id);\n\n   printf( \"Book 2 title : %s\\n\", Book2.title);\n   printf( \"Book 2 author : %s\\n\", Book2.author);\n   printf( \"Book 2 subject : %s\\n\", Book2.subject);\n   printf( \"Book 2 book_id : %d\\n\", Book2.book_id);\n\n   printBook( Book1 );\n   printBook2( \u0026Book1 );\n\n   return 0;\n}\n\nvoid printBook( struct Books book ) {\n   printf( \"Book title : %s\\n\", book.title);\n   printf( \"Book author : %s\\n\", book.author);\n   printf( \"Book subject : %s\\n\", book.subject);\n   printf( \"Book book_id : %d\\n\", book.book_id);\n}\n\nvoid printBook2( struct Books *book ) {\n   printf( \"Book title : %s\\n\", book-\u003etitle);\n   printf( \"Book author : %s\\n\", book-\u003eauthor);\n   printf( \"Book subject : %s\\n\", book-\u003esubject);\n   printf( \"Book book_id : %d\\n\", book-\u003ebook_id);\n}\n```\n\n## Unions\n\nStore different data types in the same memory location.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\nunion Data {\n   int i;\n   float f;\n   char str[20];\n};\n\nint main( ) {\n   union Data data;\n\n   printf( \"Memory size occupied by data : %d\\n\", sizeof(data)); // 20\n\n   data.i = 10;\n   data.f = 220.5;\n   strcpy( data.str, \"C Programming\");\n\n   printf( \"data.i : %d\\n\", data.i); // data.i : 1917853763\n   printf( \"data.f : %f\\n\", data.f); // data.f : 4122360580327794860452759994368.000000\n   printf( \"data.str : %s\\n\", data.str); // data.str : C Programming\n\n   return 0;\n}\n```\n\n## Bit Fields\n\nYou can at most use 1 bit for each variable.\n\nThe minimum size is a WORD.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\n// Requires 8 bytes\nstruct {\n   unsigned int widthValidated;\n   unsigned int heightValidated;\n} status1;\n\n// Requires 4 bytes, only 2 bits are used.\nstruct {\n   unsigned int widthValidated : 1;\n   unsigned int heightValidated : 1;\n} status2;\n\nint main( ) {\n   printf( \"Memory size occupied by status1 : %d\\n\", sizeof(status1)); // Memory size occupied by status1 : 8\n   printf( \"Memory size occupied by status2 : %d\\n\", sizeof(status2)); // Memory size occupied by status2 : 4\n   return 0;\n}\n```\n\nIf you will use up to 32 variables each one with a width of 1 bit, then also the status structure will use 4 bytes.\n\nIf you try to use more bits than the requested you are going to do a no-op.\n\n## Typedef\n\nType alias `typedef unsigned char BYTE;`.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstring.h\u003e\n\ntypedef struct Books {\n   char title[50];\n   char author[50];\n   char subject[100];\n   int book_id;\n} Book;\n\n#define TRUE  1\n#define FALSE 0\n\nint main( ) {\n   Book book; // no need to write struct.\n              // works the same way.\n\n   printf(\"Value of True: %d\\n\", TRUE);\n\n   return 0;\n}\n```\n\n### typedef vs #define\n\n`typedef` can only be used for type aliases, `#define` can be used for more things.\n\n`typedef` is interpreted by the compiler whereas `#define` is processed by the pre-processor.\n\n## Input \u0026 Output\n\n```c\nint getchar(void); // returns the next available character from the stdin\nint putchar(int c);\n```\n```c\nchar *gets(char *s); // deprecated in favor of fgets()\nint puts(const char *s);\n\n// Example\n#include \u003cstdio.h\u003e\nint main( ) {\n   char str[100];\n   printf( \"Enter a value :\");\n   gets( str );\n   printf( \"\\nYou entered: \");\n   puts( str );\n   return 0;\n}\n```\n\n```c\nint scanf(const char *format, ...)\nint printf(const char *format, ...)\n\n// Example\n#include \u003cstdio.h\u003e\nint main( ) {\n   char str[100];\n   int i;\n   scanf(\"%s %d\", str, \u0026i);\n   printf( \"\\nYou entered: %s %d \", str, i);\n   return 0;\n}\n```\n\n## File I/O\n\n### Open/Close\n```c\n// mode (you can combine them e.g. rb, wb, rb+):\n// r     read\n// w     write (if it does not exist, creates a new file)\n// a     append (if it does not exist, creates a new file)\n// r+    read+write\n// w+    read+write. Truncates the file to 0  (if it does not exist, creates a new file)\n// a+    read+wite. read from start, write appending (if it does not exist, creates a new file)\nFILE *fopen( const char * filename, const char * mode );\nint fclose( FILE *fp );\n```\n\n### Writing\n\n```c\nint fputc( int c, FILE *fp ); // single char\nint fputs( const char *s, FILE *fp ); // string\nint fprintf(FILE *fp,const char *format, ...) // similar to fputs\n\n//Example\n#include \u003cstdio.h\u003e\n\nmain() {\n   FILE *fp;\n   fp = fopen(\"/tmp/test.txt\", \"w+\");\n   fprintf(fp, \"This is testing for fprintf...\\n\");\n   fputs(\"This is testing for fputs...\\n\", fp);\n   fclose(fp);\n}\n```\n\n### Reading\n\n```c\nint fgetc( FILE * fp ); // Char\nchar *fgets( char *buf, int n, FILE *fp ); // appends a null character aat the end of buf.\n                                           // stops when it encounters a '\\n' or EOF or reads n characters.\nint fscanf(FILE *fp, const char *format, ...)\n\n//Example\n#include \u003cstdio.h\u003e\n\nmain() {\n   FILE *fp;\n   char buff[255];\n\n   fp = fopen(\"/tmp/test.txt\", \"r\");\n   fscanf(fp, \"%s\", buff);\n   printf(\"1 : %s\\n\", buff );\n\n   fgets(buff, 255, (FILE*)fp);\n   printf(\"2: %s\\n\", buff );\n\n   fgets(buff, 255, (FILE*)fp);\n   printf(\"3: %s\\n\", buff );\n   fclose(fp);\n}\n```\n\n\n### Binary I/O Functions\n\n```c\nsize_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);\n\nsize_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);\n```\n\n## Preprocessors\n\nCPP (C preprocessor) is a separate state in the compilation process.\n\n```c\n#define          Substitutes a preprocessor macro.\n#include         Inserts a particular header from another file.\n#undef           Undefined a preprocessor macro.\n#ifdef           Returns true if this macro is defined.\n#ifndef          Returns true if this macro is not defined.\n#if              Test if a compiler time condition is true.\n#else\n#elif\n#endif\n#error          Prints error message on stderr.\n#pragma         Issues special commands to the compiler, using a standardized method.\n\n// Examples\n#define MAX_ARRAY_LENGTH 20\n\n#include \u003cstdio.h\u003e\n#include \"myheader.h\"\n\n#undef  FILE_SIZE\n#define FILE_SIZE 42\n\n#ifndef MESSAGE\n   #define MESSAGE \"You wish!\"\n#endif\n\n#ifdef DEBUG\n   #error \"DEBUG MODE\"\n#endif\n```\n\n### Predefined macros\n\n```c\n#include \u003cstdio.h\u003e\n\nint main() {\n   printf(\"File :%s\\n\", __FILE__ ); // File :test.c\n   printf(\"Date :%s\\n\", __DATE__ ); // Date :Jun 2 2012\n   printf(\"Time :%s\\n\", __TIME__ ); // Time :03:36:24\n   printf(\"Line :%d\\n\", __LINE__ ); // Line :8\n   printf(\"ANSI :%d\\n\", __STDC__ ); // ANSI :1\n}\n```\n\n### Preprocessor Operators\n\nThe Macro Continuation (\\) Operator\n\nThe Stringize (#) Operator\n\n```c\n#include \u003cstdio.h\u003e\n\n#define  message_for(a, b)  \\\n   printf(#a \" and \" #b \": We love you!\\n\")\n\nint main(void) {\n   message_for(Carole, Debra); // Carole and Debra: We love you!\n   return 0;\n}\n```\n\nThe Token Pasting (##) Operator\n\n```c\n#include \u003cstdio.h\u003e\n\n#define tokenpaster(n) printf (\"token\" #n \" = %d\", token##n)\n\nint main(void) {\n   int token34 = 40;\n   // Replaced by:\n   // printf (\"token34 = %d\", token34);\n   tokenpaster(34); // Outputs: token34 = 40\n   return 0;\n}\n```\n\nThe Defined() Operator\n\n```c\n#include \u003cstdio.h\u003e\n\n#if !defined (MESSAGE)\n   #define MESSAGE \"You wish!\"\n#endif\n\nint main(void) {\n   printf(\"Here is the message: %s\\n\", MESSAGE);\n   return 0;\n}\n```\n\nParameterized Macros\n\nThe definition will be __inlined__.\n\n```c\n#include \u003cstdio.h\u003e\n\n#define MAX(x,y) ((x) \u003e (y) ? (x) : (y))\n\nint main(void) {\n   printf(\"Max between 20 and 10 is %d\\n\", MAX(10, 20));\n   return 0;\n}\n```\n\n## Header Files\n\nFile with extension __.h__ which contains function declarations and macro definitions to be shared.\n\nThe compiler comes with some header files.\n\n```c\n#include \u003cstdio.h\u003e // System headers files.       You can add directories using -l\n#include \"file\" // Only in the current directory. You can add directories using -l\n```\n\nThe preprocessors copies the source of the header file into your program.\n\nPrevent copying the header file multiple types.\n\n```c\n#ifndef STDIO\n#define STDIO\n  #include \u003cstdio.h\u003e\n#endif\n```\n\n## Type Casting\n\nCast operator: `mean = (double) sum / count;`\n\n## Error Handling\n\nError codes defined in \u003cerror.h\u003e.\n\nerrno, perror(), and strerror()\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cerrno.h\u003e\n#include \u003cstring.h\u003e\n\nextern int errno ;\n\nint main () {\n\n   FILE * pf;\n   int errnum;\n   pf = fopen (\"unexist.txt\", \"rb\");\n\n   if (pf == NULL) {\n\n      errnum = errno;\n      fprintf(stderr, \"Value of errno: %d\\n\", errno); // Value of errno: 2\n      perror(\"Error printed by perror\"); // Error printed by perror: No such file or directory\n      fprintf(stderr, \"Error opening file: %s\\n\", strerror( errnum )); // Error opening file: No such file or directory\n   } else {\n\n      fclose (pf);\n   }\n\n   return 0;\n}\n```\n\n## Variable Arguments\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdarg.h\u003e // required for variadic arguments\n\ndouble average(int num,...) {\n\n   va_list valist;\n   double sum = 0.0;\n   int i;\n\n   /* initialize valist for num number of arguments */\n   va_start(valist, num);\n\n   /* access all the arguments assigned to valist */\n   for (i = 0; i \u003c num; i++) {\n      sum += va_arg(valist, int);\n   }\n\n   /* clean memory reserved for valist */\n   va_end(valist);\n\n   return sum/num;\n}\n\nint main() {\n   printf(\"Average of 2, 3, 4, 5 = %f\\n\", average(4, 2,3,4,5));\n   printf(\"Average of 5, 10, 15 = %f\\n\", average(3, 5,10,15));\n}\n```\n\n## Memory Management\n\nFrom `\u003cstdlib.h\u003e`:\n\n```c\nvoid *calloc(int num, int size); // num * size bytes\nvoid free(void *address);\nvoid *malloc(int num); // num bytes\nvoid *realloc(void *address, int newsize); // extens allocated memory up to newsize.\n```\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstring.h\u003e\n\nint main() {\n\n   char name[100];\n   char *description;\n\n   strcpy(name, \"Zara Ali\");\n\n   description = malloc( 200 * sizeof(char) );\n\n   if( description == NULL ) {\n      fprintf(stderr, \"Error - unable to allocate required memory\\n\");\n   } else {\n      strcpy( description, \"Zara ali a DPS student in class 10th\");\n   }\n\n   printf(\"Name = %s\\n\", name );\n   printf(\"Description: %s\\n\", description ); // Description: Zara ali a DPS student in class 10th\n}\n```\n\n## Command Line Arguments\n\n```bash\n$./a.out testing\nThe argument supplied is testing\n```\n\n```c\n#include \u003cstdio.h\u003e\n\n// argv[0] = name of the program\n// argv[1] pointer to the first command line argument.\nint main( int argc, char *argv[] )  {\n\n   if( argc == 2 ) {\n      printf(\"The argument supplied is %s\\n\", argv[1]);\n   }\n   else if( argc \u003e 2 ) {\n      printf(\"Too many arguments supplied.\\n\");\n   }\n   else {\n      printf(\"One argument expected.\\n\");\n   }\n}\n\n```\n\n\n# Tutorial: GCC and Make\n\n## GCC\n\nSource: \u003chttps://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html\u003e\n\nThe GNU C Compiler (GCC). Current version 8.3.0\n\n```bash\n# 1.\n$ gcc -Wall -g source1.c source2.c -o program_name\n\n-g: debug\n-v: verbose\n-Dname: defining macros. Example -DDEBUG=\"TRUE\", -DHaskell=\"Haskell 98\"\n\n# 2. Compile and then link\n$ gcc -c -Wall hello.c\n$ gcc -c -Wall util.c\n$ gcc hello.o util.o -o hello\n\n# Shared library .so\nCompile using -shared\n```\n\n### GCC Compilation Process\n\n```\nSource (.c, .h)\n\n      Preprocessing (cpp)\n\nInclude Header, Expand Macro (.i)\n\n      Compilation (gcc)\n\nAssembly Code (.s)\n\n      Assemble (as)\n\nMachine Code (.o)\n\n      Linking (ld)\n\nStatic Library (.a)\nExecutable Machine Code\n```\n\nGCC compiles the program in the four previous steps:\n\n```bash\n# Pre-processing\n$ cpp hello.c \u003e hello.i\n# Compilation\n$ gcc -S hello.i\n# Assembly\n$ as -o hello.o hello.s\n# Linker\n$ ld -o hello hello.o ..libraries...\n```\n\n### Headers (.h), Static Libraries (.a) and Shared Libraries (.a)\n\n#### Static vs Shared\n\nA library is a collection of pre-compiled object files that can be linked into your programs via the linker.\n\nStatic (.a): the code is copied into the executable.\n\nDynamic (.so): only a small table of references is copied. Before the executable is run, the OS loads the machine code needed for the external functions (dynamic linking).\n\n#### Searching for Header Files and Libraries (-I, -L and -l)\n\nThe __compiler__ needs the __headers file__ to compile the code.\n\nThe __linker__ needs the __libraries__ to resolve external references from other object files or libraries.\n\nFor headers: gcc option `-Idir` or `CPATH` environment variable.\n\nFor librares: `-Ldir` or `LIBRARY_PATH`. In addition, you also have to specify the library name: `-lxxx.a`.\n\nThe are some default paths:\n\n```bash\n$ gcc -v -o hello hello.c\n# -L/usr/lib/gcc/x86_64-pc-cygwin/6.4.0\n# -L/usr/x86_64-pc-cygwin/lib\n# -L/usr/lib\n# -L/lib\n# -lgcc_s     // libgcc_s.a\n# -lgcc       // libgcc.a\n# -lcygwin    // libcygwin.a\n# -ladvapi32  // libadvapi32.a\n# -lshell32   // libshell32.a\n# -luser32    // libuser32.a\n# -lkernel32  // libkernel32.a\n```\n\n#### Utilities for examining the compiled files\n\n```bash\n# File type\n$ file\n# List symbol table of object files\n$ nm hello.o\n# List Dynamic-Link Libraries\n$ ldd hello\n```\n\n## Make\n\nAutomate compilation.\n\n```make\n# Makefile\nCC = gcc -Wall\n\nall: hello\n\n# Checks if hello.o exists, otherwise looks for a rule to create it.\nhello: hello.o\n\t $(CC) -o hello hello.o\n\nhello.o: hello.c\n\t $(CC) -c hello.c\n\nclean:\n\t rm hello.o hello\n```\n\n### Automatic variables\n\n```\n$@: the target filename.\n$*: the target filename without the file extension.\n$\u003c: the first prerequisite filename.\n$^: the filenames of all the prerequisites, separated by spaces, discard duplicates.\n$+: similar to $^, but includes duplicates.\n$?: the names of all prerequisites that are newer than the target, separated by spaces.\n```\n\nExample:\n\n```make\nall: hello\n\n# $@ matches the target; $\u003c matches the first dependent\nhello: hello.o\n\tgcc -o $@ $\u003c\n\nhello.o: hello.c\n\tgcc -c $\u003c\n\nclean:\n\trm hello.o hello\n```\n\n### Virtual Path (VPATH)\n\n```make\n# Search for dependencies and targets from \"src\" and \"include\" directories\n# The directories are separated by space\nVPATH = src include\n```\n\n### Pattern Rules\n\n```make\n# Applicable for create .o object file.\n# '%' matches filename.\n# $\u003c is the first pre-requisite\n# $(COMPILE.c) consists of compiler name and compiler options\n# $(OUTPUT_OPTIONS) could be -o $@\n%.o: %.c\n\t$(COMPILE.c) $(OUTPUT_OPTION) $\u003c\n\n# Applicable for create executable (without extension) from object .o object file\n# $^ matches all the pre-requisites (no duplicates)\n%: %.o\n$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@\n```\n\n### A sample Makefile\n\n```make\n# A sample Makefile\n# This Makefile demonstrates and explains\n# Make Macros, Macro Expansions,\n# Rules, Targets, Dependencies, Commands, Goals\n# Artificial Targets, Pattern Rule, Dependency Rule.\n\n# Comments start with a # and go to the end of the line.\n\n# Here is a simple Make Macro.\nLINK_TARGET = test_me.exe\n\n# Here is a Make Macro that uses the backslash to extend to multiple lines.\nOBJS =  \\\n Test1.o \\\n Test2.o \\\n Main.o\n\n# Here is a Make Macro defined by two Macro Expansions.\n# A Macro Expansion may be treated as a textual replacement of the Make Macro.\n# Macro Expansions are introduced with $ and enclosed in (parentheses).\nREBUILDABLES = $(OBJS) $(LINK_TARGET)\n\n# Here is a simple Rule (used for \"cleaning\" your build environment).\n# It has a Target named \"clean\" (left of the colon \":\" on the first line),\n# no Dependencies (right of the colon),\n# and two Commands (indented by tabs on the lines that follow).\n# The space before the colon is not required but added here for clarity.\nclean :\n  rm -f $(REBUILDABLES)\n  echo Clean done\n\n# There are two standard Targets your Makefile should probably have:\n# \"all\" and \"clean\", because they are often command-line Goals.\n# Also, these are both typically Artificial Targets, because they don't typically\n# correspond to real files named \"all\" or \"clean\".\n\n# The rule for \"all\" is used to incrementally build your system.\n# It does this by expressing a dependency on the results of that system,\n# which in turn have their own rules and dependencies.\nall : $(LINK_TARGET)\n  echo All done\n\n# There is no required order to the list of rules as they appear in the Makefile.\n# Make will build its own dependency tree and only execute each rule only once\n# its dependencies' rules have been executed successfully.\n\n# Here is a Rule that uses some built-in Make Macros in its command:\n# $@ expands to the rule's target, in this case \"test_me.exe\".\n# $^ expands to the rule's dependencies, in this case the three files\n# main.o, test1.o, and  test2.o.\n$(LINK_TARGET) : $(OBJS)\n  g++ -g -o $@ $^\n\n# Here is a Pattern Rule, often used for compile-line.\n# It says how to create a file with a .o suffix, given a file with a .cpp suffix.\n# The rule's command uses some built-in Make Macros:\n# $@ for the pattern-matched target\n# $\u003c for the pattern-matched dependency\n%.o : %.cpp\n  g++ -g -o $@ -c $\u003c\n\n# These are Dependency Rules, which are rules without any command.\n# Dependency Rules indicate that if any file to the right of the colon changes,\n# the target to the left of the colon should be considered out-of-date.\n# The commands for making an out-of-date target up-to-date may be found elsewhere\n# (in this case, by the Pattern Rule above).\n# Dependency Rules are often used to capture header file dependencies.\nMain.o : Main.h Test1.h Test2.h\nTest1.o : Test1.h Test2.h\nTest2.o : Test2.h\n\n# Alternatively to manually capturing dependencies, several automated\n# dependency generators exist.  Here is one possibility (commented out)...\n# %.dep : %.cpp\n#   g++ -M $(FLAGS) $\u003c \u003e $@\n# include $(OBJS:.o=.dep)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonadplus%2Flearning-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonadplus%2Flearning-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonadplus%2Flearning-c/lists"}