01 Setting Up, First Program

Prequisites: Please know your Linux basics, how to use a text editor, the bash
shell, and how to find and install software.

You need gcc, the GNU Compiler Collection. Your favorite Linux distribution
should pull in any dependencies like cpp, binutils, and glibc, the GNU shared
C library. libc6 is the same as glibc version 2, and you should see libc6
installed on your system as libc.so.6 or libc.so. Yes, we love naming
confusion on Linux don't we.

Coders need good typing skills. There are many free typing tutors, and if you
spend ten minutes per day practicing you'll see your typing skills improve
rapidly.

You'll need some patience and persistence. Anyone can learn to do anything,
including become a good coder. Everyone taking this course comes from different
backgrounds and levels of experience, so don't compare yourself to your fellow
students, or think you're too slow or too stupid or have the wrong kind of
brain. Learning anything isn't about raw blazing brilliant talent, but working
at it. Everyone who is a good coder has invested a lot of time and effort.

Lessons run weekly, every Sunday, and I estimate about 16 weeks.

All lessons and messages are archived at
http://mailman.linuxchix.org/mailman/listinfo/courses

## Lesson 1: Setting Up, First Program ##

I recommend typing rather than copy-and-pasting the examples, because it
trains your eyes to see details, and when you're writing code details are
everything. If you miss a single character such as a semi-colon or curly brace
your code will not work correctly.

C is a compiled language. Writing the code is just the first step; then it must
be compiled using a program called a compiler, like gcc.

code > compile > executable binary

This creates an executable binary, which is our actual program. (This is a
very simplified explanation, which is all we need for the moment.)

The classic beginning program is always a "Hello World!" program, or something
similar. It's a fast and easy way to learn the basic steps of write code,
compile code, and then run the resulting executable. Type this example source
code into a text editor and name it whatever you want, except test, because
Linux already has a command called test. My example is called welcome.c. It
must have the .c extension so that gcc knows this is a C source code file:

#include <stdio.h>
main()
{
printf( "Hello, and welcome to the Beginning C Course!\n" );
getchar();
}

Now compile it:

$ gcc -o welcome welcome.c

The -o option means "give the output file this name." If you don't name your
output file gcc will call it a.out.

And now you can run your new compiled program:

$ ./welcome
Hello, and welcome to the Beginning C Course!

You must prepend your new command with ./ when you are running it from inside
its directory. If you go up one level, then you just need the normal filepath,
for example if I put welcome in my cfiles directory:

$ cfiles/welcome

Or you can put it in a directory that is your path. Run echo $PATH to see all
of your paths:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

This means that any command placed in any of these directories can be run
without typing out the full filepath, because the bash shell knows to look in
these directories when you enter a command. When you're writing your own code
it can be helpful to create a directory in your home directory to store your
executables, to avoid permissions hassles. Then put your new directory in your
path by adding a line to your ~/.profile, like this:

PATH=$PATH:$HOME/cfiles

Then logout and log back in. Copy welcome to your new directory, and the which
command will see it:

$ which welcome
/home/carla/cfiles/welcome

And you can run it like any other command, with just the command name:

$ welcome

You can read your nice plain-text source code file, but a binary executable is
a different kettle of clams. You can read it with the hexdump command, which
spits out giant blobs of hexadecimal:

$ hexdump welcome
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0002 0003 0001 0000 8300 0804 0034 0000
[...]

A more useful command for binary files is strings, which extracts all of the
text strings:

$ strings welcome
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
puts
__libc_start_main
GLIBC_2.0
PTRh0
[^_]
Hello, and welcome to the Beginning C Course!

## Explaining the Source Code File ##

Now let's dissect our new source code file. #include <stdio.h> is a
preprocessor directive that tells gcc to include the code from the header file
stdio.h in our little program. A preprocessor directive always starts with the
pound sign, and you can have more than one. stdio.h is plain-text source code,
so you can read it. stdio.h is a standard C library header that is used in
pretty much all C programs because it handles input and output-- input from
files and the keyboard, and output to files or the screen. Code libraries are
wonderful things because we can re-use them and not start over completely from
scratch every time we write a new program.

The next part is the function main, which is the first function executed in a C
program. All C programs must start with the main() function. A function is a
block of code dedicated to performing a particular task. A function is made up
of statements, which are instructions, which end in semi-colons. Our example
main() function includes two statements:

main()
{
printf( "Hello, and welcome to the Beginning C Course!\n" );
getchar();
}

printf is a built-in C function that formats and prints the text in the
parentheses to the screen. The parentheses enclose the arguments, or values,
that are passed to the function. A function must always be followed by a set
of parentheses, even when there are no arguments. Any text string in an
argument must be enclosed in double quotes. \n is a newline, and a semi-colon
terminates the statement.

getchar(); is a hack. I don't recall if this is a Windows behavior, or if it
happens in some Linux environments; at any rate on some systems when our
little example program finishes running the whole terminal closes, so all you
see is a quick flash and it's gone. getchar(); makes the program wait for a key
press before it closes. If you don't need getchar(); you can delete it, or
comment it out. There are two ways to comment C code. This way comments a
single line:

// getchar();

This way comments a multi-line block:

/*
getchar();
*/

Or all on one line:

/* getchar(); */

Well that's all for today. But don't be sad because there is homework! Please
feel free to share your own discoveries, thoughts, and questions on the list.

1. Enter more text for the printf function to work on, and try different
formatting options from man printf.

2. Look up the spec for stdio.h, and see what the various macros and functions
in the spec look like in your own stdio.h file.

3. Make errors on purpose in your source code file and see what the compiler
does.

Thank you all, and I'm looking forward to some good discussion!