Consistently ranked among the top two positions of the TIOBE Index since 2001, C is a general-purpose, procedural programming language best known for its ability to map efficiently to machine code.
In this article, we’ll take a closer look at the C programming language, how it works, and why you should learn it.
The Basics of C
Procedural, imperative, and statically typed, C was initially developed by legendary computer scientist Dennis Ritchie at Bell Labs in 1972.
But to understand what that means in plain English, it’s important to cover a few key programming concepts:
- Imperative programming: Just like spoken languages have an imperative mood for expressing commands like “go,” imperative programming is a paradigm in which programmers explicitly write commands dictating “how” a computer should perform some function. It’s most often used in contrast with declarative programming in which you focus on “what” you are trying to accomplish, allowing the language to decide “how“ behind the scenes.
- Procedural language: Early computer programming was all about writing step-by-step instructions that are simple enough for a computer to understand. A procedural language is an imperative programming style where you write procedures or subroutines which contain a series of computational steps that must be executed in that order by the machine.
- Statically typed: A language is statically typed if the type of a variable (e.g., string, boolean, integer) is known at compile time. It implies that you will need to explicitly declare variable types in your program as you write it for the program to compile.
- Weakly typed: People often make the mistake of assuming statically typed = strongly typed. But C is one of those early exceptions. It is considered weakly typed in that you can convert any type to another type without throwing a compiler error by using a cast. It’s important to note that strong and weak typing lacks an official precise definition and is often used colloquially by programmers when comparing the type systems between languages. The stricter the typing rules at compile-time, the “stronger” it is.
- Compiled: A compiled language is one where source code is directly translated into machine code that can be executed by a processor.
The C language was designed to help move the UNIX operating system kernel code from assembly to a higher-level programming language. Today it is used in a variety of applications from programming embedded systems to creating new languages.
Why is the C programming language called C?
C earned its namesake as an alphabetical play on being a successor to the Basic (B) programming language, which itself was a stripped-down memory-efficient version of BCPL (Basic Combined Programming Language). B lacked any types of its own, relying on context and the underlying machine’s memory word format, but as memory capacity increased, so too did the desire to support multiple data types. C added a type system allowing the language to remain more lightweight and basic than BCPL but also complex enough to write powerful programs. The four basic primitive types of C include char, int, float, and void.
But the evolution of the C Family of languages didn’t stop there. C proved to be such a versatile language that it is often called the mother of all languages. Developers went on to create C++, PHP, JavaScript, Java, Python, and Perl just to name a few.
What is C used for?
From software applications such as operating systems to programming embedded systems, or hardware, C is considered to be the best choice for writing low-level code. Common examples of C applications include:
- Embedded systems: Any computer system where you have a processor, memory, and input/output devices around its periphery is an embedded system. Microcontrollers, systems on a chip (SoC), and other chips found within are examples of embedded systems.
- Operating systems: Complex hardware devices such as computers and smartphones require system-level software to manage their hardware components and provide software resources for other programs. Windows, Linux, Mac, and Unix are examples of operating systems that use C in their source code.
- System applications: Apps installed in the system/app/ partition of your device are called system apps. They usually come pre-installed on mobile phones and PCs and interface natively with the hardware.
- H3: Desktop applications: Desktop applications run directly on your computer desktop, which is the main graphical user interface (GUI) you interact with on a personal computer. These apps do not run in a web browser and rely on your operating system and hardware to function. For this reason, they may need some C to interface directly with systems-level components.
- Browsers and their extensions: Browsers and their extensions allow us to surf the web. Websites and web applications can be run within a browser. The browser itself could be considered a desktop application. But the apps that run within the browser are not.
- Databases: Database apps allow users to store, access, and manipulate data. SQLite and PostgreSQL are examples of relational databases that are implemented in C.
- H3: Machine learning algorithms: C lets you unlock the hidden potential within your hardware, making it a great optimization tool for machine learning algorithms. The most popular language for machine learning apps, Python, is also written in C.
As a memory-efficient, performant language that maps easily to machine code, C is often found somewhere in the underlying source code of any software that must access native resources on a host machine.
Why learn the C language?
In a world seemingly dominated by high-level languages such as JavaScript and Python, you might be wondering why someone would still learn C?
- H3: The size of the code: C binaries and runtime are incredibly lightweight. The language was designed to fit on small microcontrollers
- H3: Efficiency and portability: C was designed to be both portable and efficient. It’s about as close as you can get to the efficiency of an assembly language without sacrificing portability. Due to its ubiquity, there is a compiler for just about every conceivable architecture, making the language easy to port to other operating systems and processors.
- H3: Placing data in custom addresses: In real-time systems where calls to a garbage collector for memory management can be too costly, or there is not enough memory for dynamic allocation of the heap and stack, the ability to point directly to custom addresses is a lifesaver.
- H3: Memory manipulation: In the world of systems programming, it’s important to have a full understanding of how memory works and full flexibility to dictate how your application uses that memory. That ability to place data in custom addresses via pointers gives you unprecedented control over memory manipulation that cannot be replicated in higher-level languages.
Many of those popular higher-level languages also use C within their binaries, compilers, and interpreters. Learning C can give you an edge and a greater appreciation for what higher languages can do while gaining the skills to perform systems-level optimizations when needed.
How does the C programming language work?
Computers don’t speak the same language we do, so we must translate our language into the 1’s and 0’s a processor understands. The C programming language works by writing your code into an executable file. The C compiler will take that executable and convert it in its entirety into machine code that will then be executed by your computer at runtime.
Below is a C code example program for displaying “Hello World”:
#include <stdio.h>
int main() {
// printf() displays the string between the quotation marks
printf("Hello, World!");
return 0;
/* We can also use getch(); as a terminating function instead of return 0; */
}
There are a few things to note from this code example that can tell us how a C program works:
- First, we use a preprocessor command #include telling the compiler to include the header file stdio. h in the program. Loading this header file is necessary because we wish to use the standard input and output function printf() to print our message.
- Next, we initialize the main function we wish to program with int main() {}
- Then we specify within the curly brackets “{}” what we want the function to do. In this case, we use printf(“Hello World!”); to print our message.
- Finally, we need to tell the compiler when the program is finished by closing with an exit status using a return statement (return 0;). You can also terminate the program with getch() if you want to hold the screen for further user input.
Compile the code and you will return the output “Hello World!”
This example was very basic and only demonstrates a fraction of C’s power. We can use conditionals, control statements, and data structures to perform more complex tasks.
Because C is so fast, lightweight, and efficient it is often the underlying language behind many higher-level programming languages and libraries such as the popular Node.js library for server-side JavaScript. If you are setting out to build a new language, chances are high that you’ll use C to write the low-level libraries that will allow that language to communicate with the machine. This layer of abstraction will be hidden from the end-user of your programming language.
Basic C commands you should know
Now that we’ve walked you through an example of this code let’s recap the six most common commands every C programmer should know:
- include <stdio.h> which lets you include input and output functions found within C’s most basic standard library file, the header file <stdio.h>. Common functions found within <stdio.h> include print(), scanf(), puts(), and remove().
- int main() is something that you will see in most programming languages. It allows you to initialize the main function which is the starting point of your program. It’s also where you can pass command line arguments.
- { and } Are used to mark the start and end of a function. This syntax is popular in most programming languages.
- /*_some_comments_*/ allows you to write comments for other developers to read. Text between the /*text*/ will not be compiled or executed.
- getch(); is used to tell your program to wait for user input. It pauses the output screen until a user presses any key.
- Return 0; is an alternative way to terminate a function. It simply returns the integer 0, ending the program.
These C commands give you the basic syntax for constructing a C program. Understanding the basics can help you create more complex programs.
C – more than a basic programming language
In this article, we gave a quick overview of the C programming language, what it is, where it’s used, and why programmers love it. There’s a reason C consistently ranks among the top two positions on the coveted Tiobe Index. It’s the lingua franca of programming languages. If you learn C you will be forced to grapple with fundamental concepts of programming itself such as memory management and data types. These skills can translate into learning other languages and help you better communicate ideas to other programmers.