Very tiny text added...
This commit is contained in:
parent
839f92f40f
commit
755d47d478
@ -50,7 +50,7 @@ void echo (char * string) {
|
||||
}
|
||||
|
||||
void fatal_failure (int condition, char * message) { // We use this function to abort the program if condition is met and to print the message.
|
||||
if (condition == FALSE) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces.
|
||||
if (condition == TRUE) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces.
|
||||
echo ("[\033[1;31mExiting\033[0m] "); // Simply printing the message using our 'echo' function, but we also use some colours, more on that later.
|
||||
echo (message); // Also, notice how "this or that" is implicity 'char *' type... Maybe it's too early to explain it at this point.
|
||||
echo ("\n"); // This will only print a new line, we'll see how to use it later.
|
||||
@ -167,57 +167,64 @@ int string_compare (char * string_0, char * string_1) {
|
||||
}
|
||||
@
|
||||
|
||||
And I used this approach below to show that you can solve the problem using different solutions...
|
||||
And I used this approach below to show that you can solve the problem using different solutions... You'll notice that "limited" versions have variable 'offset' of type integer. We
|
||||
use it to interate the strings, while in "unlimited" versions, we iterate on pointers to those strings, which are pushed to the stack. Both versions work, both versions give the
|
||||
same results, you can use any of them.
|
||||
*/
|
||||
|
||||
int string_compare (char * string_0, char * string_1) {
|
||||
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer.");
|
||||
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer."); // This will be seen in next 5 functions too, we don't want NULL here.
|
||||
fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer.");
|
||||
|
||||
for (; (* string_0 != CHARACTER_NULL) && (* string_1 != CHARACTER_NULL); ++string_0, ++string_1) {
|
||||
if (* string_0 != * string_1) {
|
||||
return (FALSE);
|
||||
for (; (* string_0 != CHARACTER_NULL) && (* string_1 != CHARACTER_NULL); ++string_0, ++string_1) { // We iterate until either string reaches the null character.
|
||||
if (* string_0 != * string_1) { // In case that characters at the same offset are different:
|
||||
return (FALSE); // > We return FALSE, 0, since strings aren't the same...
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
return (TRUE); // Otherwise, strings are same, we return TRUE, 1.
|
||||
}
|
||||
|
||||
char * string_copy (char * string_0, char * string_1) {
|
||||
fatal_failure (string_0 == NULL, "string_copy: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_copy: Source string is null pointer.");
|
||||
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) {
|
||||
* string_0 = * string_1;
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { // This time and in next function, we iterate only source string.
|
||||
* string_0 = * string_1; // And we assign character at the same offset to destination string (aka copy it).
|
||||
}
|
||||
|
||||
* string_0 = * string_1; // Copying null termination, since the loop stopped on that condition.
|
||||
* string_0 = * string_1; // Copying null termination, since the loop stopped on that condition.
|
||||
|
||||
return (string_0);
|
||||
return (string_0); // Lastly, we return the destination string, in order to be able to bind functions.
|
||||
}
|
||||
|
||||
char * string_concatenate (char * string_0, char * string_1) {
|
||||
fatal_failure (string_0 == NULL, "string_concatenate: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_concatenate: Source string is null pointer.");
|
||||
|
||||
string_0 += string_length (string_0);
|
||||
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) {
|
||||
* string_0 = * string_1;
|
||||
string_0 += string_length (string_0); // We'll first offset destination string to the end of it.
|
||||
// Because we want to start copying from the end, aka concatenate it.
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { // The rest of the function is same as string_copy, so:
|
||||
* string_0 = * string_1; // We could even use it here, but that defies the purpose of learning now.
|
||||
}
|
||||
|
||||
* string_0 = CHARACTER_NULL;
|
||||
* string_0 = CHARACTER_NULL; // Again, assign null termination.
|
||||
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
/*
|
||||
As for "limited" versions of previous 3 functions, they do the same thing, but are capped to some variable 'limit'. These functions have their own use-case, for example, if
|
||||
strings aren't null terminated, if you're not sure that they are null terminated, if we're dealing with binary (not textual) data (casted to char *), and many more cases.
|
||||
*/
|
||||
|
||||
int string_compare_limit (char * string_0, char * string_1, int limit) {
|
||||
int offset;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_compare_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_compare_limit: Source string is null pointer.");
|
||||
|
||||
for (offset = 0; offset != limit; ++offset) {
|
||||
for (offset = 0; offset < limit; ++offset) {
|
||||
if (string_0 [offset] != string_1 [offset]) {
|
||||
return (FALSE);
|
||||
}
|
||||
@ -230,12 +237,13 @@ char * string_copy_limit (char * string_0, char * string_1, int limit) {
|
||||
int offset;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_copy_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_copy_limit: Source string is null pointer.");
|
||||
|
||||
if ((limit <= 0) || (string_1 == NULL)) {
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
for (offset = 0; offset != limit; ++offset) {
|
||||
for (offset = 0; offset < limit; ++offset) {
|
||||
string_0 [offset] = string_1 [offset];
|
||||
}
|
||||
|
||||
@ -246,6 +254,7 @@ char * string_concatenate_limit (char * string_0, char * string_1, int limit) {
|
||||
int offset, length_0, length_1;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_concatenate_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_concatenate_limit: Source string is null pointer.");
|
||||
|
||||
if ((limit <= 0) || (string_1 == NULL)) {
|
||||
return (string_0);
|
||||
@ -254,7 +263,7 @@ char * string_concatenate_limit (char * string_0, char * string_1, int limit) {
|
||||
length_0 = string_length (string_0);
|
||||
length_1 = string_length (string_1);
|
||||
|
||||
for (offset = 0; (offset != length_1) && (offset != limit); ++offset) {
|
||||
for (offset = 0; (offset < length_1) && (offset < limit); ++offset) {
|
||||
string_0 [length_0 + offset] = string_1 [offset];
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ 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
|
||||
CHARACTER_COUNT // Not an actual ASCII table count (128), but for starting 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.
|
||||
@ -209,11 +209,11 @@ extern void * deallocate (void * data );
|
||||
|
||||
extern int string_length (char * string); // We deal with strings a lot in this program, so string functions will be more important than character functions from chapter one.
|
||||
|
||||
extern int string_compare (char * string_0, char * string_1);
|
||||
extern int string_compare (char * string_0, char * string_1); // See how nicely they align, right?
|
||||
extern char * string_copy (char * string_0, char * string_1);
|
||||
extern char * string_concatenate (char * string_0, char * string_1);
|
||||
|
||||
extern int string_compare_limit (char * string_0, char * string_1, int limit);
|
||||
extern int string_compare_limit (char * string_0, char * string_1, int limit); // These ones too, it's beautiful (in my opinion), tho some consider it useless.
|
||||
extern char * string_copy_limit (char * string_0, char * string_1, int limit);
|
||||
extern char * string_concatenate_limit (char * string_0, char * string_1, int limit);
|
||||
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
set -xe
|
||||
|
||||
gcc -Wall -Wextra -Wpedantic -Werror -Ofast -c -o chapters/chapter_0.o chapters/chapter_0.c
|
||||
gcc -Wall -Wextra -Wpedantic -Werror -Ofast -c -o chapters/chapter_1.o chapters/chapter_1.c
|
||||
gcc -Wall -Wextra -Wpedantic -Werror -Ofast -c -o chapters/chapter_2.o chapters/chapter_2.c
|
||||
gcc -g -Wall -Wextra -Wpedantic -Werror -O0 -c -o chapters/chapter_0.o chapters/chapter_0.c
|
||||
gcc -g -Wall -Wextra -Wpedantic -Werror -O0 -c -o chapters/chapter_1.o chapters/chapter_1.c
|
||||
gcc -g -Wall -Wextra -Wpedantic -Werror -O0 -c -o chapters/chapter_2.o chapters/chapter_2.c
|
||||
|
||||
gcc -Wall -Wextra -Wpedantic -Werror -Ofast -c -o xhartae.o xhartae.c
|
||||
gcc -g -Wall -Wextra -Wpedantic -Werror -O0 -c -o xhartae.o xhartae.c
|
||||
|
||||
gcc -o xhartae xhartae.o chapters/chapter_0.o chapters/chapter_1.o chapters/chapter_2.o
|
||||
|
||||
|
@ -29,7 +29,7 @@ Why should you learn or use C programming language in 2023?
|
||||
- C can interface with huge variety of other distinct programming languages.
|
||||
- C can be a lot more readable, faster and easier if used well.
|
||||
|
||||
One sane C program should have the following structure:
|
||||
One sane C program should have the following structure (please keep in mind that this is a book, not a sane program, thanks...):
|
||||
|
||||
0) Optional file, author or license information in comment.
|
||||
1) Header guards and implementation definitions.
|
||||
|
Loading…
Reference in New Issue
Block a user