Selaa lähdekoodia

Minor fixes and reordering...

master
Ognjen Milan Robovic 5 kuukautta sitten
vanhempi
commit
d656866bef
6 muutettua tiedostoa jossa 219 lisäystä ja 122 poistoa
  1. +5
    -84
      chapter/chapter_0.c
  2. +35
    -17
      chapter/chapter_0.h
  3. +80
    -0
      chapter/chapter_1.c
  4. +61
    -11
      chapter/chapter_1.h
  5. +28
    -0
      program/program_0.c
  6. +10
    -10
      xhartae.c

+ 5
- 84
chapter/chapter_0.c Näytä tiedosto

@@ -138,17 +138,18 @@ int string_compare (char * string_0, char * string_1) {
int string_length (char * string) {
int length;

fatal_failure (string == NULL, "string_length: String is null pointer.");
fatal_failure (string == NULL, "string_length: String is null pointer."); // If variable 'string' is null pointer, we abort the program.

for (length = 0; string [length] != CHARACTER_NULL; ++length); // Since in C, strings are null terminated, looping until we see null character is strings' length.
for (length = 0; string [length] != CHARACTER_NULL; ++length); // In C, strings are null terminated, looping until we see null character is strings' length.

return (length);
return (length); // If we pass it non-null terminated string, program will fault!
}

/*
Now, I've implemented "unlimited" versions of string comparison, copying and concatenation different from "limited" versions. They correspond with standard library functions
'strcmp', 'strcpy', 'strcat', 'strncmp', 'strncpy' and 'strncat' found in header file <string.h>. In "unlimited" versions, I rely on the fact that we want to apply the operation
on entire strings, that those strings are null terminated and I used that in my advantage. For example, function 'string_compare' could be something like this:
on entire strings, that those strings are null terminated and I used that in my advantage. For example, function 'string_compare' could be something like example below. Also,
notice that 'destination / source' versus 'string_0 / string_1', which do you think is more readable?

@C
int string_compare (char * string_0, char * string_1) {
@@ -415,84 +416,4 @@ void terminal_show_cursor (int show) {
}
}

char * number_to_string (int number) {
int i, sign;

static char string [32];

for (i = 0; i != 32; ++i) {
string [i] = CHARACTER_NULL;
}

if (number == 0) {
string [0] = '0';
string [1] = CHARACTER_NULL;
return (string);
}

if (number < 0) {
number *= -1;
sign = 1;
} else {
sign = 0;
}

for (i = (string [0] == '-'); number != 0; ++i) {
string [i] = (char) (number % 10) + '0';
number /= 10;
}

if (sign != 0) {
string [i] = '-';
++i;
}

string [i] = CHARACTER_NULL;

string_reverse (string);

return (string);
}

char * format_to_string (int number, int sign, int base, int amount, char character) {
int i;

static char string [32];

for (i = 0; i != 32; ++i) {
string [i] = CHARACTER_NULL;
}

if (number == 0) {
string [0] = '0';
string [1] = CHARACTER_NULL;

string_realign (string, amount, character);

return (string);
}

if (number < 0) {
number *= -1;
}

for (i = (string [0] == '-'); number != 0; ++i) {
string [i] = "0123456789ABCDEF" [number % base];
number /= base;
}

if (sign != 0) {
string [i] = '-';
++i;
}

string [i] = CHARACTER_NULL;

string_reverse (string);

string_realign (string, amount, character);

return (string);
}

#endif

+ 35
- 17
chapter/chapter_0.h Näytä tiedosto

@@ -9,12 +9,12 @@ It is distributed in the hope that it will be useful or harmful, it really depen
#ifndef CHAPTER_0_HEADER
#define CHAPTER_0_HEADER

#include <stdlib.h> // We'll need this header file for malloc, calloc, realloc, free and exit.
#include <stdlib.h> // We'll need this header file for malloc, calloc, realloc, free, atexit, rand and exit (some will be used in future chapters).
#include <fcntl.h> // This one for open and O_ flags.
#include <unistd.h> // And this one for read, write, close and lseek.

/*
> Code formatting
Code formatting

It's very important that your code is aligned, readable and safe. So, we'll talk about it even before the first chapter, the so-called "zero chapter". I write assembly and Ada
beside C, but still, 90% of my projects are written in C programming language! Why? Because C is like a girl that's a bit older than you, quiet but very smart and respectable, and
@@ -28,7 +28,7 @@ the start, it should happen over time, naturally. Just be sure to always be cons

General code formatting should follow these rules in C programming language:

- Always use tabs for indentation, and spaces for alignment. You'll hear people say the otherwise, don't trust them, it's pure cancer.
- Always use tabs for indentation, and spaces for alignment. You'll hear people say the otherwise, don't trust them, they don't know.
- Separate most (not all!) operators with space before and after it. We'll provide exceptional cases for this rule below.
- Align most (not all!) operators horizontally, and logical units vertically. Again, examples are the best showcase.
- Always use curly braces and round braces, even when they're not required by the compiler. Most linters warn about this.
@@ -36,6 +36,7 @@ General code formatting should follow these rules in C programming language:
- Think very carefully if you'll limit the line length, it depends on your workflow and attention span... For me, 180 characters per line.
- If you want, use pagination, but I don't recommend it when working with C. I use it in Ada, because comments there start with "--".
- Always use snake case (this_style), for enumerations and macros (THIS_STYLE), and never put underscore before or after the identifier.
+ Feel free the break the rules if, by your jugdement, that will improve readability or emphasize the intention, I break them too.

For now, don't worry about what's an identifier, compiler, linter, those scary and unknown words will be explained later, when the time comes.

@@ -58,7 +59,7 @@ D) Again, same extension but for binary operators, that'll use left-hand variabl
E) Logical operators, and, or, not and operators '?' and ':' are used together, as they form ternary operator.
F) Comparison operators, equals, not-equals, less-or-equal, greater-or-equal, less and greater.

Some more symbols are also operators, but my advice is not to treat them as such, just consider them some kind of special cases.
Some more symbols are also operators (and some are not), but my advice is not to treat them as such, just consider them some kind of special cases.

- Before:

@@ -104,7 +105,7 @@ many function agruments, and always place them in consistent and logical order.
@C
// Internal and external function declaration:

static int string_copy_limit (char * string_0, char * string_1, int limit);
static int string_copy_limit (char * destination, char * source, int limit);

extern int32_t string_copy (char * string_a,
char * string_b,
@@ -115,6 +116,8 @@ extern size_t copy_string_n (
string_t b,
size_t n
);

// And you can improve last 2 examples by using 'destination' for 'string_0/a' and 'source' for 'string_1/b', since it's more clear what the function does.
@

Internal ('static') and external ('extern') variable declarations are different from function declarations, because you need to initialize internal variables to some value, I like
@@ -124,15 +127,19 @@ redeclaring them, some will warn you that they're already initialized to zero, s
@C
// Internal and external variable declaration:

static int curses_active = 0;
static int curses_active = 0; // You can declare and define internal variables right away, all in one line.
static char curses_signal = '\0';
static char * curses_screen = NULL;

extern unsigned int positive;
extern unsigned int positive; // You need to declare external variables without initializing them immediately.
extern int negative;
extern int * * coordinate_system;

static void (* encode_type_0 [TYPE_0_COUNT]) (void) = { NULL };
unsigned int positive = +1; // And then to define them separately, unlike internal variables.
int negative = -1;
int * * coordinate_system = NULL;

static void (* encode_type_0 [TYPE_0_COUNT]) (void) = { NULL }; // We're declaring arrays of function pointers this way, we'll cover them in later chapters.
static char * (* encode_type_1 [TYPE_1_COUNT]) (int l) = { NULL };
static int (* encode_type_2 [TYPE_2_COUNT]) (int l, int r) = { NULL };

@@ -142,20 +149,31 @@ extern xcb_pixmap_t blesses_pixmap;
extern xcb_connection_t * blesses_connection;
extern xcb_screen_t * blesses_screen;
extern xcb_image_t * blesses_image;

xcb_window_t blesses_window; // Here, same example for external variables, but you don't even need to initialize them.
xcb_gcontext_t blesses_context; // If you know what you're doing, and when they'll be initialized, you can leave them like this.
xcb_pixmap_t blesses_pixmap;
xcb_connection_t * blesses_connection;
xcb_screen_t * blesses_screen;
xcb_image_t * blesses_image;
@

Only for 'main' function, you shouldn't add 'static' or 'extern' keywords before it. Every C file needs to have exactly one 'main' function, it's the programs' entry point. Also,
some people like to define their own types, with keyword 'typedef', I'm not a fan of it, since in C types are also keywords unlike in Ada. Again, it'll become more clean in future
chapters why I dislike user-defined types, unions and structures.
chapters why I dislike user-defined types, unions and structures. That doesn't mean we won't use them tho, because I need to show-case their usage. Also, as for main function, it
can have either 'void' as argument, so the program takes no command-line arguments, or 'int argc' and 'char * * argv / char * argv []'.

@C
// Main function:

int main (int argc, char * * argv) {
int main (void) {

int32_t main (int32_t argc,
char * argv []) {

// Somewhere before with using 'typedef':
// typedef int number_t;
// typedef char * string_t;
number_t main (
number_t argc,
string_t argv []) {
@@ -170,7 +188,11 @@ enum { // This is completely unnecesary, but I don't care, it's a good showcase
TRUE
};

enum { // This is also one of my preferences, to use CHARACTER_NULL or CHARACTER_LINE_FEED instead of '\0' or '\n' in special (non-string) cases.
enum { // I use these to explicitly identify character literals outside of strings.
// This is also one of my preferences, to use CHARACTER_NULL or CHARACTER_LINE_FEED instead of '\0' or '\n' in special (non-string) cases.
// I align them like this, you can do whatever you want here, I just don't like to write a lot of short lines of code... I align long identifiers by 40 characters + indentation.
// 8 + 0 * 40 8 + 1 * 40 8 + 2 * 40 8 + 3 * 40
// ^ ^ ^ ^
CHARACTER_NULL, CHARACTER_START_HEADER, CHARACTER_START_TEXT, CHARACTER_END_TEXT,
CHARACTER_END_TRANSMISSION, CHARACTER_ENQUIRY, CHARACTER_ACKNOWLEDGE, CHARACTER_BELL,
CHARACTER_BACKSPACE, CHARACTER_TAB_HORIZONTAL, CHARACTER_LINE_FEED, CHARACTER_TAB_VERTICAL,
@@ -179,10 +201,10 @@ enum { // This is also one of my preferences, to use CHARACTER_NULL or CHARACTER
CHARACTER_DEVICE_CONTROL_4, CHARACTER_NOT_ACKNOWLEDGE, CHARACTER_SYNCHRONOUS_IDLE, CHARACTER_END_TRANSMISSION_BLOCK,
CHARACTER_CANCEL, CHARACTER_END_MEDIUM, CHARACTER_SUBSTITUTE, CHARACTER_ESCAPE,
CHARACTER_FILE_SEPARATOR, CHARACTER_GROUP_SEPARATOR, CHARACTER_RECORD_SEPARATOR, CHARACTER_UNIT_SEPARATOR,
CHARACTER_COUNT // Not an actual ASCII table count (128), but for starting invisible characters.
CHARACTER_COUNT // Not an actual ASCII table count (128), but for ending special invisible characters.
};

enum { // I like to align enumerations with 10, 20 or 40 characters per name, and optionally use NAME_ as prefix and NAME_COUNT as last element.
enum { // I like to align enumerations with 10, 20 or 40 characters per name, and optionally use NAME_ as prefix and NAME_COUNT as last element, look above...
EFFECT_NORMAL, EFFECT_BOLD, EFFECT_ITALIC, EFFECT_UNDERLINE, EFFECT_BLINK, EFFECT_REVERSE,
EFFECT_COUNT
};
@@ -228,8 +250,4 @@ extern void terminal_colour (int colour, int effect); // Set terminal chara
extern void terminal_cancel (void); // Reset terminal character attributes.
extern void terminal_show_cursor (int show); // Toggle rendering of terminal cursor.

// These will be useful in chapter three, where we'll learn about 'printf' function. It's too complex to cover it at this point.
extern char * number_to_string (int number);
extern char * format_to_string (int number, int sign, int base, int amount, char character);

#endif

+ 80
- 0
chapter/chapter_1.c Näytä tiedosto

@@ -226,4 +226,84 @@ void * file_record (char * name) {
return (data); // We return pointer to new memory, but remember, we have to free it later.
}

char * number_to_string (int number) {
int i, sign;

static char string [32];

for (i = 0; i != 32; ++i) {
string [i] = CHARACTER_NULL;
}

if (number == 0) {
string [0] = '0';
string [1] = CHARACTER_NULL;
return (string);
}

if (number < 0) {
number *= -1;
sign = 1;
} else {
sign = 0;
}

for (i = (string [0] == '-'); number != 0; ++i) {
string [i] = (char) (number % 10) + '0';
number /= 10;
}

if (sign != 0) {
string [i] = '-';
++i;
}

string [i] = CHARACTER_NULL;

string_reverse (string);

return (string);
}

char * format_to_string (int number, int sign, int base, int amount, char character) {
int i;

static char string [32];

for (i = 0; i != 32; ++i) {
string [i] = CHARACTER_NULL;
}

if (number == 0) {
string [0] = '0';
string [1] = CHARACTER_NULL;

string_realign (string, amount, character);

return (string);
}

if (number < 0) {
number *= -1;
}

for (i = (string [0] == '-'); number != 0; ++i) {
string [i] = "0123456789ABCDEF" [number % base];
number /= base;
}

if (sign != 0) {
string [i] = '-';
++i;
}

string [i] = CHARACTER_NULL;

string_reverse (string);

string_realign (string, amount, character);

return (string);
}

#endif

+ 61
- 11
chapter/chapter_1.h Näytä tiedosto

@@ -75,7 +75,11 @@ see that sometimes is preferable to use switch statement somewhere, or while loo
library that internally used structures everywhere, so you'll need to adapt to it, we'll see examples later...

So, real men need these keywords { char, int, void, sizeof, static, if, else, for, enum, return }, and use the rest of them in order to silence compiler warnings, use some
standard library functions, clean the source code or access an API / library / header file. Lets see some more examples and keep in mind code formatting...
standard library functions, clean the source code or access an API / library / header file. Lets see some more examples and keep in mind code formatting... Also, since this is a
book about C, I'll write comments and use those keywords I dislike, much to my dismay. You surely have different point of view on certain things than me, which is completely
natural, but always remember one thing:

There's a huge difference in being smart and in not being stupid. I'm simply not stupid, but I'm not smart, use this book to write something smarter than I did.

@C
extern int this_is_kind (kind_type this);
@@ -86,6 +90,9 @@ extern int this_is_kind (kind_type this);
// this - we named our argument about what's it supposed to be, use similar approach in return type, function, argument type and argument names.
@

You'll see this pattern a lot in my code, being consistent makes you more productive and efficient when doing any kind of task, from programming and studying foreign languages, to
cleaning your living room and washing your dishes. Be consistent no matter what you do.

Before continuing, lets describe some imporant types in C very simply:

Word: Bytes: Bits: Kind: Minimum: Maximum:
@@ -102,12 +109,13 @@ Before continuing, lets describe some imporant types in C very simply:
float 4 32 Real (IEEE754) / /
double 8 64 Real (IEEE754) / /

Note that you shouldn't care for now about 'void' and 'void *', because they're special cases, nor about their minimum and maximum. Also, the less types you use, the more
type-safe your code is. That's the reason why I use 'int', 'char *' and 'char', and sometimes 'void *' and 'int *'. You get less compiler and linter warnings about conversions,
but you need to know exactly what you're doing and what your code will do in order to have no bugs. Again, think twice, write once.
Note that you shouldn't care for now about 'void' and 'void *', because they're special cases, nor about their minimum and maximum. Also, the less types you use, the more type
safe your code is. That's the reason why I use 'int', 'char *' and 'char', and sometimes 'void *' and 'int *'. You get less compiler and linter warnings about conversions, but you
need to know exactly what you're doing and what your code will do in order to have no bugs. Again, think twice, write once. When I write programs in Ada language however, I make
a lot of types, since it's completely different language and has different coding practices.
*/

enum { // We won't even cover all of those, this is just an example of how to do similar task without hardcoding file extensions.
enum { // We won't even cover all of those file formats, this is just an example of how to do similar task without hardcoding file extensions, we'll use it later.
FILE_TYPE_TEXT, FILE_TYPE_COMMON_ASSEMBLY, FILE_TYPE_FLAT_ASSEMBLY, FILE_TYPE_GNU_ASSEMBLY,
FILE_TYPE_NETWIDE_ASSEMBLY, FILE_TYPE_YET_ANOTHER_ASSEMBLY, FILE_TYPE_C_SOURCE, FILE_TYPE_C_HEADER,
FILE_TYPE_ADA_BODY, FILE_TYPE_ADA_SPECIFICATION, FILE_TYPE_CPP_SOURCE, FILE_TYPE_CPP_HEADER,
@@ -116,16 +124,21 @@ enum { // We won't even cover all of those, this is just an example of how to do

/*
Here are some "utility" functions that we'll maybe use, reimplementation of those from standard library header file <ctype.h>. I prefer names like this, and this is for learning
purposes, so it's nice that you can see it here instead of searching through folders such as "/usr/include/". Lets talk about ASCII table now!
purposes, so it's nice that you can see it here instead of searching through folders such as "/usr/include/". But before that, lets talk about ASCII table now!

In functions 'character_is_uppercase', 'character_is_lowercase' and 'character_is_digit', we use characters that are in certain range on ASCII table, which we'll show just below.
So, it's safe to use '>=' and '<=' operators, but in other cases, we want to compare them selectively, and for simplicity we use function 'character_compare_array'... Here's how
ASCII table looks like, I don't like encodings like UTF-8 and others, so neither should you. We'll also write a subprogram that prints this to terminal or graphical window.

ASCII table:

- 0B: Binary representation.
- 0O: Octal representation.
- 0D: Decimal representation.
- 0X: Hexadecimal representation.
_______________________________________________________________________________________________________________________________________________________________
|_0B______|_0O__|_0D__|_0X_|_SYM_|_Full_name____________________________________|_0B______|_0O__|_0D__|_0X_|_SYM_|_Full_name____________________________________|
| | |
| | | | | | | | | | | | |
| 0000000 | 000 | 0 | 00 | NUL | Null | 0000001 | 001 | 1 | 01 | SOH | Start of heading |
| 0000010 | 002 | 2 | 02 | STX | Start of text | 0000011 | 003 | 3 | 03 | ETX | End of text |
| 0000100 | 004 | 4 | 04 | EOT | End of transmission | 0000101 | 005 | 5 | 05 | ENQ | Enquiry |
@@ -190,9 +203,42 @@ ASCII table:
| 1111010 | 172 | 122 | 7A | z | Lowercase z | 1111011 | 173 | 123 | 7B | { | Opening brace |
| 1111100 | 174 | 124 | 7C | | | Vertical bar | 1111101 | 175 | 125 | 7D | } | Closing brace |
| 1111110 | 176 | 126 | 7E | ~ | Tilde | 1111111 | 177 | 127 | 7F | DEL | Delete |
|_______________________________________________________________________________|_______________________________________________________________________________|

You can see that values of 'A' ... 'Z', 'a' ... 'z' and '0' ... '9' are sequential, but symbols and "system" characters are mixed up.
|_________|_____|_____|____|_____|______________________________________________|_________|_____|_____|____|_____|______________________________________________|

You can see that values of 'A' ... 'Z', 'a' ... 'z' and '0' ... '9' are sequential, but symbols and "system" characters are mixed up. You can also look at it this way:

- 0 ... 7: Upper 3 bits (0B0---0000).
- 0 ... F: Lower 4 bits (0B0000----).
___________________________________________________
|___|__0__|__1__|__2__|__3__|__4__|__5__|__6__|__7__|
| | | | | | | | | |
| 0 | NUL | DLE | | 0 | @ | P | ` | p |
| 1 | SOH | DC1 | ! | 1 | A | Q | a | q |
| 2 | STX | DC2 | " | 2 | B | R | b | r |
| 3 | ETX | DC3 | # | 3 | C | S | c | s |
| 4 | EOT | DC4 | $ | 4 | D | T | d | t |
| 5 | ENQ | NAK | % | 5 | E | U | e | u |
| 6 | ACK | SYN | & | 6 | F | V | f | v |
| 7 | BEL | ETB | ' | 7 | G | W | g | w |
| 8 | BS | CAN | ( | 8 | H | X | h | x |
| 9 | HT | EM | ) | 9 | I | Y | i | y |
| A | LF | SUB | * | : | J | Z | j | z |
| B | VT | ESC | + | ; | K | [ | k | { |
| C | FF | FS | , | < | L | \ | l | | |
| D | CR | GS | - | = | M | ] | m | } |
| E | SO | RS | . | > | N | ^ | n | ~ |
| F | SI | US | / | ? | O | _ | o | DEL |
|___|_____|_____|_____|_____|_____|_____|_____|_____|

You can notice that if you toggle 5th bit of alphabet characters, you can set them to lowercase or uppercase, since we're dealing with binaries in this case, when only 5th bit is
1, and others are 0, that's 2**5 (2 to the power of 5), which is 32, which is again equal to space character. That table also works for hexadecimals, you can see that for example,
character 'H' is in '4' column and '8' row, so hexadecimal value for character literal 'H' is 0X48. Of course, there's no need to memorize any of those, they can just be handy if
you feel exceptionally smart and want to do some bit manipulation on strings.

Lets talk very shortly about C preprocessor, I don't like to use it, but sometimes you have to, and I'll show few useful examples in later chapters. Note that you can make a
complete project in C programming language, without using the preprocessor even once, but since modern programs are large and often split into separate source files, and there's
no truly good build system (in any language), people use them in order not to copy paste structures, unions, enumerations and function declarations, and global variables were
villified because of multiple people working on the same project, and fucking things up. I felt the need to repeat this below too...

In C language, we have C source files with the extension '.c', and C header files with the extension '.h'. Both of those are just plain text files, and please use 7-bit ASCII
encoding, since it's common sense, UTF is cancer, and 8-bit ASCII is for enlightened people like Terrence Andrew Davis. C language is completely separate (on some C compilers)
@@ -220,7 +266,7 @@ wooden wheels attached to it.
*/

extern int character_is_uppercase (char character); // Notice how we align those functions, I believe this improves the readability of any program, in any programming language.
extern int character_is_lowercase (char character); // Some people would just use 'ischrupp' or something, but I hate reading code written like that...
extern int character_is_lowercase (char character); // Some people would just use 'ischrlow' or 'islower', but I hate reading code written like that...
extern int character_is_digit (char character); // Important note is also that a programming language is not, and it should be like natural language, why?
extern int character_is_blank (char character); // Because we need strict rules in programming language, same like in mathematical languages, now now, don't be scared.
extern int character_is_alpha (char character);
@@ -248,4 +294,8 @@ extern int file_size (char * name); // We get the size
extern int file_type (char * name); // We get the type of the file by its' 'name' (by file name extension).
extern void * file_record (char * name); // We store an entire file into some memory address.

// These will be useful in chapter three, where we'll learn about 'printf' function. It's too complex to cover it at this point.
extern char * number_to_string (int number);
extern char * format_to_string (int number, int sign, int base, int amount, char character);

#endif

+ 28
- 0
program/program_0.c Näytä tiedosto

@@ -0,0 +1,28 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic

Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/

#include "../chapter/chapter_0.c"

static void cool_echo (char * text, int colour, int effect);

static void heyo (void) { cool_echo ("Heyo world!\n", COLOUR_GREEN, EFFECT_BOLD); }
static void cyaa (void) { cool_echo ("Cyaa world!\n", COLOUR_RED, EFFECT_BOLD); }

int main (void) {
heyo ();

cyaa ();

return (EXIT_SUCCESS);
}

void cool_echo (char * text, int colour, int effect) {
terminal_colour (colour, effect);
echo (text);
terminal_cancel ();
}

+ 10
- 10
xhartae.c Näytä tiedosto

@@ -66,13 +66,13 @@ Why should you learn or use C programming language in 2023?
Goal of this so-called book?

- You'll be able to write your own compiler or interpretter, for your own language after reading this, and many more programs.
- You might learn something new. My target audience is people who don't know C languages, but maybe there's something new for you.
- You might learn something new. My target audience is people who don't know C language, but maybe there's something new for you.
- You won't (hopefully) buy into big ideas and paradigms about programming, you'll just create programs, and have fun doing so.

Before we get into it, there are some requirements that this book is based on. Thou shalt use GNU/systemd/Linux operating system, commonly and wrongly refered to as Linux OS or
just simply distro (distribution). They come in many flavours, so if you're new to this, you could just install BunsenLabs, LXLE or Mint on some old laptop, if you don't want to
switch totally from spyware known as Windows (niche OS made for games). You'll revive your old laptop that was useless, and you support free software by doing so, making you a
part of the revolution. Beside that, you'll need a C compiler such as TCC, GCC (which is preinstalled on most distros) or Clang, and lastly Valgrind and Splint, to verify the
just simply distro (distribution). They come in many flavours, so if you're new to this, you could just install BunsenLabs, LXLE or Mint on some old laptop, if you want to finally
switch totally from spyware known as Windows (niche OS made for games). You'll revive your old laptop that was useless, and you support free software by doing so, making yourself
a part of the revolution. Beside that, you'll need a C compiler such as TCC, GCC (which is preinstalled on most distros) or Clang, and lastly Valgrind and Splint, to verify the
quality of your C source code. Text editor or IDE is a trivial thing at the begining, but it'll shape your coding style in the long run. Lets talk about them.

GNU/Linux operating systems:
@@ -106,14 +106,14 @@ Text editors or IDEs (integrated development environments):
- ed: It's the STANDARD text editor for UNIX-based operating systems. Nothing else can be said, it's literally the best tool I've ever seen, and I use it sometimes.
- kilo: Terminal text editor, written in C language, less than 1000 lines of code. It's nice, simple and usable, and you can extend it once you learn C.
- nano: Also terminal text editor, very simple to use, but some prefer micro over it. You gotta admit, people are very creative when naming their software...
- Vim: Beast of an editor, once you learn how to exit it, you'll be like a Gott to other non-Vim users. I won't tell you how to exit it. I don't know.
- Emacs: Yet another beast of an editor, your pinky finger will be twice stronger because of it. It has many extensions and all PROs use it.
- Vim: Beast of an editor, once you learn how to exit it, you'll be like a Gott to other non-Vim users. I won't tell you how to quit Vim. I don't know.
- Emacs: Not a text editor, but an entire operating system, your pinky finger will be twice stronger because of it. It has many extensions and all PROs use it.
- Mousepad: State of the art text editor, it works same as Notepad, but it's more based. You really don't need anything more complex than this for editing a text file.
- Geany: I use it most of the time, but I switch to nano, Emacs, my own text editor whenever I feel like it, in order not to limit myself to just one tool.

Jokes aside, don't obesess over any distro (as long as it's some kind of Linux, BSD is cucked), any kind of compiler and any kind of text editor! You only want to edit text file,
insert and delete few lines of code, nothing more. You don't need some IDE (bloated text editor) that uses 2 GiB or RAM, opens up after 10s of blank window, and work slow overall.
Just don't use any of the following for reasons you'll understand once your grow up: Windows, MSVC, VS Code, Visual Studio, Atom, Helix, Kakoune, Eclipse, Sublime.
insert and delete few lines of code, nothing more. You don't need some IDE (bloated text editor) that uses 2 GiB or RAM, opens up after 10s of blank window, or works slow overall.
Just don't use any of the following for reasons you'll understand once your grow up: Windows, MacOS, MSVC, ICC, VS Code, Visual Studio, Atom, Helix, Kakoune, Eclipse, Sublime.

One sane C program should have the following structure (please keep in mind that this is a book, not a sane program, thanks...):

@@ -126,14 +126,14 @@ One sane C program should have the following structure (please keep in mind that
6) Internal function then variable definition.
7) External function then variable definition.
8) Main function.
9) You can also define functions here if you want to.
*/

int main (int argc, char * * argv) {
(void) argc;
(void) argv;

//~preview_c_file ("program/example.c", 5, 1);
preview_c_file ("chapter/chapter_0.c", 0, 0);
preview_c_file ("program/example.c", 0, 0);

return (EXIT_SUCCESS);
}

Loading…
Peruuta
Tallenna