forked from xolatile/xhartae
66 lines
4.6 KiB
C
66 lines
4.6 KiB
C
|
/*
|
||
|
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.
|
||
|
*/
|
||
|
|
||
|
#ifndef CHAPTER_2_HEADER
|
||
|
#define CHAPTER_2_HEADER
|
||
|
|
||
|
/*
|
||
|
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.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h> /* We need this header file for functions 'puts' and 'printf'. */
|
||
|
#include <unistd.h> /* And in this header file we have write system call. */
|
||
|
|
||
|
/*
|
||
|
Lets talk about function declaration. In C, sometimes you need to declare functions that you'll use before they're called. I prefer to always declare functions except when I'm
|
||
|
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.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
// Function declaration: Output: Input:
|
||
|
extern void function_0 (void); // undefined (none) // undefined (none)
|
||
|
extern float function_1 (double a); // ieee754_32b // ieee754_64b
|
||
|
extern int function_2 (int a, int b); // integer_32b // integer_32b, integer_32b
|
||
|
static unsigned int function_3 (char * a, int b, char c); // natural_32b // integer_8b_pointer, integer_32b, integer_8b
|
||
|
static char * function_4 (char * a); // integer_8b_pointer // integer_8b_pointer
|
||
|
static void * function_5 (struct structure * a, void * b); // undefined_pointer // [structure]_pointer, undefined_pointer
|
||
|
|
||
|
extern unsigned long int * PLEASE_NO (const signed short int, void *, const char const * *, long double []);
|
||
|
**/
|
||
|
|
||
|
/*
|
||
|
So, lets go through those 6 normal functions, and then lets see what's wrong with 'PLEASE_NO' function.
|
||
|
0) This is the simplest form of function, which can be used to make the code more clear (sometimes) by breaking down long functions into smaller ones, and calling them in certain
|
||
|
order. However, don't abuse it for code refactoring, because most of the time, procedural is the easiest to read, write and debug.
|
||
|
1) In C (and in non-embedded environment, also known as your normal post-2012 laptop or computer), keyword 'float' is (almost) real number encoded in IEEE754, 32 bits or 4 bytes
|
||
|
long, while keyword 'double' is same as float, but enlarged to 64 bits or 8 bytes. They are pain to use in some cases because of limited precision.
|
||
|
2)
|
||
|
3)
|
||
|
4)
|
||
|
5)
|
||
|
Now, lets talk very briefly about what's wrong with 'PLEASE_NO':
|
||
|
- Don't use long types 'unsigned long int', if you really type with those characteristics, use 'size_t : stdlib', 'uint64_t : stdint' or 'unsigned long'.
|
||
|
- Don't use 'const' keyword at all, that's my honest advice, it won't catch bugs in C, it'll cause useless compiler warnings. Live unsafe, think more.
|
||
|
- Don't use 'signed', since it's default for any integer type, as well as you shouldn't use keywords 'register', 'volatile', 'auto', but more on that later...
|
||
|
- You can use '[]' in function declarations, but it doesn't mean much since array is passed as pointer to first element in C, so '*' is enough.
|
||
|
- 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.
|
||
|
*/
|
||
|
|
||
|
extern void hello_world_0 (void); /* All 4 functions take no agruments, and return nothing. They just execute the code that's defined in them. */
|
||
|
extern void hello_world_1 (void);
|
||
|
extern void hello_world_2 (void);
|
||
|
extern void hello_world_3 (void);
|
||
|
|
||
|
extern void (* hello_world [4]) (void); /* External (global) variable with name 'hello_world' of type 'array of 4 function pointers with no input/output'. */
|
||
|
|
||
|
#endif
|