Saturday, August 24, 2024

C Programming for dummies



There is always something new to learn (or is there).



I am currently reading "C Programming for Dummies" 2nd edition by Dan Gookin. I decided to take it out of my local library. mainly because I had it on my wish list and I don't have anything else to read at the moment. I have books on C that I have had since the 90's. I read through them when I am trying to figure something out. Usually, it has to do with pointers. I have not had any formal training on C. I have taken a class on C++. and that did cause some confusion as I assumed certain things I learned about C++ were inherited from C. While, one thing I discovered is function overloading is not in C. So I am reading this book to find things I did not already know about the C programming language. It has been 2 days and so far I am up to chapter 7 (of 27) and have not discovered anything of note yet. I have come across a few things that are simplified for the sake of not having to go down the rabbit hole on what may be edge cases. sort of like how teachers in grade school said "A sentence can't start with because" As I discover new knowledge I will write it here and post it when I am done with the book (and have edited the blog of course).

So, the first thing that catches my attention is in chapter 7. I don't often use the getchar() function, so it did catch me off guard that it returns an int and not a char. I assume there is a reason, such as that in some languages/character sets a single character is more than 1 byte. and I need to check the sizeof(char) but I think it varies, but an int is almost always more than 1 byte. off the top of my head, I believe the standard is at least 4 bytes but can vary depending on architecture. I have not done any coding on this (yet) . I am just free-writing as I read the book. I have had issues when I needed a data type to be exactly 1 byte and tried to use char with differing results depending on the system and compiler. The more reliable way is to use uint8_t. I will try later to see if that data type works with getchar(). This goes for putchar(int) instead of putchar(char).

Also in chapter 7, it does what several other books I have read when it comes to pointers. it introduces functions like scanf() before explaining pointers. it just says put a & in front of the variable without explaining why. When I first started teaching myself C, I just followed the syntax without questioning why. I think pointers are confusing to new programmers (and experienced programmers) partly because pointers are generally taught as an afterthought. The chapter on pointers is 18; I will see if they are mentioned before then. and as soon as I wrote that last sentence I turned the page and there is one line that said "Part 4 of this book covers pointers" Chapter 18 is in part 4 by the way.

