Development Environments: C (and C++) Programming Setup
Image credits: Image created by the author using the program Spectacle.
Requirements
The requirements to start programming activities with C are similar to those described for JavaScript, Python, and Lua. However, C is a compiled language instead of an interpreted one, it uses a compiler instead of an interpreter. Thus, the first option is a text editor and a compiler. The second remains an Integrated Development Environment (IDE).
To avoid repeating the discussions from JavaScript and Python:
- If you already have a text editor, you can install and configure a compiler for the C language. However, the usage of a compiler requires, at least, one extra step if compared to the usage of an interpreter. Thus, if you are just starting, an IDE can be preferable;
- If you would rather use an IDE, the simplest option is choosing one that includes, at least, a text editor, a compiler and a debugger into a single program. A good option combining the three features is Code::Blocks;
- If you do now know how to install program, what is
PATH
or how to configure it, you can refer the topic regarding how to install programs. Unlike the previous languages,PATH
configuration can be required to use some C (and C++) IDEs.
Part of the contents of this page will be identical to the Python's page. Therefore, if certain paragraphs seem familiar, it will not an impression, but déjà vu. As a matter of fact, this will also occur in new entries about development environments for other programming languages. After all, the setup procedures are similar.
On the other hand, most of the content will be new, because C is a compiled programming language. Compiled programs require an extra step before they can be used (the compilation), performed to transform source code into an executable file (the computer program).
In particular, the section discussing Compilers and Programs is one of the most detailed sections up to this point. If it is not necessary to fully understand it at this moment (especially if decide to use an IDE), though it is important to remember it once you must work with external libraries.
In fact, unless you are experienced using the command line, I strongly advice beginners to use of IDEs for both the C and C++ programming languages.
C and C++
A development environment for C is often also enough for C++. Tools that are compatible with C++ are often compatible with C as well. Furthermore, it is possible to use C code in C++. Although that does not mean that all C code is compatible with C++, implementations based on older standards (such as C89) often are compatible with C++. On the other hand, the reciprocal is not always true; C++ code without proper implementation choices is often incompatible with C.
For this entry, the most important takeaway is that the concepts to compile C code are also applicable to C++. Thus, instead of repeating them, the page describing how to set up C++ development environments refers to this page.
C as the First Programming Language
Python and Lua lead my list of recommended programming languages for beginners, as previously commented in introduction about development environments; the third option is JavaScript, due to the Internet.C is far on my list, because it is a lower level language (that is, closer to the hardware) than Python, Lua and JavaScript (which are all higher level languages than C). For the first steps with programming, C definitely is not my recommendation. It is not impossible to learn C as a very first programming language (it was my first), though it is far from being ideal.
C programming requires operations that are abstracted, simplified or non-existent on modern languages. The knowledge of these operations contributes to train good programmers, though it is an additional difficulty that is unnecessary for first programming activities.
Furthermore, there are parts of the C standard library that require attention and very careful use.
Indeed, some parts are potentially dangerous enough that they virtually should never be used (such as gets()
).
Thus, if you can choose, I recommend starting with Python, Lua, and JavaScript. It is better to focus on learning programming concepts, logic and computational thinking first. You can return to C once you are more experienced. It will be probably simpler and more productive to learn C once you understand the basics.
About C
C is a traditional, compiled, and, if used correctly, high performance and efficient programming language. It provides a thin abstraction over the hardware, with low overhead. The language is a good choice to write operating systems and embedded systems, as well as compilers, interpreters and libraries requiring excellent performance and availability to multiple architectures and platforms. In fact, the kernel of the Linux operating system, which is used on the most varied devices, is one of the most famous projects written in C.
C is a simple language regarding its resources, though it is not exactly simple to use and learn. In fact, C simplicity comes from a lack of resources. It is, thus, elegant to experience people, tricky to beginners (and also for the experienced).
It is necessary to understand how the hardware, and computer and software architectures work to program well in C. To program very well in C, it is necessary to understand concepts such as memory layouts and how to program in machine code. This happens because C is often classified as a low to mid level language. One of the lowest possible levels is programming using machine language. C is close to the hardware. In fact, it is so close that it is possible to include assembly in C source code files, with the appropriate directives.
C is an old language, which does not provide modern and convenient resources from modern languages. There are not predefined data structures (only arrays are part of the language, that is, sequences contiguous positions of memory), there is not even a data type for strings. A character is an integer number. Strings are arrays of numbers. Although this is true for that is how computers work, the result is not convenient for programmers.
Thus, C is not a language for beginners. Unlike modern languages, C assumes that the programmer knows what she or he is doing. The programmer is truly powerful in C. The liberty has its costs, from which it is possible to cite the learning complexity and the higher potential to make mistakes.
For instance, the language does not impose run time checks nor limits the access to the memory of the machine. Provided that the code is syntactically valid, the operation is allowed. In other words, C allows operations that are not allowed (or, at least, hard to perform) in other programming languages, such as accessing arbitrary memory positions by their addresses (including ones that are not owned by the program itself, something that good operating systems do not allow).
Thus, a possible outcome from learning C can be appreciating the conveniences that are commonly provided by modern programming languages. Another outcome can be noticing how modern program languages hinder (in the sense of "get in the way") of the programmer.
One of C differentials is the higher predictability for the machine code generated by the compiler from the source code. Sometimes, the resulting machine or assembly code is practically a direct translation of the required instructions to convert the C source code to machine code. In other words, the language tends to do exactly what the programmer has instructed it to do.
With proper care, C allows writing source code that is portable among different computer architectures (provided that there exists a compiler that is compatible with the chosen architecture and platform). Library written in C even are used as basis for other programming languages. Some program languages themselves have reference implementations written in C. Furthermore, it is possible to share code among different programming languages by creating a C interface, as well as using technologies such as Common Gateway Interface (CGI) to use C with Web systems.
In short, C is one of the programming pillars and excels on what it proposes to do. Its relevancy from its creation (1972) to the current days is proof.
However, teaching and learning are not strong points of C in the 21st century. For teaching programming, the most applicable inheritance from C can be the "Hello, world!" program, defined by Brian Kernighan and Dennis Ritchie in the book The C Programming Language.
For C documentation, you can use the following resources:
- Manual pages on Linux systems.
Use the
man
command. For instance:man 3 printfPRINTF(3) Linux Programmer's Manual PRINTF(3) NAME printf, fprintf, dprintf, sprintf, snprintf, vprintf, vfprintf, vdprintf, vsprintf, vsnprintf - formatted output conversion SYNOPSIS #include <stdio.h> (...)
- The GNU C Library (glibc) documentation;
- MSDN, for Microsoft's `MSVC` compiler;
- cppreference.com;
- cplusplus.com.
Versions
C has always been a relevant language; nevertheless, the language standard have had a resurgence in the last years. Until a decade ago, the predominant standard where C89 or C90, defined in 1989 and 1990, and C99, published in 1999 (and not supported by some popular compilers).
In the last decade, the C11 and C17 standards have modernized a little the C language. However, the support for the new standards vary by compiler. To use new resources, it is necessary to verify the support by the chosen compiler and target platform.
For learning activities, it is likely that many materials follow the C89 and C90 standards for resources and examples. If you are interested in the new resources, it can be useful to search for terms like "modern C".
In addition, the quality of the C standard library (especially for older standards) varies. As many programs (read decades worth of software creation) rely on the erratic behavior of the standard library, some problems which should have been solved a long ago remain to this day, for solving them could affect existing programs in potentially unpredictable ways.
Thus, it is convenient to choose high quality external library for professional C development, especially for operations such as string manipulation. For educational purposes, it can be interesting to create your own standard library.
Compilers and Programs
Unlike JavaScript, Python, and Lua, that are interpreted languages, C is a compiled language.
In practice, this means that there exists an additional step for programming: the generation of a program in the form of an executable file (for instance, with the .exe
extension on Windows).
Thus, for instance, to use a "Hello, World" program written in an interpreted language such as Lua, one can create something like (script.lua
):
print("Hello, world!")
To interpret and run the code:
# File creation; you can use any text editor.
emacs script.lua
# Interpreting and running the program.
lua script.luaHello, world!
If one wishes to run the program again, it is necessary to reinterpret it.
# Interpreting and running the program.
lua script.luaHello, world!
The interpreter converts Lua source code into code used by the computer at use time.
In a compiled language such as C, the process requires using a compiler (for instance, gcc
on Linux or mingw
on Windows) and running the generated program.
Executable files on Linux usually do not use an extension, though the following examples will use .exe
to ease the identification of the generated file for the program.
To compile with gcc
, the file name (or path) must be provided.
The minimum required command resembles gcc my_file.c
, which will generate a program using the default name (usually something like a.out
or a.exe
).
To choose a name for the output program, you can use the option -o
.
For instance, if you want an output program file named my_program.exe
, you should write -o my_program.exe
.
Combining both parameters, the command becomes gcc my_file.c -o my_program.exe
.
To convert the Lua example into an equivalent C program, we can consider the following C program, written in the file program.c
(printf()
is a function from the standard library to write in console; documentation. stdio.h
is the library that defines the printf()
function):
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
return 0;
}
Next, you need to compile source code into a program before running it. The compilation succeeded only if the source code does not have any syntactic errors.
# File creation; you can use any text editor.
emacs program.c
# Compiling.
gcc program.c -o my_program.exe# Running the program.
./my_program.exeHello, world!
To run the program on Windows, you should use my_program.exe
instead of ./my_program.exe
.
Alternatively, you can double-click on the icon for the file my_program.exe
to run it on Windows.
After compiling the file, you can run it again whenever you wish to use the program in the future.
# Running the program
./my_program.exeHello, world!
The file
command available on Linux can show that the resulting program file is an executable file.
file my_program.exemy_program.exe: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9c567624f5b731ccb0f18141f9490a7b8421ef21, for GNU/Linux 4.4.0, not stripped
Thus, one advantage of creating a binary executable file for a program is becoming able to use the program in another machine without needing to install the development environment (for instance, the compiler).
To be more exact, some libraries may be required to run a program, depending on the type of link used by the dependencies.
For instance, programs written in C++ for Windows (for instance, digital games or video games) using the MSVC
compiler often require installing the Visual C++ redistributable packages.
A disadvantage of compilation is that it is only possible to a program in another machine if the machine's architecture and platform are compatible with the format of the executable file.
If the actions required to compile and run programs seem to require incompatible efforts to start programming activities, you can use an IDE. A good IDE will provide an option to compile and run the program (if the compilation was successful), simplifying the required operations and enabling you to focus on learning. Should the compilation fail, the IDE will show a list of errors provided by the compiler (usually with shortcuts to browse the line on which the error was identified in the embedded text editor).
Cross-Compilation
To generate an executable file from a platform to be used on another platform (different from the first), it is necessary to perform a cross-compilation.
For instance, a compatible compiler can generate a program from a Linux machine to be used on another machine running the Windows operating system.
A possible compiler for Windows is called mingw
(the gcc
for Windows).
Thus, an example of cross-compiling from Arch Linux to Windows could be:
# File creation; you can use any text editor.
emacs program.c
# Compiling.
x86_64-w64-mingw32-gcc program.c -o my_program.exe# The resulting file can be used on Windows, not on Windows.
The usage of the resulting program requires a Windows environment. It could happen in a different machine or at the same one, using dual boot, a virtual machine, or even only on Windows, if the previous compilation was performed using the Windows Subsystem for Linux.
# Running the program on Windows.
my_program.exeHello, world!
Libraries and Link
Link, which uses a tool called linker, allows combining source code existing on different files into the generation of a single program. The need to learn how to link libraries can take a while (or not); it depends on the used libraries, of the environment, and the choice of using (or not) an IDE.
As an example, the standard Mathematics library (math.h
) is one of those that may require using the linker (it depends on the system).
The following programs use sqrt()
(documentation) to calculate the square root of a number.
#include <stdio.h>
#include <math.h>
int main()
{
printf("%f\n", sqrt(25));
return 0;
}
To compile the program, the -l
(lowercase l) character is required to use the linker, followed by the name of the library.
For instance, if a library is called Lib
, you should use -Lib
.
If you want to use multiple libraries, this process must be repeated for each one.
For instance, for the libraries Franco
, E
, and Garcia
, the resulting linker options would be -lFranco -lE -lGarcia
.
In the case of the math.h
library, the library filename is usually m
(the name of the compiled library file can be different from the one used in the header), resulting in -lm
.
# File creation; you can use any text editor.
emacs square_root.c
# Compiling. The linker uses the `-l` parameter followed by the name of the library.
# For `math.h`, we use `m`, resulting in `-lm`.
gcc square_root.c -lm -o square_root.exe# Running the program.
./square_root.exe5.000000
Furthermore, if the link is dynamic, a file with the compiled linked library must be present either in the directory of the executable file or in the PATH
.
If the link is static, the library code is added into the compiled application.
IDEs can reduce the need to use the linker for libraries belonging to the standard library. Therefore, this is another reason that a good IDE is a relevant option to start programming in C.
Besides the linker, you may also need to set directories.
Library and Directories of Headers
Even using an IDE, a linker is virtually required to use external libraries. For instance, if you want to use a graphical library in C or C++, you will need to use the linker -- and more.
Besides configuring the linker, it is also required to set paths for headers and/or source code of the external libraries. To do this, the compiler requires an additional parameter.
For instance, gcc
uses the L
(uppercase L) followed by the path to the directory of the library.
If the path to the library is /home/franco/Desktop/lib
, you should use -L/home/franco/Desktop/lib
as the parameter.
As it was the case for -l
(lowercase l), it is necessary to pass all paths to the desired libraries.
Thus, for the libraries Franco
in /home/franco/Franco/
, E
in lib/E/
, e Garcia
in ../Garcia/
, the inclusion for directories would become: -L/home/franco/Franco/ -Llib/E/ -L../Garcia/
.
As you may notice, it is possible to use absolute and relative paths. As a rule of thumb, the ideal is using relative paths whenever possible, and build absolute paths with environment variables when a relative path is not an option.
It is prudent to highlight that you should combine all parameters to compile the program. Thus, the example could become:
gcc my_program.c \
-o my_program.exe \
-lFranco -lE -lGarcia \
-L/home/franco/Franco/ -Llib/E/ -L../Garcia/
In this case, the \
(backslash) at the end of a line in interpreters like bash
e zsh
allows to continue a command in multiple lines.
If a backslash is not used, the command must be written in a single line:
gcc my_program.c -o my_program.exe -lFranco -lE -lGarcia -L/home/franco/Franco/ -Llib/E/ -L../Garcia/
Build Systems
If it seems somewhat complicated to compile programs in C (and C++), there programs called build systems or build automation software that try to simplify the process.
Some options include:
Some options, such as CMake
, can even generate build systems compatible with other build systems.
In other words, build systems can be complex. Thus, if C (and C++) compilation could seem complicated, it is always possible to make it even more complex.
An alternative for simple projects is to create a shell script.
On Linux, options include bash
, zsh
, csh
and fish
.
On Windows, options include .bat
(for cmd
) and PowerShell
.
The principle is writing the compilation line the script and using it whenever necessary.
The minimum contents of the file is the line to compile the program.
A potentially desirable improvement is to configure the PATH
inside the shell script.
Nevertheless, some techniques are interesting and useful. There are techniques and advanced resources for compilation, including incremental compilation, which only builds files that have changed since the last compilation, and the very interesting hot swap or run-time compilation (an example), that allow recompiling a running process.
Compiler and Text Editor
You should use root
or administrator
accounts only to install the compiler.
After the installation, use a regular user account, with lower privileges, to run the compiler and program using it.
You should also run your created programs with a regular user account.
Linux
C is part of every Linux distribution, for the majority of the kernel is written in the language. Thus, there are distributions that include a pre-installed C compiler out of the box.
To start programming in the language, you should choose a compiler. A traditional option is the GNU Compiler Collection (GCC). Another option is Clang.
The following examples describe how to install gcc
in some Linux distributions.
- Arch Linux:
You probably will not have to install GCC in Arch Linux. If you do need:
pacman -S gcc glibc
The package
gcc
includes the compilersgcc
(for C) andg++
(for C++). - Debian, Ubuntu or distributions based on the former ones:
apt-get install build-essential # If you also want to install the manual pages: apt-get install manpages-dev
The package
build-essential
includes the compilersgcc
(for C) andg++
(for C++). - Fedora:
dnf install gcc glibc
If you want to install the
g++
compiler for C++, you can use:dnf install gcc-c++ glibc
- Gentoo:
You probably will not have to install GCC in Gentoo. If you do need:
emerge --ask --oneshot sys-devel/gcc
I believe that Gentoo includes
g++
withgcc
, though I am not sure.
macOS
On macOS environments, you can use brew
to install GCC.
Another option is installing the IDE Xcode, that includes Clang.
Windows
A GCC implementation for Windows is called Minimalist GNU for Windows (MinGW).
Among other options, you can install MinGW
using the previous link to the official page of the project, via Cygwin, MSYS2, or using Scoop e Chocolatey, mentioned in the entry describing how to install programs.
Both Scoop and Chocolatey can install the compiler with ease.
If you do not use either, MSYS2 can be a convenient option because it allows using other programs such as git
.
The project page describes how to install it.
Should you wish to add the interpreter to the PATH
, refer to how to install programs.
For convenient, the following instructions also describe how to install MSYS2
.
If you do not want to change the installation directory (it must not have spaces nor accents), you can simply proceed with the installation: Next
, Next
, Next
, Next
, Finish
.
To start MSYS2
, search the Start menu for msys
and press enter
when the option MSYS2 MSYS
appear.
The option will open the terminal Mintty, which uses bash
.
The process to install programs is similar to using pacman
on Arch Linux.
The first step is updating the system:
./pacman -Syu:: Synchronizing package databases...
mingw32 1461.1 KiB 424 KiB/s 00:03 [#####################] 100%
mingw64 1468.3 KiB 421 KiB/s 00:03 [#####################] 100%
ucrt64 1609.9 KiB 1094 KiB/s 00:01 [#####################] 100%
clang64 1452.3 KiB 446 KiB/s 00:03 [#####################] 100%
msys 387.5 KiB 357 KiB/s 00:01 [#####################] 100%
:: Starting core system upgrade...
resolving dependencies...
looking for conflicting packages...
Packages (5) filesystem-2021.06-2 mintty-1~3.5.1-1 msys2-runtime-3.2.0-15
pacman-6.0.1-3 pacman-mirrors-20210902-1
Total Download Size: 9.38 MiB
Total Installed Size: 45.57 MiB
Net Upgrade Size: 0.21 MiB
:: Proceed with installation? [Y/n]
Y
The first update will close the terminal. Open it again (using the Start menu). This time, use:
./pacman -Su:: Starting core system upgrade...
there is nothing to do
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...
Packages (28) bsdtar-3.5.2-1 ca-certificates-20210119-3 curl-7.79.1-1
gdbm-1.21-1 glib2-2.68.4-1 gnupg-2.2.29-1 gzip-1.11-1
icu-69.1-1 less-590-1 libcurl-7.79.1-1 libedit-20210714_3.1-1
libexpat-2.4.1-1 libgcrypt-1.9.4-1 libgdbm-1.21-1
libidn2-2.3.2-1 libnghttp2-1.45.1-1 libopenssl-1.1.1.l-1
libp11-kit-0.24.0-1 libreadline-8.1.001-1 libsqlite-3.36.0-2
libssh2-1.10.0-1 libxml2-2.9.12-2 msys2-keyring-1~20210904-1
nano-5.9-1 openssl-1.1.1.l-1 p11-kit-0.24.0-1 tzcode-2021c-1
wget-1.21.2-1
Total Download Size: 22.70 MiB
Total Installed Size: 79.53 MiB
Net Upgrade Size: 0.24 MiB
:: Proceed with installation? [Y/n]
:: Proceed with installation? [Y/n]
Y
This will allow you to install other programs.
To install MingGW
:
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
When the system asks what you want to install, you can press enter
to install everything (all).
After the setup finishes, you can close MSYS2
.
To start gcc
, search for MSYS MinGW 64-bit
in the Start menu.
In the console, it will be called gcc
, as it happens in Linux.
Hereafter, the commands will be similar to those used on Linux.
The next step is finding your files in the terminal.
To get a list of disks in your computer, you can use the command df
.
dfFilesystem 1K-blocks Used Available Use% Mounted on
C:/msys64 145706840 108812024 36894816 75% /
D: 257564668 254681332 2883336 99% /d
E: 811839484 775074060 36765424 96% /e
In the previous example, the directory C:\msys64\
is available on /
.
The C:\
drive is on /c/
.
The D:\
drive is on /d/
, and so on.
The number of disk units can vary in your computer.
It depends on the available number of disks and partitions in your machine.
With the previous information, to access files in the desktop of an account called Franco
, you can browse to /c/Users/Franco/Desktop/
.
cd /c/Users/Franco/Desktop/
# If you want to list files and directories in the desktop:
ls -l
Now you can compile files stored in the desktop. Change the folder according to your needs.
Besides MingGW, MSYS2
provides thousands of ready to use packages, listed on this link.
Alternatives to install the compiler on Windows include:
- The new Windows Subsystem for Linux;
- Chocolatey or Scoop;
- An IDE with an integrated compiler (for instance, Code::Blocks).
Environment Test
You can start to program in C (and in C++, for many previous systems) after installing the compiler.
To use the compiler, use its binary file or type gcc
(the name can vary on Windows, depending on the installation; for instance, it can be named mingw
) in a command line interpreter (this requires setting up the PATH
for manual installs; click here for information on how to configure it).
Unlike interpreted languages, C is compiled, and, therefore, you do not run the compiler to program in the language. As described in Compilers and Programs, a source code file is provided as a parameter to the compiler, which will be used to generate the program (as an executable binary file).
This section presents the same examples used in JavaScript, Python and Lua for purposes of testing and comparing the languages.
Thus, to start, you can create a file with the following contents:
#include <stdio.h>
int main()
{
printf("Olá, meu nome é Franco!\n");
return 0;
}
The message means "Hello, my name is Franco!" in Portuguese. Instead of translating it to English, it uses accented characters for further explanations.
Choose a name for the file (for instance, ola.c
) and compile it:
gcc ola.c -o ola.exe
The result will be a program called ola.exe
as an executable file.
For a better integration with your platform, choose (or omit) a file extension according to your operating system:
Linux:
gcc ola.c -o ola
Windows (choose between
gcc
ormingw
, according to your setup):gcc ola.c -o ola.exe
macOS:
gcc ola.c -o ola
To run your program:
Linux:
./olaOlá! Meu nome é Franco.
Windows:
# For use with `cmd.exe`: ola.exeOlá! Meu nome é Franco.
If you are using
MSYS2
onbash
instead ofcmd
, the process is similar to Linux; that means you should run the program as./ola.exe
:# For use with `MSYS2`: ./ola.exeOlá! Meu nome é Franco.
macOS:
./olaOlá! Meu nome é Franco.
Error: Stray Character in Program
In some operating systems (likely on Windows) and compilers (on the command line or IDE), it is possible that the compilation fails with an error message resembling error: stray '\###' in program
if you copied and pasted source code with accents.
This happens due to differences in codification used in the text file used by the source code and the text that was copied from this Web page and pasted in the editor.
There are three options to continue:
- Configure your text editor to use the same codification adopted on this page: Unicode Transformation Format 8-bit (UTF-8). The default encoding used by Windows to Latin languages is called Windows-1252. It is important not to mix characters with different encoding in a source code file. UTF-8 is a good option for compatibility with all modern operating systems.
- If you have copied and pasted the code, you can erase it and type the text yourself. This is a simple, though inconvenient, way of avoiding the problem;
- Remove accented characters or other special symbols from strings and comments.
Where Are the Accents?
In some operating systems (likely on Windows), accents may not work when you run the program.
Instead of accented letters, there can appear incorrect characters (or Greek letters).
For instance, Olß, meu nome Ú Franco!
.
In some cases, there can appear two or more characters when there should appear only one.
It could look something like: Ol├í, meu nome ├® Franco!
.
This is, once again, a problem with text encoding and decoding.
C treats strings (words and text) as arrays of bytes encoded in American Standard Code for Information Intrechante (ASCII).
Each character of the type char
has exactly 1 byte (8 bits).
With one byte, it is possible to represent 256 characters, at most.
ASCII encodes one character per byte, thus the representation works correctly.
As it name suggests, ASCII only encodes characters from the English language. However, there are languages besides English -- and many more than 256 possible symbols for characters.
UTF-8 allows encoding characters for different languages, and it is retro-compatible with ASCII for characters of the English language.
However, characters in UTF-8 can require multiple bytes (one to four, more specifically).
In other words, a single character in UTF-8 can have multiple bytes.
For instance, the accented character á
in UTF-8 has 2 bytes.
In ASCII, its value would correspond to two characters instead of a single one.
Thus, depending on the chosen codification for text in the source code and the codification used by the program, the results can vary.
To fix the problem, you need to configure the locale, which defined options for localization of formats (strings, numbers, currencies...).
To configure it, there is the function setlocale()
(documentation).
After defining a correct value for the text codification, the correct results should appear in the console.
Unfortunately, the correct value can vary according to opeating system, chosen encoding, or even a custom configuration for an user account. Some possible values for Brazilian Portuguese include:
- On Linux:
"pt_BR.utf8"
;"pt_BR.UTF8"
;"pt_BR.UTF-8"
;"pt_BR.ISO-8859-1"
.
- On Windows:
"Portuguese"
;"Portuguese_Brazil.1252"
;"pt_BR"
;"pt-BR"
;"pt"
.
An alternative is using ""
to choose the default configuration for the person using the computer.
For instance, if her/his system is in Brazilian Portuguese, ""
will return something like pt_BR.UTF-8
on Linux Portuguese_Brazil.1252
on Windows.
If you are reading this page in English, it is likely that your operating system's language is not Portuguese.
If you want to see the accented characters, you will need to use one the non-empty (that is, different than ""
) previous values.
#include <locale.h>
#include <stdio.h>
int main()
{
// "": default locale for the operating system. setlocale(LC_ALL, ""); // If your system is not in Portuguese, you can try something like: // setlocale(LC_ALL, "pt_BR.utf8"); // or "pt_BR.UTF-8" // setlocale(LC_ALL, "Portuguese"); // or "Portuguese_Brazil.1252" or "pt_BR" // or "pt-BR" or "pt"
printf("Olá, meu nome é Franco!\n");
return 0;
}
Thus, if you want to use accents and other special symbols correctly, remember to set up the locale()
.
Back to the Tests
After the issue of accents, you can create a second C source code file to continue the tradition from previous languages.
In compiled languages, this would be the first script as a source code file to create a program.
Thus, the filename could be first-program.c
.
This time, technically, this will not be your first program.
Therefore, if you wish to number it correctly, change the name.
If the filename contains spaces, write the parameter to the compiler between double quotes (for instance, as gcc "Name with Spaces.c" -o "My Program.exe"
).
#include <stdio.h>
int main()
{
printf("My First C Program\n");
printf("Hello! My name is Franco.\n");
printf("The program can do Math.\n");
printf("Check it out: %d\n", 1 + 1);
printf("Bye!\n");
return 0;
}
To compile and run your program:
Linux:
gcc first-program.c -o first-program./first-programMy First C Program Hello! My name is Franco. The program can do Math. Check it out: 2 Bye!
Windows (if you are using
MSYS2
withbash
instead ofcmd
, the process is similar to Linux; that means you should run the program as./first-program.exe
):gcc first-program.c -o first-program.exefirst-program.exeMy First C Program Hello! My name is Franco. The program can do Math. Check it out: 2 Bye!
macOS:
gcc first-program.c -o first-program./first-programMy First C Program Hello! My name is Franco. The program can do Math. Check it out: 2 Bye!
Congratulations! If you have gotten to this point, now you understand how an IDE compiles and run programs behind the scenes. The next section shows how IDEs make the process easier, especially for beginners.
IDEs
The same considerations about the use of IDEs in Python apply to C (and C++). In particular, they are even more relevant for C (and C++). An IDE makes it easier to compile and run programs under development. If you are not familiar with the command line, an IDE will help you to focus on activities to learn programming instead of how to use a shell.
Thus, the option to run code with a single click is very convenient in C (and C++).
In particular, search for the option to run a project with a single click (normally on a triangle icon (🢒
) commonly used to play content eletroelectronics) or with a key press (usually F5
).
Furthermore, remember shortcuts for text editors, such as Ctrl n
(or File / New
) to create new files and Ctrl o
(or File / Open
) to open existing files.
There are many high quality IDEs for C and C++. However, many can be complex for beginners. It can be important to find a middle ground between features and ease of use.
To start out, Code::Blocks is a good option and perhaps one of the simplest. The simplest option is possibly Dev-C++, though it is not, necessarily, one of the best.
In general, any IDE that eases the required processes to compile and run programs are potentially useful for beginners. As you acquire more experience and practice, you can explore other options and pick a favorite one. Once you are at this point, my recommendation is choosing the IDE which provides the best integration with a debugger for your use cases.
Code::Blocks
Possibly an excellent option for beginners who are using Windows, Code::Blocks balances ease of use with features.
The IDE is more modern than Dev-C++
while simpler than options such as Visual Studio
.
The integration of the IDE with its debuggers has also been improving the latest versions.
Furthermore, it is possible to download versions of Code::Blocks
that include the mingw
compiler on Windows, which removes the necessity to configure the compiler before using it.
To download one of these versions, you should choose the options including the term -mingw
in the download filename.
To install Code::Blocks
on Windows (20.03
was the latest version when it was accessed; the value can vary):
- In the initial page, click in Downloads;
- Next, click in Download the binary release;
- In the next page, choose one of the files:
- For 64-bit systems (suitable for most cases; if you have a very old computer, choose the 32-bit one):
- Installer:
codeblocks-20.03mingw-setup.exe
. - Archive to extract and use the executable file
codeblocks.exe
(orCbLauncher.exe
):codeblocks-20.03mingw-nosetup.zip
.
- Installer:
- For 32-bit systems:
- Installer:
codeblocks-20.03-32bit-setup.exe
; - Archive to extract and use the executable file
codeblocks.exe
(orCbLauncher.exe
):codeblocks-20.03-32bit-nosetup.zip
.
- Installer:
- For 64-bit systems (suitable for most cases; if you have a very old computer, choose the 32-bit one):
If you choose FossHUB
to download, the option with the compiler is named including compiler.
For the installer, the simplest option is performing a full install: Full: All plugins, all tools, just everything
.
If the IDE does not find the compiler after the setup, click in Settings / Compiler / Global Compiler Settings
.
Then choose GNU GCC Compiler
.
Next, choose Restore defaults
.
To create a source code file using Code::Blocks
, click in File / New / Empty File
(shortcut: Ctrl Shift N
), write the code and salve the file.
To compile and run the program, click in the with of an engine with a play triangle (or use the shortcut: F9
).
To create a project with multiple files, click in File / New / Project...
.
Next, choose Console application
, then Next >
, choose a language (C or C++), click in Next >
.
Choose a title for your project and a directory to store its files.
Click Next >
.
In the next screen, keep both options active (Debug
and Release
), then click Finish
.
The process to compile and run is the same used for files.
The easiest way is pressing the F9
shortcut.
If you with to translate the IDE (for instance, to Portuguese), click in: Settings / Environment / View
.
Mark the option Internationalization
, choose the language and restart (close and reopen) the IDE.
It is important to notice that the IDE language does not affect the output of programs.
Thus, if you wish to use characters that do not belong to the English language, you have to set the locale with setlocale()
.
Dev-C++
Dev-C++
is a very traditional IDE for beginners starting programming in C and C++.
It also resists the time.
First released in 1998, the IDE is on its fourth generation of maintainers:
- Last updated on 2005: Bloodshed Dev-C++ (the original);
- Last updated on 2012: wxDev-C++;
- Last updated on 2016: Orwell Dev-C++;
- Last updated on 2021: Embarcadero Dev-C++.
As the first options are out of date and have not been updated in the last years, choose the last option of the list to download the most recent version if you choose to use Dev-C++
.
In my opinion, one of the reasons for its success is the ease to compile and run a program.
Other IDEs (such as Code::Blocks
) now provide similar facilities, though Dev-C++
was the pioneer.
Dev-C++
is not the best, nor the most complete C and C++ IDE, though it is easy to use.
First, it includes a ready to use mingw
compiler.
Second, instead of requiring the creation of a project, it is enough to create a new file, write the code, and use the option to compile and run the resulting program.
Usability and ease of use are important features of software.
Dev-C++
is a demonstration that making a system easy to access and use can be more important than providing a system with better features, but high complexity.
Personally, I would recommend Code::Blocks
over Dev-C++
.
However, when you are stating, Dev-C++
is a valid option.
KDevelop
For Linux, KDevelop is another good option for C and C++ development. The IDE has versions for Windows and macOS under development, potentially serving as alternatives for these systems in the future.
Unfortunately, the experimental version for Windows do not provide an embedded compiler, something that can make it header to install by beginners.
Although there exists instructions to set it up, they require configuring the PATH
(check how to install programs to learn how to configure the PATH
).
On the other hand, if you use Linux, KDevelop
can be easy to configure, as the package managers commonly add compilers to the PATH
after they are installed.
Qt Creator
As it was the case for KDevelop, Qt Creator is a good option for all operating systems, though it may require manual setup for a compiler (and, thus, configuring the PATH
).
Qt Creator
tries to find available compiles and debuggers installed in the machine.
If it does not find any, you need to follow the documentation to configure the compiler.
The access to the downloads page for the IDE can be confusing.
For easier access, you can use this link or or this link to get the offline installer by choosing Qt Creator
on the page.
It is also possible to download the IDE from GitHub, something potentially desirable as it does not require creating an account.
The download from GitHub also provides an option including a compiler for Windows.
To get them, check the options with MinGW
(for GCC) or MSVC
(for Microsoft's C++ compiler) in the filenames.
Visual C++ / Visual Studio
On Windows, you can use Visual Studio, an IDE from Microsoft (the name is Visual Studio
; do not confuse it with Visual Studio Code
, discussed in text editors).
Previously, the version for C and C++ was called Visual C++
, while Visual Studio
referred to the program supporting multiple programming languages.
Nowadays, Visual Stuio
encompasses the former Visual
IDEs into a single program.
The free version is called Visual Studio Community
.
Visual Studio
is a popular option for professional C++ development on and for Windows.
Thus, if you decide to program C++ professionally on Windows, it is possible that you will use Visual Studio
on corporate environments.
Recent versions have simplified the processes to create projects. However, you cannot create a single file and compile it. You will need to create a project (sometimes called a solution in the IDE) and use it (even if the project has a single source code file).
The debugger from Visual Studio
is one of the most complete (from the graphical options) for C and C++.
The IDE used by the compiler (MSVC
) is modern for C++, though it may not be as up-to-date as GCC and Clang.
For C, the compiler was quite out of date when compared to other options, though this seems to have improved in 2020.
Regardless, even the poor support for C in older versions of Visual Studio
is enough to learn the language.
The main disadvantage is the lack of secure alternatives for deprecated functions of the C standard library.
To install the free version, choose Community 2019
after selecting the option Download Visual Studio with C++
.
For the setup, mark the option Desktop development with C++
.
The option allows programming in C and C++ (instead of other options, programming in C will use the same C++ compiler).
To create a new project:
- Choose
Create a new project
; - Choose
Console App
and clickNext
; - Choose a name and directory for the project, then click
Create
; - To compile and run, click in the play icon or press
F5
.F5
run the program with the debugging mode enabled. If you want to run the program without it, you can useCtrl F5
instead.
If you are a university student from a Science, Technology, Engineering and Mathematics (STEM) course (particularly Computer Science, Computer Engineering or Information Systems), you may be eligible for other free versions and/or systems from Microsoft via the project Microsoft Azure Dev Tools for Teaching (former DreamSpark and Imagine). However, it is necessary to verify if your learning institution has a partnership with the company.
Xcode
Apple provides the Xcode IDE for macOS. If you want to compile project for Apple devices, you will need the IDE (technically, there are alternatives for cross-compiling using Linux, though I do not know whether they are accepted by Apple Store).
As I do not use macOS, I do not have much to add.
However, if you do use it, Xcode
is probably the default option to use with the operating system.
Other Options
There are many other options of IDEs for C and C++, including:
First Steps to Begin Programming in C
The following source code snippets illustrate some resources of the C programming language. At this time, it is not necessary to fully understand them; the purpose is showing resources and the syntax of the language.
There are two ways of using the code. You can:
- Write and run the code in the IDE of your choice;
- Write the code using a text editor, generate a program using the file with code in a compiler, and run the generated program in your computer.
This simplest and fastest way is to use an IDE.
The examples are the same adopted for JavaScript. Therefore, you can compare languages, and notice similarities and differences between them.
Getting to Know C Through Experimentation
Text writing:
// gcc 1.c -o p1 #include <stdio.h> int main() { printf("One line.\n"); printf("Another line.\n"); printf("One line.\nAnother line.\n"); return 0; }
To compile and run without an IDE, create a file named
1.c
with the previous contents and type:gcc 1.c -o p1 ./p1
You can choose other name for the source code file (
.c
) and for the executable to be compiled. In the next examples, the compilation line will be commented in the first line of the source code.If you do not want to create a file for each example, you can erase the contents and write the code from the next example. If you do want to save a copy of each example, (at this moment) it is necessary to create individual files.
Comments (text that is ignored by the interpreter; documentation):
// gcc 2.1.c -o p2.1 #include <stdio.h> int main() { printf("Compiler processes\n"); // Compiler ignores. return 0; }
// gcc 2.2.c -o p2.2 int main() { /* <- Here the comment starts. It can spawn multiple lines. Here it ends -> */ return 0; }
// gcc 2.3.c -o p2.3 int main() { /* It can also start and end in the same line. */ return 0; }
// gcc 2.4.c -o p2.4 int main() { // Though, for single line comments, it is easier to use this comment style. return 0; }
Mathematics operations:
Sum, subtraction, multiplication and division (documentation):
In C, the division of two integer numbers result in an integer number (the remainder is truncated). To perform a real number division, at least one of the numbers must be real. For instance, compare the values of the divisions
6 / 4
and6 / 4.0
.
// gcc 3.1.c -o p3.1 #include <stdio.h> int main() { printf("%d\n", 1 + 1); printf("%d\n", 2 - 2); printf("%d\n", 3 * 3); printf("%f\n", 4 / 4.0); // What does happen if you try to divide by 0? Try it! return 0; }
- Math expressions:
// gcc 3.2.c -o p3.2 #include <stdio.h> int main() { printf("%f\n", 1 + 2 - 3 + (4 * 5) / 6.0); return 0; }
- Power (documentation: pow()):
// gcc 3.3.c -lm -o p3.3 #include <stdio.h> #include <math.h> int main() { printf("%f\n", pow(5, 2)); return 0; }
- Square root (documentation: sqrt()):
// gcc 3.4.c -lm -o p3.4 #include <stdio.h> #include <math.h> int main() { printf("%f\n", sqrt(25)); return 0; }
// gcc 3.5.c -lm -o p3.5 #include <stdio.h> // In some compilers, you may have to remove the comment from the next line // to use MATH_PI. // #define _USE_MATH_DEFINES #include <math.h> int main() { printf("%f\n", sin(M_PI / 2.0)); // Seno. return 0; }
Comparisons (
1
meanstrue
;0
meansfalse
; to be more exact,0
meansfalse
and non-zero meanstrue
):- Equality (documentation; strcmp()):
// gcc 4.1.c -o p4.1 #include <stdio.h> int main() { printf("%d\n", 1 == 2); // Equal: both equals are required! printf("%d\n", 1 != 2); // Different. return 0; }
// gcc 4.2.c -o p4.2 #include <stdio.h> #include <string.h> // strcmp() requires careful use... // Use only when learning; for distribution programs, only use if you know // what you are doing. int main() { printf("%d\n", !strcmp("Franco", "Franco")); // 0 as the result means equal; !0 == 1 para true. printf("%d\n", strcmp("Franco", "Franco") != 0); printf("%d\n", strcmp("Franco", "Seu Nome") != 0); // C differs lower case characters from upper case ones (and vice-versa). printf("%d\n", 'F' == 'f'); // Single characters in C are integer numbers. printf("%d\n", 'F' != 'f'); printf("%d\n", !strcmp("Franco", "franco")); printf("%d\n", strcmp("Franco", "franco") != 0); return 0; }
- Other comparisons (documentation):
// gcc 4.3.c -o p4.3 #include <stdio.h> int main() { printf("%d\n", 1 < 2); // Less than. printf("%d\n", 1 > 2); // Greater than. printf("%d\n", 1 <= 2); // Less or equal than. printf("%d\n", 1 >= 2); // Greater or equal than. return 0; }
Variables and assignment (documentation; fprintf()):
Variables are like boxes that store values put inside them. The assignment operator (a single equal sign (
=
) in C) commits the storage.// gcc 5.1.c -o p5.1 #include <stdio.h> int main() { int x = 123; printf("%d\n", x); return 0; }
// gcc 5.2.c -o p5.2 #include <stdio.h> int main() { float result = 123.456 + 987.654; printf("%f\n", result); return 0; }
You should note that you can declare a variable with a chosen name only once. However, you can change its value as many times as you need.
// gcc 5.3.c -o p5.3 #include <stdio.h> int main() { char name[32] = {'\0'}; snprintf(name, sizeof name, "Franco"); printf("%s\n", name); snprintf(name, sizeof name, "Franco Garcia"); printf("%s\n", name); return 0; }
// gcc 5.4.c -o p5.4 #include <stdio.h> #define MAXIMUM_LENGTH 32 int main() { char variables_can_vary[MAXIMUM_LENGTH] = {'\0'}; snprintf(variables_can_vary, MAXIMUM_LENGTH, "Franco"); printf("%s\n", variables_can_vary); snprintf(variables_can_vary, MAXIMUM_LENGTH, "Your Name"); printf("%s\n", variables_can_vary); snprintf(variables_can_vary, MAXIMUM_LENGTH, "Other Name"); printf("%s\n", variables_can_vary); return 0; }
// gcc 5.5.c -o p5.5 #include <stdio.h> int main() { int logical_value = 1; printf("%d\n", logical_value); logical_value = 0; printf("%d\n", logical_value); logical_value = (1 + 1 == 2); return 0; }
Constants (documentation):
// gcc 6.1.c -o p6.1 #include <stdio.h> #define PI 3.14159 int main() { printf("%f\n", PI); return 0; }
// gcc 6.2.c -o p6.2 #include <stdio.h> const float E = 2.71828; int main() { printf("%f\n", E); E = 0; // Error; the value of a constant cannot be changed once set. return 0; }
Errors:
// gcc 7.c -o p7 #include <stdio.h> int main() { print(Ooops!) // Text should be between double quotes. pri("Incorrect name for printf"); printf("%d\n", 1 / 0); printf("%d\n", 0 / 0); return 0; }
Strings for words and text (documentation):
// gcc 8.1.c -o p8.1 #include <stdio.h> int main() { printf("Ok, this is a valid string\n"); printf("%c\n", 'A'); // Single character. printf("Ok, this " " is also a " " valid string" "\n"); return 0; }
// gcc 8.2.c -o p8.2 #include <stdio.h> int main() { printf("If you want to 'mix' quotes, you have to use those different from the external ones.\n"); printf("Otherwise, you will need to escape them with a backslash, like this: \". The backslash is required.\n"); return 0; }
Logical operations (documentation):
// gcc 9.c -o p9 #include <stdio.h> int main() { printf("%d\n", 1 && 1); // This is a logical "and". printf("%d\n", 1 || 1); // This is a logical "or". printf("%d\n", !1); // This is a logical "not". return 0; }
Conditions (documentation):
// gcc 10.1.c -o p10.1 #include <stdio.h> #include <string.h> #define MAXIMUM_LENGTH 256 int main() { char browser[MAXIMUM_LENGTH] = {'\0'}; snprintf(browser, MAXIMUM_LENGTH, "Firefox"); if (!strcmp(browser, "Firefox")) { printf("Mozilla Firefox.\n"); } return 0; }
// gcc 10.2.c -o p10.2 #include <stdio.h> #include <string.h> #define MAXIMUM_LENGTH 256 int main() { char my_browser[MAXIMUM_LENGTH] = {'\0'}; snprintf(my_browser, MAXIMUM_LENGTH, "Your Browser"); if (!strcmp(my_browser, "Firefox")) { printf("You use a browser from Mozilla.\n"); } else { printf("You use another browser.\n"); } return 0; }
// gcc 10.3.c -o p10.3 #include <stdio.h> #include <ctype.h> #include <string.h> #define MAXIMUM_LENGTH 256 int main() { char i_use[MAXIMUM_LENGTH] = {'\0'}; snprintf(i_use, MAXIMUM_LENGTH, "X"); int index = 0; while ((index < MAXIMUM_LENGTH) && i_use[index] != '\0') { i_use[index] = tolower(i_use[index]); ++index; } if (!strcmp(i_use, "firefox")) { printf("You use a browser from Mozilla.\n"); } else if ((!strcmp(i_use, "chrome")) || (!strcmp(i_use, "chromium"))) { printf("You use a browser from Google.\n"); } else if (!strcmp(i_use, "edge")) { printf("You use a browser from Microsoft.\n"); } else if (!strcmp(i_use, "safari")) { printf("You use a browser from Apple.\n"); } else if (!strcmp(i_use, "internet explorer")) { printf("You should use a more modern browser...\n"); } else { printf("You use another browser.\n"); } return 0; }
Loops (documentation: for, while, e do...while):
// gcc 11.1.c -o p11.1 #include <stdio.h> int main() { int i; for (i = 0; i < 5; i = i + 1) { printf("%d\n", i); } return 0; }
// gcc 11.2.c -o p11.2 #include <stdio.h> int main() { int j = 0; while (j < 5) { printf("%d\n", j); ++j; // The same as j = j + 1 and similar to j++ (there are slightly differences) } return 0; }
// gcc 11.3.c -o p11.3 #include <stdio.h> int main() { int k = 0; do { printf("%d\n", k); k++; } while (k < 5); return 0; }
Functions (documentation):
// gcc 12.c -o p12 #include <stdio.h> int my_function(int x, int y) { int result = x + y; return result; } int main() { // A function is a block of code that performs arbitrary processing as defined // by the programmer. // After the definition, you can execute the function whenever wanted, using // a function call. int z = my_function(12, -34); // This is an example of a function call. printf("%d\n", z); printf("%d\n", my_function(1, 2)); // This is another example. return 0; }
Data types (documentation):
// gcc 13.c -o p13 #include <stdio.h> #define MAXIMUM_LENGTH 256 int main() { int integer_number = 1; int another_integer_number = -1; float real_number = 1.23; int logic_value = 1; // or 0; 0 is false, any other value is true char string_for_text[MAXIMUM_LENGTH] = {'\0'}; // \0 marks the end of a string snprintf(string_for_text, MAXIMUM_LENGTH, "Text here. Line breaks use\nthat is, this will be at\n the third line.\n"); return 0; }
Input (documentation: fgets(), strcspn() e sscanf()):
// gcc 14.c -o p14 #include <stdio.h> #include <string.h> #define MAXIMUM_LENGTH 256 int main() { // Once there is a request for a value, type one then press `enter`. printf("What is your name? "); char your_name[MAXIMUM_LENGTH] = {'\0'}; fgets(your_name, MAXIMUM_LENGTH, stdin); your_name[strcspn(your_name, "\r\n")] = '\0'; printf("How old are you? "); char your_age_text[MAXIMUM_LENGTH] = {'\0'}; fgets(your_age_text, MAXIMUM_LENGTH, stdin); int your_age; sscanf(your_age_text, "%d", &your_age); printf("%s\n", your_name); printf("%d\n", your_age); printf("Hello, %s!\n", your_name); printf("You are %d years old.\n", your_age); return 0; }
Congratulations! You Are Already Able to Write Any Program in C
Well... Probably not. To write any programs in the language without greater limitations, perhaps it would be necessary to know pointers as well. Furthemore, C is a language that requires knowing how the hardware works to minimize the risk of errors. Even then, errors will happen.
However, the title of the section is technically correct.
Don't you believe it? You can find the explanation in the introduction to JavaScript
In short, it is not enough to learn the syntax of a language to solve problems using it. It is much more important learning programming logic and developing computational thinking skills than learning the syntax of a programming language. In fact, when you are in doubt about the syntax, you just have to consult the documentation. You do not have to memorize it.
After you learn a first programming language, it is relatively simple to learn other languages (that adopt similar programming paradigms to the first one). To verify this statement, you can open a new window in your browser and place it side by side with this one. Then, you can compare the source code blocks written in C (in this window) and in Python (in the second window).
If you wish to perform comparisons with other programming languages, the following options are available:
Next Steps
Once the development environment is configured, you can continue your system development journey.
To avoid repetitions, I recommend reading the page about configuring the JavaScript environment. Even if you are not interested at the language, many discussions are relevant to any programming language. Besides, you will understand a way to create Internet pages and will be able to create content for your browser.
Until GDScript (for Godot Engine), the topics describe develoment environment configurations for a few programming languages. After GDScript, the focus becomes basic concepts for learning programming.