C is probably the most widely known programming language. It is used as the reference language for computer science courses all over the world, and it’s probably the language that people learn the most in school among with Python and Java.

I remember it being my second programming language ever, after Pascal.

C is not just what students use to learn programming. It’s not an academic language. And I would say it’s not the easiest language, because C is a rather low level programming language.

Today, C is widely used in embedded devices, and it powers most of the Internet servers, which are built using Linux. The Linux kernel is built using C, and this also means that C powers the core of all Android devices. We can say that C code runs a good portion of the entire world. Right now. Pretty remarkable.

When it was created, C was considered a high level language, because it was portable across machines. Today we kind of give for granted that we can run a program written on a Mac on Windows or Linux, perhaps using Node.js or Python. Once upon a time, this was not the case at all. What C brought to the table was a language simple to implement, having a compiler that could be easily ported to different machines.

I said compiler: C is a compiled programming language, like Go, Java, Swift or Rust. Other popular programming language like Python, Ruby or JavaScript are interpreted. The difference is consistent: a compiled language generates a binary file that can be directly executed and distributed.

C is not garbage collected. This means we have to manage memory ourselves. It’s a complex task and one that requires a lot of attention to prevent bugs, but it is also what makes C ideal to write programs for embedded devices like Arduino.

C does not hide the complexity and the capabilities of the machine underneath. You have a lot of power, once you know what you can do.

I want to introduce the first C program now, which we’ll call “Hello, World!”

hello.c

#include <stdio.h>

int main(void) {
printf("Hello, World!");
}

Let’s describe the program source code: we first import the stdio library (the name stands for standard input-output library).

This library gives us access to input/output functions.

C is a very small language at its core, and anything that’s not part of the core is provided by libraries. Some of those libraries are built by normal programmers, and made available for others to use. Some other libraries are built into the compiler. Like stdio and others.

stdio is the libraries that provides the printf() function.

This function is wrapped into a main() function. The main() function is the entry point of any C program.

But what is a function, anyway?

A function is a routine that takes one or more arguments, and returns a single value.

In the case of main(), the function gets no arguments, and returns an integer. We identify that using the void keyword for the argument, and the int keyword for the return value.

The function has a body, which is wrapped in curly braces, and inside the body we have all the code that the function needs to perform its operations.

The printf() function is written differently, as you can see. It has no return value defined, and we pass a string, wrapped in double quotes. We didn’t specify the type of the argument.

That’s because this is a function invocation. Somewhere, inside the stdio library, printf is defined as

int printf(const char *format, ...);

You don’t need to understand what this means now, but in short, this is the definition and when we call printf("Hello, World!");, that’s where the function is ran.

The main() function we defined above:

#include <stdio.h>

int main(void) {
printf("Hello, World!");
}

will be ran by the operating system when the program is executed.

How do we execute a C program?

As mentioned, C is a compiled language. To run the program we must first compile it. Any Linux or macOS computer already comes with a C compiler built-in. For Windows, you can use the Windows Subsystem for Linux (WSL).

In any case, when you open the terminal window you can type gcc, and this command should return you an error saying that you didn’t specify any file:

That’s good. It means the C compiler is there, and we can start using it.

Now type the program above into a hello.c file. You can use any editor, but for the sake of simplicity I’m going to use the nano editor in the command line:

Type the program:

Now press ctrl-X to exit:

Confirm by pressing the y key, then press enter to confirm the file name:

That’s it, we should be back to the terminal now:

Now type

gcc hello.c -o hello

The program should give you no errors:

but it should have generated a hello executable. Now type

./hello

to run it:

I prepend ./ to the program name, to tell the terminal that the command is in the current folder

Awesome!

Now if you call ls -al hello, you can see that the program is only 12KB in size:

This is one of the pros of C: it’s highly optimized, and this is also one of the reasons it’s this good for embedded devices that have a very limited amount of resources.

Check out some of my other tutorials on C: