C Programming in 2021

by Ray Dall

##########

PREFACE

I have just begun (19MAR2021) to rewrite this course as much of it was outdated.
C is just as relevant today as it was the day it was created.
My writing style has grown, and this is likely to be less of a dry read.
I am also more familiar with C than I was 20 years ago when I wrote the original course.
Hope you enjoy this new version.

COURSE REQUIREMENTS

Every course you take has some kind of requirements. English Literature courses require that you know the alphabet, can read, preferably in English. Algebra requires that you have some basic general math skills. Auto Mechanics requires that you have access to tools, and something with an engine.

Before you can actually write any code and turn it into a working program, there are a few things you are going to need. Understanding that many of the people who take my course may not have disposable incomes, I try to keep things as inexpensive as possible.

In this course, you will need a computer. I teach C as it applies to its native operating system - UNIX. At bare minimum, you need a UNIX/Linux based computer. If you do normally use Windows, don't be afraid. I'll try to make this as painless as possible.

If you want to get the most out of the course, invest in an inexpensive,
Raspberry Pi computer. Raspberry Pi Computer

For $85, you get a pocket sized, fully functional quad core 64 bit computer, that can handle DUAL HDMI Monitors! It will plug right into your TV set. It is actually nice to write code from your easy chair on a 65 inch monitor. It is ready to go and comes with all the software you'll ever need to write code, and to be in control of the "Internet of Things". Check out these specs!

Finally, every program we write in this course will be 100% tested to work on that computer.

I'm not implying that the C programs will not work under Windows, Mac, or another version of Linux/Unix, merely that I haven't tested them on those units, and can not guarantee the results. C is a cross platform language and should work equally well on any system, but as they say - when you make something idiot proof - they make better idiots. So it goes with computer programming. I can write a program today that works great on a particular machine, and one small change in the Operating System can render the program inoperable. This, of course, is true of any programming language, not just C.

In addition to the computer, before you can actually write any code and turn it into a working program, you will also need a C compiler and a text editor of some kind. Unix computers come with a totally free compiler built in. Let's face it - UNIX was at least partly written in C!

In windows, of course, you'll have to BUY a C compiler and/or Software Developement Suite, which will cost you HUNDREDS of dollars.

Buy Microsoft Visual Studio for only $484.99

(or save $400 and just BUY THE RASPBERRY PI)


If you don't want to spend ANY money, you could simply download a copy of Linux (for free) and use it on your existing computer. I personally use Debian, which is one of the most venerable and well supported distributions, and is the grandfather of Ubuntu. Most of Linux was WRITTEN in C, and Linux comes with all the software you need to write, compile and debug the C language. I'm not saying you have to wipe your hard drive and get rid of Windows completely (why not?, I did!). There are other ways. Nowadays you can get what is called a "Live" distribution of Linux that you can run from a DVD, CD, or flash drive. Just plug it in and boot your computer. Use it for the course, then unplug it and reboot back into Windows when you are done. THIS course does not cover how to do that.

There is one final way to get access to a Unix computer:
Use someone else's. Although this is less secure, because you don't have full access and control of your files, and someone else COULD steal or delete your code - the odds are pretty good they won't. Services like the "Super Dimensional Fortress" are out there and usable for free.

Advantage: Most programmers worth their salt use Linux nowadays, and if you DON'T familiarize yourself with the operating system, you may find it difficult to get a good paying job after college! (Employers tend to pay $10K-$25K more a year for people with Linux background). So now you have TWO reasons for at least giving Linux a try.

Why C?

C, while a bit complex, is one of the oldest, fastest, and most reliable languages there is. Being VERY close to the computer's original machine language, with the ability to output in Assembly (executable code) without the need for an interpreter (which slows the computer down at every command) - C is fast... Lightning fast.

C is also the mother of many other languages. Because of that, if you know C, you have a great head start at learning C++, C#, Java, and even Golang! Learning C will teach you the necessary disciplines, and in many cases, even the code necessary to work with other languages. Point of fact - if you can code in C, you can code in C++... because a C++ compiler will compile a C program just fine.

It is also cross-platform, which means that if you properly write a program in C on a Linux machine, it will work equally well on a Mac, Windows, Cell phone, or even some car's central processing unit! In addition, if you were looking to write programs for the Arduino, or for many other similar single board systems, C is the Arduino's native language!

Anything you can do with a computer, you can do with C. Being a compiled language, it is not only fast, but secure. Languages like Python may be easier to learn, but it leaves the source code on the machine, which of course can be easily read (and hacked) by anyone. Compiled languages need only leave an executable binary file, which can neither be easily read, nor hacked. Properly written C code is very stable, very fast, very secure and very adaptable. The question then shouldn't be why C, but rather, why not?

