C code in the shape of a doughnut, which outputs a 3D spinning doughnut to stdout

A Crash Course in C Programming: Lesson 1 (Getting Set up and Running "Hello World")


This text is based on the book of the same name by Elwin, Lynch and Marchuk of Northwestern University (2015). While their book focuses on programming the Microchip PIC32, I've attempted to abstract away details specific to the MIPS architecture in order to provide a generic, system-agnostic crash course on C. Consequently, much of the material in the original (which deals with specific hardware and libraries) will not be covered. I suggest that those who specifically wish to program a micro-controller or single-board computer (SBC) look to the Arduino, BeagleBone, Raspberry Pi and Udo Bolt boards (and books thereon; both O'Reilly and Make have published many). If you're new to C, using a computer is generally easier. That's the environment on which I'm focusing.

Assumptions

Most books and tutorials on the C language include a "Why C?" section that give you the benefits and disadvantages of C programming, as well as compare it to other languages. I'm assuming you already know how to write, debug and test code to some degree, so I'm sparing you those details. If you want them, you can easily find them yourself.

I'm also assuming that you have some familiarity with a command-line interface (Windows command prompt/Powershell or a terminal emulator and `bash/zsh on *NIX) and a text editor such as emacs or vim (I don't care which, since that's not relevant). Familiarity with a command prompt/terminal emulator is only required if you're using command-line interface applications/tools such as RHIDE or vim, instead of a GUI IDE.

I'm also assuming that you know that C is a difficult language to learn and requires a lot of time (as opposed to Nim and Python), but is definitely worth knowing if you want some understanding of how languages based on it (C++, C#, Java, Nim, Python and Rust, for example) work under the hood and how you can (possibly) write performant extensions for them in it or C++.

Whence C? (A Very Short History)

First there was A. Then Ken Thompson of Bell labs created B and BPL (Bell Programming Language). Inspired by his work there, he, Brian Kernighan and Dennis Ritchie created C in the late 1960s/early 1970s while creating UNIX (when Bell Labs left the MULTICS project).

Some time later, Bjarne Stroustrup created C++, an iteration on C that brought object-oriented programming to C (although OOP is optional in C++, like it is in Python). The rest is history, which you can also look up if you want to, rather than me bore you with it.

Getting Started

Since the architecture and operating system on which you write, compile, link and run code is largely irrelevant, I'm not going to recommend one. However, I find development easiest on a GNU/Linux system, so will be using an x86_64 machine running Debian and the gcc toolchain. On Windows, I mostly use Bloodshed/Orwell Dev-C++, despite its age. At time of writing, the Borland/Embarcadero version is buggy. (I have not been able to get Code::Blocks, the successor to Dev-C++, to install devpaks.) You can (and probably should) use Visual Studio Community Edition, although it is set up to do C++ development by default; just use the C libraries and code in your C++ project (cstdio instead of stdio.h and cstdlib instead of stdlib.h, for example).

