# Introduction to the C Programming Language

> Get started with C, a low-level, compiled language with no garbage collection that powers Linux, embedded devices, and your first Hello, World program.

Author: Flavio Copes | Published: 2020-01-30 | Canonical: https://flaviocopes.com/c-introduction/

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](https://flaviocopes.com/python-introduction/) 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](https://flaviocopes.com/nodejs/) 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](https://flaviocopes.com/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

```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

```c
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:

```c
#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:

![Terminal showing gcc command with clang error: no input files message](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.10.50.png)

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:

![Terminal showing nano hello.c command being typed after the gcc error](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.11.39.png)

Type the program:

![GNU nano editor showing the Hello World C program code with include stdio.h and main function](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.16.52.png)

Now press `ctrl-X` to exit:

![Nano editor exit confirmation dialog asking to save modified buffer with Yes/No options](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.18.11.png)

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

![Nano editor filename confirmation dialog showing hello.c as the file name to write](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.18.15.png)

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

![Terminal back to command prompt after successfully creating the hello.c file using nano](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.13.46.png)

Now type

```sh
gcc hello.c -o hello
```

The program should give you no errors:

![Terminal showing successful compilation with gcc hello.c -o hello command completing without errors](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.16.31.png)

but it should have generated a `hello` executable. Now type

```sh
./hello
```

to run it:

![Terminal output showing Hello, World! message after running the compiled hello program](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.19.20.png)

> 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:

![Terminal showing ls -al hello command output displaying the compiled program is 12556 bytes in size](https://flaviocopes.com/images/c-introduction/Screen_Shot_2020-01-29_at_10.19.55.png)

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:

- [Variables and types](https://flaviocopes.com/c-variables-types/)
- [Constants](https://flaviocopes.com/c-constants/)
- [Operators](https://flaviocopes.com/c-operators/)
- [Conditionals](https://flaviocopes.com/c-conditionals/)
- [Loops](https://flaviocopes.com/c-loops/)
- [Pointers](https://flaviocopes.com/c-pointers/)
- [Functions](https://flaviocopes.com/c-functions/)
- [Arrays](https://flaviocopes.com/c-arrays/)
- [Strings](https://flaviocopes.com/c-strings/)
- [Input/output](https://flaviocopes.com/c-input-output/)
- [Type definitions](https://flaviocopes.com/c-typedef/)
- [Enumerated types](https://flaviocopes.com/c-enums/)
- [Structs](https://flaviocopes.com/c-structures/)
- [Header files](https://flaviocopes.com/c-header-files/)
- [The C preprocessor](https://flaviocopes.com/c-preprocessor/)