Finally - C will never be outdated. The original code was written in the late 1960's. That makes it over 50 years old...one of the oldest and most venerable languages in use today. But it isn't outdated yet, because it is constantly being written. Unlike other languages, like BASIC or Python - the commands aren't a fixed set. Every program you write is a function, and every function is a new command - so every time you write a new program - you have added to the commands possible to be used by other programmers! (Especially true if you make your code "open source".)

Because every program that is written by every programmer in the world adds to the possibility of new commands - I will not be teaching you EVERY command there is. I can't - and nobody can. If I did, someone would write a new command tomorrow, and then my complete book would be incomplete. So I will give you all of the commands I believe you will need to write your own, and to get you started on your never ending journey. Have fun. Write your own commands. Make C YOUR language. Conquer the world. Hack the NSA. Ok... maybe not that last part. Last 3 sentences REDACTED including this one...

History

Before we get into the bits and bytes of the language, lets get some historical perspective as to where the language came from, and where it is heading.

I've done a lot of research, and if there is one thing I've learned about C and Unix... is that its origins are shrouded in contradiction and secrets. It was kind of a dark project that originally was not done with the consent of the company that "funded it", and people could have been fired... so at first - nobody wanted to talk about it... until it was nearly completed and it was a viable product.

C is likely one of the most influential programming languages in the world. It isn't the first, nor will it be the last, but it has left a lasting impression, and even though it was one of the earliest adopted languages, it is still used on a regular basis on everything from toys to spacecraft.

This is what is known:
Shortly after graduation from Berkley, Electrical Engineer Ken Thompson landed a job with AT&T's Bell Laboratories. One of his first assignments there was to work with a multi-company consortium to build an operating system that could work on many different computer platforms. That system was called MULTICS. At the time, computers were mostly programmed in Assembly language, and a program written for one computer could not be easily ported to another. Multics was supposed to fix that. Multics, however, wound up being a bust, and Ken Thompson went back to work at Bell Laboratories home office. Many lessons were learned, though, in the process of writing MULTICS. One, was the language BCPL (Basic Combined Programming Language). Another great outcome of the project was a Space Travel game program written for testing the machine. Ken wrote the Space Travel program, and got adicted to it. When the Multics project went bust... his addiction drove him to find another way to play the game.