in chapter 8 which deals with decision making the author discusses the ternary operator. I did know of the ternary operator from a video by Jacob Sorber (https://www.youtube.com/watch?v=PfMV_wa0KY4), but I have not used it myself.

something I had not used in C but thought existed was until loops. While reading chapter 9 on loops I thought it was something they omitted at first, but I checked the keyword list and man documentation (or lack thereof) and discovered that I was getting syntax mixed up between languages (probably MS Basic and VB). An until loop is just a negated while loop so including it would be redundant to some degree. I assume a macro could be made so that they until(expression) equals while(!(expression)). I wonder if this book goes into macros.

In chapter 11 (the math chapter) something sounded familiar but I am not fully sure if I knew it. and this involves trig functions. I have used trig but I don't know if I used it in C (or any programming language) in C trig functions use radians and not degrees. This is kind of important to know. 90% of the time when I do use trig I am doing it in degrees, so I would need to make a conscious effort to use radians.

Another of these mathematical equations is with order of precedence. When you are writing literals it is easier to keep track of the order of operations. When you have variables and constants I like to add parentheses () to make things clearer on what happens first.

I read through chapter 12 (arrays) wondering when they will address pointers. and it was like the final paragraph. and they just said that it would be addressed in a later chapter. I don't understand why arrays are always taught that way after the fact. just pull the bandaid off and get through it. It makes things clearer.

On another note, I don't think I have used multidimensional arrays beyond 2 dimensions.

ok so in chapter 13 which deals with text manipulation, they say the "functions" in ctype.h are not functions but are macros. I mentioned before that they did not mention macros in the chapter on functions or when discussing #define. Now that is not going to confuse anyone. But, now I do want to read ctypes.h to see what the macros are doing.

The functions in string.h do give me issues and I tend to use the man pages often when dealing with string manipulation. and sometimes sprintf() is your friend, but snprintf() could be a safer path.


ok halfway through, nine days until I need to return (or renew) the book from the library.

Chapter 15 was on command line arguments using argc and argv depending on the compiler and os there could be others but this book does not discuss them and I am not sure if they are standardized. but if you are designing a program to be executed by a script or other processes then command line arguments are important. and without dealing with pointers (yet) and coping with argv as just an array and not a pointer aspect can get confusing down the line.

I am about to start chapter 16 on variables, let's see if they discuss pointers... halfway through the chapter and I don't see pointers mentioned. but I do want to talk about typedef and structs. For a while, I thought if you used something like "struct qwerty..." in C you could use qwerty as a data type like you can in C++. In C++ structs and classes are usable by the class name right away without using typedef.

again a perfect point to even just mention pointers... when discussing global variables and passing by value they could mention passing by reference and using pointers.

Chapter 17 is on binary/bitwise manipulation. This is a topic I know of but I need to look it up each time I use it. If you have seen my Raspberry Pi Pico video series on my YouTube channel you will see me using it in Python. but even then it was limited and I had to keep looking up the documentation. and That was a while ago so I need to recheck the code to see how I did it. I do know that when I went to reprogram it in C/C++ I didn't get that far. First, it is written in C++ because the SDK for the pico is set with C++ classes, but I code C++ like C with classes most times and stuff like that drives C++ programmers nuts. and I really need to get back to that project.

In the book they say XOR is pronounced "zor" . I have always heard it as "ex or". from programming classes to logic (philosophy) classes to YouTube tutorials. I am pretty sure Ben Eater says "ex or" when dealing with digital logic chips. and for those that don't know XOR is exclusive OR in logic.

I wish the book went more in-depth with hex. I don't know if they will but Chapter 17 sort of glossed over it. it does come in handy when dealing with binary with something like register flags.


chapter 18 and we finally get to pointers. it only took 269 pages (of 409 not counting appendixes). so I didn't start to understand pointers really until I started looking at assembly. I understand assembly at the concept level but I have coded basic stuff in 6502 and x86 assembly but I don't know any variant of assembly to program something from scratch in it. but when you understand what assembly is doing you understand that all variables are pointers. A variable name is just a reference to a place in memory where the value is stored. C adds a layer of abstraction to it and like all C instructions it is broken down into multiple assembly instructions. In assembly, the variable name is just a label. I would use the goto command as an example but I don't think this book even mentions goto besides listing it as a C keyword. Let's say we have a C variable X and X is an int. Let's say in this case an int is 4 bytes. So if we need the value of X what C does is it gets the value in memory of where X points to and the next 3 bytes (4 bytes total) this chapter did not really cover pass-by-value and pass-by-reference. I will guess the next chapter (also on pointers) will.

chapter 19 starts out with pointer arithmetic and comparing it to arrays. and then goes into strings are char arrays (which was mentioned earlier in the book) but then goes into strings are char pointers. Again once you understand how assembly treats memory (because this is how the computer handles memory) you can understand this better.

then it introduces the double-pointer. not to be confused with a double pointer. are you confused a double-pointer (**name) is a pointer to a pointer basically a 2-dimensional array (name[][]) where a double pointer is (double *name). so what is (double **name) is this a double-double-pointer? and with 2 pages left in the chapter they cover passing a pointer to a function (pass by reference)

Chapter 20 and now we have malloc(). I am speed-reading this. otherwise, I would be falling asleep on each page. and it is not because of the way it is written but because I know most of this already. Do I remember it verbatim? no. that is why I use man pages and other tools (stack overflow, google, etc) when I am programming. That being said it talks about casing when using malloc() but it does not mention that malloc() returns a void pointer. and in turn, does not discuss void pointers. I just checked the index and of the 3 pages listed for the void data type, only one has a sentence that mentions void pointers.

now to linked lists. something else that I am aware of but don't think I have used. Not much is new to me but if this was a book I owned and not a library book that I need to return in 3 days I would put a permanent bookmark on this chapter (like a piece of tape or dog-ear). I do think I will renew it so I am not rushed with this blog.

On a side note my library app has decided that it won't show me books I have checked out and in turn, I can't renew them via the app. so I will need to login to the website to do that. so that is new.

We are at chapter 21 so it is time for time. I would like to see how deep the book goes into time. Timing on a computer is very system and hardware-dependent. I wonder if it will dive into RTC (Real-Time-Clocks). This book does not mention embedded systems and that is a use case where how timing works is important because of the low-level nature of it.

They kind of gloss over how time works at the machine level. and to be fair C is a multi-platform programming language so everything may be different. That is the beauty of the C Standard Library: it does all that under the hood so you have a consistent performance and code can be used across platforms. they did mention the Unix epoch and that is important to know (and something I kind of forgot about). and they discuss how time can be used to seed a random number with srand(). In the future, I plan on using the Raspberry Pi Pico to use a hardware sensor to generate a random seed. look for that on this blog or my YouTube channel. The time chapter was short but it did express what needed to be said...or written...or read....you know what I mean.


chapter 22 introduces files and how to save, write, append, edit...etc them. The book uses the library function/file pointer method fopen() to open files as opposed to the system call/file descriptor method of open(). and the library function may be more consistent. I think I used open() with my ffmpeg project. Unfortunately, that laptop needs some love and care and I did not put the source on github. I was in the process of making a GitHub video and making a repository for the project, but I waited too long.


So along with file manipulation, we need to deal with file management which Chapter 23 covers. One of the things is directories. and this is definitely needed when a user needs to select a file or you need information on a file. if you saw my c/c++ work on my FFMPEG project I used a relative path when accessing files (../dir/dir/file, ./file, ./dir/file, etc) I could have used an absolute path, but that would make it less portable because everything would need to be in the exact same directory. Now here is a question: do you call them directories or folders?


Something I have difficulty in C is using multiple source files. my brain wants to say that as long as I use #include it is all good. and that is fine for the header (.h) files but for some reason you need to use the linker for multiple "source"(.c) at least that is my experience with compilers I have used. That is why I have been trying to learn more about Makefiles. and I just checked the index to see if Make is covered and it is not. probably because they expect you to use an IDE, another way is to use build scripts with bash (or your shell of choice). so using multiple files is what Chapter 24 covers. so the book puts the function prototype in the header file (ex2403.h) but puts the code for the function in main.c just under the main() function. If you are going to put the code for the main.c file why bother putting the prototype in a header file? That just seems worthless to me. I know the book is trying to teach how to put prototypes in the header and how to put code in a separate .c file, but why not culminate it with the prototype in the header file and the code for the functions in another .c file and show it working all as one.

There are bugs and bugs and bugs. As the book says, everyone writes bugs in their code. In Chapter 25 they start out by saying to use printf(). and yes I do that all the time, but many will tell you using printf() can obscure bugs, cause bugs, or negate what is causing the bug. A better way is to use tools like GDB. let's see if the book mentions that (I am only on page 1 of the chapter)

ok, something I didn't know was the __LINE__ macro. This macro displays the line number of the code that it is in. It is useful in debugging. and they do mention the GNU debugger but the book goes into the IDE Code::Blocks debugger. I don't use Code:Blocks often so I am just skimming this part. it does talk about breakpoints, I need to see if they have GDB for Dummies.

on to part six, which is called the parts of tens and chapter 6 is 10 common boo-boos. Before reading this I assume I have made all 10 multiple times. The first one is messing up conditionals and yes I do that all the time. especially using = instead of ==. the second one I don't think I have done. that is adding a semicolon ; instead of curly braces { }. if you don't use the curly braces to encapsulate the code block the loop does not know what code to run. missing the break keyword in a switch case, yup I have done that one. I do understand that you may want the switch case to roll over to the next case but that is an exception (to my knowledge). so missing braces is common for me. on this keyboard in particular because the close brace button is temperamental. ok, they added ignoring warnings. if it lets me compile I am guilty of this one. I will run it and see if it works. most of the time I will glance at it. Most of my warnings tend to be declaring a variable and not using it. This is because when I plan out something I try to add all the variables at the beginning. sometimes I am doing code in stages and don't need the variable. Other times I will use a variable for debugging and comment out the debugging code and not the variable definition. I will even use this with GDB because sometimes I want to see if a calculation is being computed correctly. generally to make sure the order of operations is going how I think it should. so they put endless loops, but I think they covered that already. I think they are forcing it to be a list of 10 things. and scanf() part of this is not knowing that you need to put pointers as arguments, and forgetting the ampersand (&). The funny thing is I know Ampersand from the show Wheel of Fortune. I think it was the category “same name” where they introduced the ampersand. so that was chapter 26


now 10 reminders and suggestions, that is chapter 27 the last chapter. So the first thing it says is to maintain good posture. This is funny because as I am typing this I am reaching over the book and my tablet to type this. not good posture at all. it says to use creative names for things like variables and functions, but I would argue creative is not the right word. Use descriptive names may be a better wording. I agree with the book you should write functions when doing repetitive tasks. The key is to not overdo it. I have seen code where almost everything is in its own function and main() is just the caller for them. In this case, you better know how to use pointers. The next reminder is to make little changes in your code, so if you are adding a feature or debugging you have a clear path of what to change or not to change. Making several changes in several parts of the code will make the map to how you got from part a to part b difficult. but sometimes you make a significant change to a function, like changing the arguments and you need to fix every place the function is called. A good example is say you have a code that takes a string (char array) and you discover you need to add an int for the string length for security purposes to avoid string overruns. you need to change the function, but now you need to find every place you called the function. One crude way is to compile it and go through the error messages one by one. and if you are doing it from the terminal and don't know where the function calls are this may be the quickest. if you are in an IDE that checks for syntax errors that may be another way. it tells you to know what a pointer is. After spending half the book avoiding pointers, now the author wants to make sure you know what they are. It talks about adding whitespace. If you are the only coder on a project use the white space to make it readable to you. If you are part of a bigger project there may be style guidelines for white space that you will need to follow; be flexible. it suggests to read your code out loud. I am not sure how well that would work for me, but it may work for you. For writing (like this blog) I run it through a text-to-speech website to make sure it sounds correct. I don't think that will help with code.


Finally the Appendixes. The first one (Appendix A) is the ASCII codes (0-127) there are -255 to -1 but this book does not cover that or utf-8 and utf-16 that may also apply so look this up. for nothing else so you know what they are if you come across it (utf-8 is common in HTML). appx B is the C17 keywords. As I am writing this C23 is due to come out. and it does give some of the C++ keywords (I guess for context). appx C is the Operators. This is a good thing to review from time to time. Appx D are the built-in data types but you may want to look into custom data types like uint8, uint16...etc. Appx E has the escape sequences (for use in functions like printf()). F is a conversion chart and G is order of precedence.

so that is the book. I had not planned on doing a chapter-by-chapter review. But that is what I did. Now I need to return this to the library. so I may not have it during editing (if I don't edit this soon).

.

Check Out My YouTube Channel https://www.youtube.com/@samplesandtests/