ソースを参照

Minor fixes again...

master
コミット
84eaa15282
4個のファイルの変更20行の追加14行の削除
  1. +2
    -3
      chapter/chapter_0.c
  2. +3
    -2
      chapter/chapter_1.c
  3. +8
    -5
      chapter/chapter_2.c
  4. +7
    -4
      chapter/chapter_2.h

+ 2
- 3
chapter/chapter_0.c ファイルの表示

@@ -345,7 +345,7 @@ char * string_realign (char * string, int amount, char character) { //
}

/*
Ignore what next two functions do, it's about memory management that we'll cover in later chapters.
Ignore what next two functions do, it's about memory stuff that we'll cover in later chapters.
*/

int memory_compare (void * destination, void * source, int length) {
@@ -387,8 +387,7 @@ void memory_copy (void * destination, void * source, int length) {
}

/*
Again, please consider these 'terminal_*' functions black magic, as well as 'number_to_string' and 'format_to_string' as they are more complex to cover them at this point, we'll
talk more about them later... For now, just take a look at how I format the code in them.
Again, please consider these 'terminal_*' functions some form of black magic... For now, just take a look at how I format the code in them.
*/

void terminal_clear (void) {


+ 3
- 2
chapter/chapter_1.c ファイルの表示

@@ -174,8 +174,9 @@ int file_size (char * name) {
int size = -1; // Lets just assume that everything is wrong, everything falls apart...
int file = -1; // Everything is just -1 around us...

file = file_open (name, O_RDONLY); // We open a file to read it.
size = (int) lseek (file, 0, SEEK_END); // We set the offset to the end of the file.
file = file_open (name, O_RDONLY); // We open a file to read it.

size = (int) lseek (file, 0, SEEK_END); // We set the offset to the end of the file.

fatal_failure (size == -1, "file_size: Failed to get size of file, invalid file size."); // Again, error of 'lseek' would be -1, so we check for that...



+ 8
- 5
chapter/chapter_2.c ファイルの表示

@@ -114,8 +114,8 @@ goes for functions declared in "chapter_2.h", but there's another trick to this.

@C
// Option A:
static void * my_function (char * name, int size);
static int my_function (char * name, int size);
// ...
int my_function (char * name, int size) {
int data = 0;

@@ -136,7 +136,7 @@ static int my_function (char * name, int size) {

Okay, external variables you see lower (without 'static') are all integers. Lets briefly see what types are the internal variables.

- curses_format / curses_format: Array of characters (also known as string!), and their size is already known at the compile time, it's inside square braces.
- curses_format / curses_cursor: Array of characters (also known as string!), and their size is already known at the compile time, it's inside square braces.
- curses_screen: Pointer to character, we'll allocate memory for it later, so it'll be a dynamic array of characters, its' size can change.
- curses_activator: Pointer to integer, we'll also allocate memory for it, so we can't use square braces for those. Remember that for later.
- curses_action: Strictly speaking, pointer to another pointer to function of signature 'void SOMETHING (void);', but ignore it for now, don't get confused.
@@ -255,13 +255,15 @@ comes from top of my head is 'echo' function from chapter zero. It'd be boring t
string literals to terminal in most cases. But that doesn't mean that 'out' is useless, as you'll see, we'll use it in 'curses_synchronize' funcion. Cons are, if you really have
repeating code all over your program, if there's a bug in one of them, there's a bug in all of them. Also, if you'll use some extracted function (also refered to as refactored in
some cases) only once, it's not a bad thing. We've extracted some code into 'curses_initialize' function, and we call it only once, inside 'curses_configure' function, but the
intention behind what it does is clear. However, I still believe that procedural code, that's executed line by line, from top to bottom, is best.
intention behind what it does is clear. However, I still believe that procedural code, that's executed line by line, from top to bottom, is best. You can use 'curses_configure'
and main loop with 'curses_synchronize' inside more functions, and it'll clean itself after the program exits.

Now, we could also implement some error checking functions for 'curses_*' functions. Good idea, when something is wrong, like we want to render a character out of the screen, we
just print an error message to terminal, right? Well, no. Remember, we're using terminal as a framebuffer (about which we'll talk about a lot more in ray tracing and rasterization
chapters), so if we just print message there, it'll corrupt our framebuffer. So, we could just write them to some log file. How about binding them, whenever something is wrong,
we don't just abort the program or stop rendering, but continue running it, while also writing error messages to that same file. Then, when we exit the program, it'll print all
error messages (if any) normally. Here's how it would look like:
error messages (if any) normally. It could be done like something below, but since I know what I'm doing (for the most part), I'll just comment them out inside functions, and
leave 'log_in' and 'log_out' unimplemented.

@C
// Enumeration for log type.
@@ -428,6 +430,7 @@ void curses_render_character (char character, int colour, int effect, int x, int
if ((x < 0) || (x > curses_screen_width - 1) || (y < 0) || (y > curses_screen_height - 1)) { // If any of these are true, we don't render.
return;
}

// Again, lets show some code formatting examples:
// if ((x < 0)
// || (y < 0)


+ 7
- 4
chapter/chapter_2.h ファイルの表示

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

#include <stdio.h> // We need this header file for functions 'puts' and 'printf'.
#include <stdio.h> // We need this header file for functions 'puts' and 'printf' in 'hello_world' functions below.
#include <unistd.h> // And in this header file we have write system call.

/*
@@ -17,7 +17,8 @@ Lets talk about function declaration. In C, sometimes you need to declare functi
quickly prototyping something out. Function declarations are property of old programming languages, you don't have to use them if you're calling every function after it's defined
(but not declared, there's a difference), but if that function is only used in one file, you should use 'static' keyword like in the example below. Keyword 'extern' tells the
compiler that your function will be used in other files, or if you're compiling your files separately, it won't add the function address (in some cases). In any case, function
declarations should be in C header file, and function definitions should be in C source file.
declarations should be in C header file, and function definitions should be in C source file. You can see how I declare functions in '.h' files, and define them in '.c' files,
unless I don't want to make some function external in some '.c' file, I use 'static' there.

@C
// Function declaration: // # // Output: // Input:
@@ -55,7 +56,8 @@ Now, lets talk very briefly about what's wrong with 'PLEASE_NO':
- Keep in mind that newer (non-ANSI) C standards allow some of the things that I'm not using here, but I don't personally like newer C standards, I'll mention that a lot.
- Last one is tricky, you should name function agruments in function declarations, but some linters will warn you not to do it, since some compiler don't check them.

Very soon, you'll be able to write your own small C programs, so prepare for it.
Very soon, you'll be able to write your own small C programs, so prepare for it. Also, the most important chemical element for organisms is, you guessed it, C (carbon). It's
the same in programming too, C is the most important language that a good programmer should know. Other languages are just extra. Now:

This is probably the first program new programmers write in language they're learning. It simply prints text to standard output. As C is very old programming language, you have a
lot of ways to do it, so we'll simply put all of them into array of function pointers, and call them sequentially in loop in our main function.
@@ -116,7 +118,8 @@ These below are external variables, they can be accessed and modified in any fil
output object files (.o), and then we can link them together (most compilers are also linkers, this is nothing out of ordinary) into final executable. We can, for example, use
functions declared in "chapter_2.h" and defined in "chapter_2.c" in completely separate file "chapter_3.c", if we have included it with '#include "chapter_2.h". Keep in mind that
header files can be included recursively, that's why we use those header guards, '#ifndef SOMETHING', '#define SOMETHING' and '#endif' at the end. That way, they'll be included
only once, so compiler won't be confused and spit out errors.
only once, so compiler won't be confused and spit out errors. You can see how I use those chapters to create new programs, and all that is in 'program/' folder. You can also just
open some 'compile.sh' file or 'makefile' and see how I compile and link.

Now, lets talk about ASCII escape sequences. Most terminals support some special combination of characters, that aren't printed like you'd normally expect. We call them escape
sequences because they all start with character literal '\033', '\x1b' or '\e', which is same as decimal 27, and in our character enumeration 'CHARACTER_ESCAPE'. They are somewhat


読み込み中…
キャンセル
保存