Around 1968, Ken, having recently displaced from the Multics project, was looking for something to do. (Engineers don't idle well). At the same time, his wife and child were out of town, and as an Engineer, he was going stir crazy. This was not a good time to be addicted to video games.

He requested a new PDP-11 from AT&T to continue working on the MULTICS project solo, but Bell Labs was loath to buy a brand new computer to continue a project they had just aborted. Wandering the halls, Ken located an older PDP-7 in a "storage closet". He requested to use it and the request was granted.

Now a PDP-7 wasn't a full blown computer, but Ken was desperate. The PDP-7 was merely what they called a "smart terminal." (A keyboard and monitor with just enough processor and memory to act as a buffer to eliminate lag and crashes between itself and the mainframe). Not being (considered) a full blown computer, he had to really conserve memory space and crop his code down the the bare necessities. As a matter of fact, the original commands in UNIX only had two character names (like ls for list, and mv for move).

He wrote a stripped down version of BCPL, which was dubbed "B". He also had to write a very small operating system to work in the PDP-7, which he called UNICS (a play on MULTICS). We now call it UNIX. During this same time, a co-worker by the name of Dennis Ritchie started writing a language who's core features were derrived from B, but also incorporating many ideas from other colleagues. This new custom programming language, they called "C". C was written in assembly language, as was UNIX originally, but later UNIX was re-written in C so that it could be ported easily to other computers.

At some point, the team had to justify the hours spent on the project, so they gave Bell Labs their progress report, and seeing a viable product, AT&T opted to give them the PDP-11 that Thompson originally requested. After all - they had to prove that the OS was "portable" to other systems. B, however, being incapable of handling byte addressability in the PDP-11, C took over the job.

The developement of C and the UNIX operating system became closely intertwined. Most of the Unix kernel was written in C, as well as BSD, Linux and several other Unix based operating systems and programs. This was one of the first kernels ever written in a language other than the native Assembly language of the processor, and it allowed cross-platform programming - so that a program written for one computer could be used on another one.

Sometime around 1978, the "The C Programming Language", otherwise known as "K&R" (named after the authors Kernhigan and Ritchie) was written. Ritchie, of course, invented the C language, and Kernhigan wrote or helped to write many early programs. This book became the defacto standard book used in many colleges. While it may be in my opinion, a bit terse and cryptic, and much of the code is either obsoleted, insecure, or just won't run on many modern computers - it is without a doubt a very high standard and authority on the language - considering one of the authors was the author of the language itself. That being said, I have personally found that on some machines, some of the programs just don't work as written in the book and need a little 'tweaking'. Also, there are some commands that were used "back in the day" that are now considered to be taboo, as they create security risks. Long story short, I wouldn't use K&R as my Bible.

In 2000, Herbert Schildt came out with "C/C++ Programmer's Reference". This, while not a proper course on the language, is in my opinion one of the most authoritative quick reference guides for C and C++ programmers, and I DO highly suggest that you get your hands on a copy of it and devour it.

Now that you know who wrote C, when it was written, and the names of a couple of good reference books - the question still remains, "What exactly IS C, and why do I need to learn it?".

Computers don't speak C. Computers speak machine language.... the language of 1's and 0's. This is because internally, the computer is nothing more than a vast array of switches (think on and off). Maching language is a binary language, with only 2 possible characters, a one or a zero. As such a typical computer sees something like the following in its own world:


10011011 01101101 11010010 11010010 10011011 01101101
11010010 11101001 10010010 11011011 11010010 11101001
11101111 00100100 10010010 11011011 01101101 11010010
10011011 01101101 11010010 11010010 11010010 10011011
11101001 10010010 11011011 11101001 10010010 11011011


Except for a very few people in the world, humans of course, can't read that for crap. We need something more "human-like" to read, and so the invention of "Assembly Language". Assembly language uses commands in the microprocessor itself to speak computer-ese. But assembly language is also a bit on the cryptic side:



push ax
push bx
mov ax,33
mov bx,45
add ax,bx
pop bx
pop ax
jnz next


Assembly is considered a "Low Level" language - in that it is as close to speaking the computer's actual language as most humans can ever achieve. We speak in a "High Level" language - humanese. In order to make things easier on us, we either need a compiler or an interpreter.

Let's take a moment to discuss the difference between a compiler and an interpreter.

Assume for a moment that you are a king. You want to make a treaty with another king, but the two of you don't speak the same language. How then, do you communicate the terms of the alliance between each other? You have 3 options.
1) You can learn the other king's language and speak it yourself.
2) You can hire an interpreter, and speak to the other king through the interpreter. Of course, this takes much time away from your schedule, and the other king's schedule, and every sentence you speak has to be respoken by the interpreter, which slows down the whole communication process. There is also the possibility, that the interpreter - being rushed to quickly interpret and respond, my make mistakes.
3) You can hire an ambassador who speaks the other king's language to meet with the king on your behalf. If the ambassador you hire has the same basic belief system as you, and understands your wants and desires, he can more quickly communicate with the other king while you go about doing other kingly business. Clearly, the ambassador route is faster, and more efficient, and so long as your ambassador is on the same thought process as you are, you can trust that he is going to represent you well.

The interpreter in the above scenereo is identical to an interpreter in an interpreted language. It is slow and redundant. Every command has to be processed twice...once to be converted into the machine's language real-time, then once again for the machine to perform the operation. This slows the program down and introduces more room for errors.

The Ambassador is more like the compiler. You tell it what you want it to do in your native language, and he changes it into a program the computer's native language.

A compiler is like a converter that compiles (converts) the program we wrote INTO an assembly language program. An interpreter, on the other hand, runs in the background (using up precious memory and speed), interpreting commands from a high level language into a low level language realtime. High level languages like C or Fortran are compiled into Assembly language, and run quickly. High level languages like BASIC and Python are never compiled. Instead, they run with an interpreter program running in the background, and as such - it takes 2 programs to do the job of one (the program you wrote, and the interpreter program), so it uses twice the memory, and processing resources, so it runs twice as slow.

You can see the obvious reason, then, why learning a compiled language like C is much better than learning an interpreted language like Python or BASIC, because compiled languages turn their programs into Assembler code, and run much faster. Python and BASIC may be easier to learn at first, (because you don't have to learn how to fuss with a compiler), but in the end, C is just as easy to write programs in if you learn it, and it simply writes a faster, cleaner, more secure, more compact code.

Finally - you must know some Unix commands

While not intended to be a complete course on UNIX/LINUX, You MUST know some basic commands in order to navigate the operating system. At bare minimum, you should MEMORIZE the following file manipulation commands:
mkdir	Make Directory
ls	List
cd	Change Directory
mv	Move a file
rm	Remove (delete) a file
nano	- a simple text editor
Until I get a course written on Linux/Unix (coming soon) a good reference is the "Linux Command Line and Shell Scripting Bible" by Richard Blum (Wiley Publishing). You can either BUY it or use an ONLINE PDF version. Trust me - while it may be a bit pricy, you won't regret purchasing that book.

Now on with the C course:

Follow the section numbers below to navigate from one section to another...

################################################################################
1 2 3 4 5
################################################################################