C language is used in areas where the program must be closely interacting with the hardware. C, C++, C#, Java, and Objective-C appeared under strong influence of C.
C is sometimes called a subset of C++ or "C++ without classes", but this is not completely true. C language appeared earlier than C++.
C supports only procedural programming. No classes, OOP, inheritance, incapsulation - only functions and structures.
The main features of the C language include:
- Access to memory through pointers (special variables in which the address of the object is stored);
- Active use of structures and unions;
- pure programming style (code is easier to debug, but harder to write).
C is usually used in fairly specific and complex tasks, because easier tasks are easier to do with higher-level languages.
We have selected some of the most popular C applications:
Optimization of code sections in C++
The object-oriented features of C++ are often more expensive than "pure C", as they consume more resources (in particular RAM). Therefore, sometimes C-style code can be more efficient. If you need to make any algorithm work faster, use the procedural style and abandon the built-in C++ tools for OOP, for example, polymorphism.
But if you need really high speed, it is better to rewrite critical parts of the code in assembly language.
This includes sophisticated hacking techniques.
- Use of vulnerabilities: buffer overflows, double deletions (heap damage).
- Injection (hiding) of the code. If you access another process using the vulnerability, you can hide your code inside someone else's and force the process to execute it. Now the hidden code will live in an "innocent" process, hidden from the user's eyes.
- Hooking. If you want to monitor someone’s interactions with the system (keystrokes, opening files), you usually need to call the tracking code whenever the user does something. To do this, you replace any fragment of the operating system API with your code.
For almost all of these applications, a PIC code is used (position-independent code - an address-independent code). It can be executed anywhere in the memory, regardless of where it is or who launched it. PIC code does not have access to global variables and tables, so C++ is not suitable for writing it (C++ classes need global tables to implement inheritance).
Code that runs in kernel mode has full access to memory and hardware: RAM, GPU, Hard disk.
Kernel mode is used for writing specific programs, which include:
Hardware drivers - one needs low-level hardware access here. Drivers are intermediaries between user code (not in kernel mode) and hardware.
The core of the operating system. By the way, many OS kernels are written in C, including Unix and Android.
It is almost impossible to use C++ code for all this, since in kernel mode there is no access to the same global tables mentioned above. Sometimes in kernel mode, PIC code is also needed - for example, for the bootloader. The bootloader is the very first program that runs when the PC starts. The BIOS or UEFI loads it from the hard drive, puts it into memory and tells the processor to start this part of the memory.
Embedded Firmware Development
For programming embedded systems, both C and C++ are often used. But C has an advantage because it allows you to develop firmware with limited resources - for example, when the microcontroller has very little RAM. In addition to C, knowledge of assembly language (as an option, ARM assembler) can also be useful for writing assembler inserts in order to further optimize the code and gain access to specific processor instructions.