What You Need

  • Some device that will execute compiled programs (a computer operating system or micro-controller with a bootloader)
  • A text editor or IDE that colorises/highlights C Code (emacs, vim, Borland Turbo C/RHIDE, Notepad++, VS Codium/Visual Studio, etc.)
  • A C compiler (I recommend gcc`; available/installable as part of WSL, Moba XTerm/Cygwin or Dev-C++/Msys on Windows.)
  • A C linker (part of gcc)
  • A C debugger (gdb)
  • The Make (cmake/make) tool (optional)
  • Git (git) or Mercurial (hg) for source control (optional)
  • GitKraken or Git Fork (optional) for a visual overview of the commit chain and repository state; command-line use of git can be difficult and error-prone. I also prefer GitLab to GitHub. (Even Microsoft, which owns GitHub, avoids/prohibits using it for security/privacy reasons.)

The advantage of using an IDE (such as C Lion, KDevelop, NetBeans or Visual Studio) is that all these tools are integrated into one interface, which makes development easier than using separate tools. The disadvantage is that it can sometimes make it hard to determine if errors come from the compiler (errors in the code) or linker (errors in including referenced files/libraries).

Note 1: Borland Turbo C/C++ and RHIDE are for DOS-based systems (DOS 6.2 to Windows 9X) and do not support any C standard later than 99, as far as I know. Dev-C++ supports at least C 11 in the latest version. It runs on Windows 2K (with some issues/restrictions) to Windows 10. This means that some later features of the C language (C 14/17) will not be available to you if you use these tools. For the most part, this shouldn't matter if you're not cross-compiling (compiling for Windows on a *NIX system or vice versa) or writing advanced/specialised code (which you won't do in a crash course).

Note 2: There is an interpreter for C, named Ch ("chish", "C-H" or "Swiss"). It executes *.c files and *.ch configuration scripts. Ch saves you having to run the "compile and link" steps, by combining them with the "run" step. As far as I know, it compiles and links a temporary executable and discards it after execution. That's not an issue if your programs are small (as is typical when learning a language), but becomes a problem when compilation time is an hour or more (such as is typical in a professional project with multiple files). It can be useful for both learning the language and checking your programs for both compile-time and runtime errors before your code is production-ready. (Please don't use it in production, as it is neither efficient nor optimised/performant.)

Say, Can You C?

Right, that's enough preamble, despite the length of introductions on some books on C programming. Let's actually write some code, the activity for which you primarily care. The classic/traditional first program in any language is "Hello World", which outputs those words to the standard output device (usually a command prompt, although it used to be a teletype printer). The chief purpose of this trivial (and apparently pointless) program is to test the system setup: Is the system correctly set up to compile, link and run a C program?

/* hello.c: Output a line to stdout */
/* This is a traditional C comment.
 * It can be used across multiple lines.
 */
// This is a single-line comment. Comments get stripped from compilation.
/* Tell the prerprocessor to include standard system library code. 
 * This literally pastes that code at this point in the file.
 */
#include <stdio.h>
#include <stdlib.h>

/* Preprocessor conditional: 
 * If a constant is not defined in the above libraries (which it should be), define it.
 */
#if ndef EXIT_SUCCESS
  # define EXIT_SUCCESS 0
#endif

/* main method: entry point into the program;
 * returns an integer value to the operating system to indicate the result of execution.
 */
int main (void) {

  /* Output a formatted string to `stdout`. `fprintf()` allows outputting to a different
   * file stream (such as `stderr`).
   */
  printf("Hello, world of C programming!\n"); // could also use `puts()`
  // "\n" means "new line" (CrLF or LF, depending on system)

  // Tell the system everything executed successfully and it can now do other things
  return EXIT_SUCCESS;
}

Don't worry about the preprocessor lines (which start with an octothorpe/hash) for now; that's pretty standard boilerplate for setting up a C program.

For my projects, I usually save the code in /usr/local/src/{language}/{project} (or <drive>:\usr\local\src\{language}\{project} on Windows), but you don't have to follow this convention. If you don't, substitute /usr/local/src/{language}/ as appropriate. (I recommend you keep the {language} directory to help keep your projects organised when using predominantly one language; Web-based projects go into /var/www/[html|cgi] or equivalent, as appropriate.)

Save this file as hello.c, then compile, link and run it. (On *NIX systems, *.c is a C source file, while *.C is C++.) If you're using an IDE, this is usually done in a single step. In a command prompt, compiling and linking are usually a single step, but execution is separate. (On windows machines, run the executable from the command prompt, since double-clicking the executable will cause the console to close after output and you won't be able to see it. I quite like cmdr for Windows XP and 7 for this purpose.)

The below bash code (*NIX or Git for Windows) shows the process in a command line interface

# make a 'bin' directory for binary files
mkdir -p /usr/local/src/c/hello/bin
# compile and link 'hello.c'
gcc -o /usr/local/src/c/hello/bin/hello /usr/local/src/c/hello/hello.c
# run the program and wait five seconds
/usr/local/src/c/hello/bin/hello && sleep 5

All going well, you should see the text "Hello, world of C programming!" in your console/terminal window (unless you're in DOS or *NIX CLI mode for some reason, such as through SSH, in which case you have no windows). If not, look at and resolve errors, then repeat the compilation and execution steps until you do.

That's all for now. In the next lesson/post, I'll show you how to do (possibly) more useful things with C, such as receiving user input and acting on it.

Thumbnail image: C code in the shape of a doughnut, which outputs a 3D spinning doughnut to stdout

How do you rate this article?

3


Great White Snark
Great White Snark

I'm currently seeking fixed employment as a S/W & Web developer (C# & ASP .NET MVC, PHP 8+, Python 3), hoping to stash the farmed fiat and go full Crypto, quit the 07:30-18:00 grind. Unsigned music producer; snarky; white; balding; smashes Patriarchy.


Return to the Source
Return to the Source

Use the Force; read the source! This blog is mostly a collection of study notes on ASM, ASP .NET, Blender, BASIC, C/C++, C#, ChucK, Computer Architecture, Computer Literacy, CSS, Digital Logic, Electronics, F#, GIMP, GTK+, Haskel, Java, Julia, JavaScript (ES6+) & JSON, LISP, Nim, OOP, Photoshop, PLAD, Python, Qt, Ruby, Scheme, SQL (MySQL & SQLite), Super Collider, UML, Verilog, VHDL, WASM, XML. If I can learn it and make notes on it, I'll write about it. || Blog images copyright Markus Spiske and Pixabay

Publish0x

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.