C is the most commonly used programming language for writing operating systems. The first operating system written in C is Unix. Later operating systems like GNU/Linux were all written in C. Not only is C the language of operating systems, it is the precursor and inspiration for almost all of the most popular high-level languages available today. In fact, Perl, PHP, Python and Ruby are all written in C.
By way of analogy, let’s say that you were going to be learning Spanish, Italian, French, or Romanian. Do you think knowing Latin would be helpful? Just as Latin was the basis of all of those languages, knowing C will enable you to understand and appreciate an entire family of programming languages built upon the traditions of C. Knowledge of C enables freedom.
Why C and not assembly language?[edit]
The biggest reason to learn C over assembly language is because it’s much easier and faster to write code in C than in assembly language for a given programming task. With C, you will write far fewer lines of code, complete the job much quicker, and with far less mental effort than if you wrote it in assembly language. And with today’s modern compilers, executable files compiled from C source code will typically run faster than one written “by hand” using assembly language. Only in rare edge cases, and only if you really know what you are doing, can assembly language offer important speed advantages over C code compiled with a decent compiler.
And with C, you do not have to sacrifice a lot of low level control over how your code is executed. A typical C statement translates into just a few assembly instructions. But C also provides you with a large software library to help you execute low-level tasks that you’d rather not be bothered programming.
Another huge advantage of C is portability. Different processors have different instruction sets. Having to rewrite and maintain assembly language code for each computer architecture you wish to execute your code on is an onerous task. And so one of the main strengths of C is that it combines universality and portability across various computer architectures while still giving you the same kind of low level hardware control you get with assembly language. This means you can write your C source code once and easily compile it into binaries for use on a wide variety of machines.
For example, C programs can be compiled and run on the HP 50g calculator (ARM processor), the TI-89 calculator (68000 processor), Palm OS Cobalt smartphones (ARM processor), the original iMac (PowerPC), the Arduino (Atmel AVR), and the Intel iMac (Intel Core 2 Duo). Each of these devices has its own assembly language that is completely incompatible with the assembly language of any other. C makes it possible to run your code on these machines with much less effort.
So is it any wonder that C is such a popular language?
Like toppling dominoes, the next generation of programs follows the trend of its ancestors. Operating systems designed in C always have system libraries designed in C. Those system libraries are in turn used to create higher-level libraries (like OpenGL, or GTK), and the designers of those libraries often decide to use the language the system libraries used. Application developers use the higher-level libraries to design word processors, games, media players and the like. Many of them will choose to program in the language that the higher-level library uses. And the pattern continues on and on and on…
That said, learning assembly language can be fun and worthwhile because it can give you a deep understanding of how your computer works at very low levels. And learning assembly language will definitely help you become a more skilled C programmer. So, by all means, we encourage you learn assembly language, but when it comes time to do real work, you’ll definitely want to get it done with C.
Why C, and not another language?[edit]
The primary design of C is to produce portable code while maintaining performance and minimizing footprint (CPU time, memory usage, disk I/O, etc.). This is useful for operating systems, embedded systems or other programs where performance matters a lot (“high-level” interface would affect performance). With C it’s relatively easy to keep a mental picture of what a given line really does, because most of the things are written explicitly in the code. C has a big codebase for low level applications. It is the “native” language of UNIX, which makes it flexible and portable. It is a stable and mature language which is unlikely to disappear for a long time and has been ported to most, if not all, platforms.
One powerful reason is memory allocation. Unlike most programming languages, C allows the programmer to write directly to memory. Key constructs in C such as structs, pointers and arrays are designed to structure and manipulate memory in an efficient, machine-independent fashion. In particular, C gives control over the memory layout of data structures. Moreover dynamic memory allocation is under the control of the programmer (which also means that memory deallocation has to be done by the programmer). Languages like Java and Perl shield the programmer from having to manage most details of memory allocation and pointers (except for memory leaks and some other forms of excess memory usage). This can be useful since dealing with memory allocation when building a high-level program is a highly error-prone process. However, when dealing with low-level code such as the part of the OS that controls a device, C provides a uniform, clean interface. These capabilities just do not exist in most other languages.
While Perl, PHP, Python and Ruby may be powerful and support many features not provided by default in C, they are not normally implemented in their own language. Rather, most such languages initially relied on being written in C (or another high-performance programming language), and would require their implementation be ported to a new platform before they can be used.
As with all programming languages, whether you want to choose C over another high-level language is a matter of opinion and both technical and business requirements could dictate which language is required.
The field of computing as we know it today started in 1947 with three scientists at Bell Telephone Laboratories—William Shockley, Walter Brattain, and John Bardeen—and their groundbreaking invention: the transistor. In 1956, the first fully transistor-based computer, the TX-0, was completed at MIT. The first integrated circuit was created in 1958 by Jack Kilby at Texas Instruments, but the first high-level programming language existed even before then.
“The Fortran project” was originally developed in 1954 by IBM. A shortening of “The IBM Mathematical Formula Translating System“, the project had the purpose of creating and fostering development of a procedural, imperative programming language that was especially suited to numeric computation and scientific computing. It was a breakthrough in terms of productivity and programming ease (compared to assembly language) and speed (Fortran programs ran nearly as fast as, and in some cases, just as fast as, programs written in assembly). Furthermore, Fortran was written at a high-enough level (and thus was machine independent enough) to become the first widely adopted programming language. The Algorithmic Language (Algol 58) was derived from Fortran in 1958 and evolved into Algol 60 in 1960. The Combined Programming Language (CPL) was then created out of Algol 60 in 1963. In 1967, it evolved into Basic CPL, which was itself, the base for B in 1969. Finally, B, the root of C, was created in 1971.
C was the direct successor of B, a stripped down version of BCPL, created by Ken Thompson at Bell Labs, that was also a compiled language – User’s Reference to B, used in early internal versions of the UNIX operating system. As noted in Ritchie’s C History : “The B compiler on the PDP-7 did not generate machine instructions, but instead ‘threaded code’, an interpretive scheme in which the compiler’s output consists of a sequence of addresses of code fragments that perform the elementary operations. The operations typically — in particular for B — act on a simple stack machine”. Thompson and Dennis Ritchie, also working at Bell Labs, improved B and called the result NB. Further extensions to NB created its logical successor, C. Most of UNIX was rewritten in NB, and then C, which resulted in a more portable operating system.
The portability of UNIX was the main reason for the initial popularity of both UNIX and C. Rather than creating a new operating system for each new machine, system programmers could simply write the few system-dependent parts required for the machine, and then write a C compiler for the new system. Since most of the system utilities were thus written in C, it simply made sense to also write new utilities in C.
The American National Standards Institute began work on standardizing the C language in 1983, and completed the standard in 1989. The standard, ANSI X3.159-1989 “Programming Language C”, served as the basis for all implementations of C compilers. The standards were later updated in 1990 and 1999, allowing for features that were either in common use, or were appearing in C++.
Getting Started[edit]
This book introduces and teaches the basics of the C programming language and touches upon some advanced topics as well. This section outlines the required skills and tools you’ll need to get the most out of this book.
Skills and Prior Experience You’ll Need[edit]
This book is for beginning programmers, so don’t worry if you have no formal computer training or prior programming experience. It’s assumed you know how to turn your computer on, start and stop applications, and perform other basic operations like installing software. It’s also assumed you have some experience interacting with your operating system through a terminal window using its command line interface. If you aren’t sure what this means, consider seeking out a tutorial for your chosen platform that can get you comfortable with getting around your computer’s command line. At a minimum, you should know the basic commands for navigating to different directories and performing simple file management operations. This book will spell out any other commands you’ll need to run from the command line to get your C code working on your machine.
Software You’ll Need[edit]
No one ever became a musician just by reading sheet music. Musicians have to constantly play and practice on their instruments to get good. Similarly, the only way to become a programmer is to write and execute lots of code. To do that, you will need two different pieces of software: a compiler and a text editor. Both can be had for no cost.
Compilers[edit]
A compiler is a sophisticated piece of software for converting the C source code you write with your text editor into the machine code[1] that you can execute on your computer. Below is a list of some popular C compilers. Note that some of the compilers listed below come as part of an integrated development environment (IDE). However, if you are brand new to programming, it’s best if you can install and run the compiler from the command line instead of through an IDE. This book uses the GNU C Compiler (GCC) in its examples so we recommend installing this compiler for use with this book. The next section in this chapter will explain how to download and install the GCC software to your machine.
Popular C compilers/IDEs include:
Name | Website | Platform | License | Details |
---|---|---|---|---|
Microsoft Visual Studio Community | Visual Studio | Windows | Proprietary, free of charge | Powerful and student-friendly version of an industry standard compiler. |
Xcode | Xcode | macOS, OSX | Proprietary, free of charge | Available free of charge at Mac App Store. |
Tiny C Compiler (TCC) | tinycc | GNU/Linux, Windows | LGPL | Small, fast and simple compiler. |
Clang | clang | GNU/Linux, Windows, Unix, OS X | University of Illinois/NCSA License | A free, permissively licensed front-end using a LLVM backend. |
GNU C Compiler | gcc | GNU/Linux, MinGW or mingw-w64 (Windows), Unix, OS X. | GPL | The De facto standard. Ships with most Unix systems. |
Text Editors and IDEs[edit]
Aside from a compiler, the only other software requirement is a text editor for writing and saving your C code. Note that a text editor is different from a word processor, a piece of software with many features for creating visually appealing documents. Unlike word processors, text editors are primarily designed to create plain text files. On Windows, the Notepad text editor can be used but it does not offer any advanced capabilities such as syntax highlighting and code completion. There are hundreds of text editors (see List of Text Editors). Among the most popular are Notepad++ for Windows as well as Atom, Sublime Text, gedit, Vim and Emacs which are also available on other operating systems (“cross-platform”). These text editors come with syntax highlighting and line numbers, which makes code easier to read at a glance, and to spot syntax errors. Many text editors have features for increasing your coding speed, such as keystroke macros and code snippets, that you can take advantage of as you gain skill as a programmer.
You may also be considering the use of an integrated Development Environment (IDE) to help you write code. An IDE is a suite of integrated tools and features in one convenient package, usually with a graphical user interface. These programs include a text editor and file browser and are also sometimes bundled with an easily accessible compiler. They also typically include a debugger, a tool that will enable you to do such things as step through the program you develop manually one source code line at a time, or alter data as an aid to finding and correcting programming errors.
However, many IDEs do not offer a command line interface to the compiler and/or offer only graphical buttons or a menu for executing programs. So for new programmers, an IDE is not ideal. Instead, a simple text editor will suffice along with the ability to issue simple commands on the command line to help you gain a hands-on familiarity and understanding of core development tools. Of course, an IDE may still be useful to you if you have experience with one. But as a general guideline: Do not use an IDE unless you know what the IDE is doing for you!
Other popular compilers/IDEs include:
On GNU/Linux, GCC is almost always included by default.
On Microsoft Windows, Dev-C++ is recommended for beginners because it is easy to use, free, and simple to install. Although the initial developer (Bloodshed) hasn’t updated it since 2005, a new version appeared in 2011, made by an independent programmer, and is being actively developed.[2] An alternate option for those working only in the Windows environment is the proprietary Microsoft Visual Studio Community which is free of charge and has an excellent debugger.
On Mac OS X, the Xcode IDE provides the compilers needed to compile various source files. The newer versions do not include the command line tools. They need to be downloaded via Xcode->Preferences->Downloads.
- ↑ Actually, GCC’s (GNU C Compiler) cc (C Compiler) translates the input .c file to the target CPU’s assembly, output is written to an .s file. Then as (assembler) generates a machine code file from the .s file. Pre-processing is done by another sub-program cpp (C PreProcessor), which is not to be confused with c++ (a compiler for another programming language).
- ↑ http://orwelldevcpp.blogspot.com/
Dev-C++[edit]
Dev C++ is an Integrated Development Environment(IDE) for the C++ programming language, available from Bloodshed Software. An updated version is available at Orwell Dev-C++.
C++ is a programming language which contains within itself most of the C language, plus extensions. Most C++ compilers will compile C programs, sometimes with a few adjustments (like invoking them with a different name or command line switch). Therefore, you can use Dev C++ for C development.
However, Dev C++ is not the compiler. It is designed to use the MinGW or Cygwin versions of GCC – both of which can be obtained as part of the Dev C++ package, although they are completely different projects.
Dev C++ simply provides an editor, syntax highlighting, some facilities for the visualisation of code (like class and package browsing) and a graphical interface to the chosen compiler. Because Dev C++ analyses the error messages produced by the compiler and attempts to distinguish the line numbers from the errors themselves, the use of other compiler software is discouraged since the format of their error messages is likely to be different.
The latest version of Dev-C++ is a beta for version 5. However, it still has a significant number of bugs. All the features are there, and it is quite usable. It is considered one of the best free software C IDEs available for Windows.
A version of Dev C++ for Linux is in the pipeline. It is not quite usable yet, however. Linux users already have a wealth of IDEs available. (e.g. KDevelop and Anjuta.) Most of the graphical text editors, and other common editors such as emacs and vim, support syntax highlighting.
- Steps for Obtaining Dev-C++ if You’re on Windows
- Go to https://sourceforge.net/projects/orwelldevcpp/ and pick the download option.
- The setup is pretty straight forward. Make sure the compiler option is ticked.
- You can now use the environment provided by the software to write and run your code.
- OPTIONALLY: “C:Program Files (x86)Dev-CppMinGW64bin” can be added to the global PATH variable of the operating system to compile with gcc from a command prompt.
GCC[edit]
The GNU Compiler Collection (GCC) is a free/libre set of compilers developed by the Free Software Foundation and can be installed on a wide variety of operating systems. GCC commands are used throughout this book to demonstrate how to compile C code so you are encouraged to take the time to install GCC on your machine.
- Steps for Obtaining the GCC Compiler if You’re on GNU/Linux
On GNU/Linux, Installing the GNU C Compiler can vary in method from distribution to distribution. (Type in cc -v to see if it is installed already.)
- For Ubuntu, install the GCC compiler (along with other necessary tools) by using
sudo apt install build-essential
, or by using Synaptic. You do not need Universe enabled. - For Debian, install the GCC compiler (as root) by using
apt install gcc
. - For Fedora Core, install the GCC compiler (as root) by using
yum install gcc
. - For Redhat, get a GCC RPM, e.g. using Rpmfind and then install (as root) using
rpm -ivh gcc-version-release.arch.rpm
- For Mandrake, install the GCC compiler (as root) by using
urpmi gcc
- For Slackware, the package is available on their website – simply download, and type
installpkg gcc-xxxxx.tgz
- For Gentoo, you should already have GCC installed as it will have been used when you first installed. To update it run (as root)
emerge -uav gcc
. - For Arch Linux, install the GCC compiler (as root) by using
pacman -S gcc
. - For Void Linux, install the GCC compiler as root by using
xbps-install -S gcc
. - If you cannot become root, get the GCC tarball from ftp://ftp.gnu.org/ and follow the instructions in it to compile and install in your home directory. Be warned though, you need a C compiler to do that – yes, GCC itself is written in C.
- You can use a commercial C compiler/IDE.
- macOS
The simplest method for obtaining a compiler is to install Apple’s proprietary IDE, Xcode, available for free.
Xcode comes bundled with a gcc-compatible compiler called clang which replaced GCC as Xcode’s default C compiler a number of years ago. But because Xcode aliases the gcc
command to the clang compiler, GCC installation isn’t necessary to compile the example code in this book.
If you prefer using the GCC compiler, the third-party package manager, Homebrew, provides an easy installation process. You’ll first need to install Homebrew, and then issue the brew install
command to install the desired GCC Homebrew formulae. You may want to find a recent tutorial that will step you through this process as other commands may be necessary to get GCC set up flawlessly on your system, especially if you already have Xcode installed.
For hardcore computer enthusiasts, GCC can be compiled directly from the source code. We highly recommend searching out and following an up-to-date tutorial for installing GCC from source files.
- Steps for Obtaining the GCC Compiler if You’re on BSD Family Systems
- Steps for Obtaining the GCC Compiler if You’re on Windows
There are two ways to use GCC on Windows: Cygwin and MinGW. Applications compiled with Cygwin will not run on any computer without Cygwin, so MinGW is recommended. MinGW is simpler to install, and takes less disk space.
To get MinGW, do this:
- Go to http://sourceforge.net/projects/mingw/ download and save this to your hard drive.
- Once the download is finished, open it and follow the instructions. You can also choose to install additional compilers, or the tool Make, but these aren’t necessary.
- Now you need to set your PATH. Right-click on “My computer” and click “Properties”. Go to the “Advanced” tab and click on “Environment variables”. Go to the “System variables” section and scroll down until you see “Path”. Click on it, then click “edit”. Add “;C:MinGWbin” (without the quotes) to the end.
- To test if GCC works, open a command prompt and type “gcc”. You should get the message “gcc: fatal error: no input files compilation terminated.”. If you get this message, GCC is installed correctly.
To get Cygwin, do this:
- Go to http://www.cygwin.com and click on the “Install Cygwin Now” button in the upper right corner of the page.
- Click “run” in the window that pops up, and click “next” several times, accepting all the default settings.
- Choose any of the Download sites (“ftp.easynet.be”, etc.) when that window comes up; press “next” and the Cygwin installer should start downloading.
- When the “Select Packages” window appears, scroll down to the heading “Devel” and click on the “+” by it. In the list of packages that now displays, scroll down and find the “gcc-core” package; this is the compiler. Click once on the word “Skip”, and it should change to some number like “3.4” etc. (the version number), and an “X” will appear next to “gcc-core” and several other related packages that will now be downloaded.
- Click “next” and the compiler as well as the Cygwin tools should start downloading; this could take a while. While you’re waiting for the installation to finish, download any text-editor designed for programming. While Cygwin does include some, you may prefer doing a web search to find other alternatives. While using a stock text editor is possible, it is not ideal.
- Once the Cygwin downloads are finished and you have clicked “next”, etc. to finish the installation, double-click the Cygwin icon on your desktop to begin the Cygwin “command prompt”. Your home directory will automatically be set up in the Cygwin folder, which now should be at “C:cygwin” (the Cygwin folder is in some ways like a small unix/linux computer on your Windows machine — not technically of course, but it may be helpful to think of it that way).
- Type “gcc” at the Cygwin prompt and press “enter”; if “gcc: no input files” or something like it appears you have succeeded and now have the gcc compiler on your computer (and congratulations — you have also just received your first error message!).
Third option is to use WSL:
- Go to http://aka.ms/wsldocs and follow the steps to install WSL
- Go to https://aka.ms/vscode and follow the steps to install VSCode
- Follow the guide and choose Get Started with C++ and WSL
- As a result you will need to install possibly Ubuntu and set-up accordingly installing GCC like the Linux guide above.
The current stable (usable) version of GCC is 4.9.1 published on 2014-07-16, which supports several platforms. In fact, GCC is not only a C compiler, but a family of compilers for several languages, such as C++, Ada, Java, and Fortran.
Embedded systems[edit]
- Most CPUs are microcontrollers in embedded systems, often programmed in C, but most of the compilers mentioned above (except GCC) do not support such CPUs. For specialized compilers that do support embedded systems, see Embedded Systems/C Programming.
Other C compilers[edit]
We have a long list of C compilers in a much later section of this Wikibook.
Which of those compilers would be suitable for beginning C programmers, that we should say a few words about getting started with that particular compiler in this section of this Wikibook?
The “Hello, World!” Program[edit]
Tradition dictates that we begin with a program that displays a “Hello, World!” greeting to the screen, followed by a new line, and then exits. Below is the C source code that does just that. Type this code into your preferred text editor/IDE and save it to a file named hello.c.
#include
int main(void)
{
printf("Hello, World!n");
return 0;
}
Source code analysis[edit]
Although this is a very simple program, a lot of hidden meaning is packed into the many symbols you see in the code. Though your compiler understands it, you can only guess at what the code, sprinkled with some familiar English words, might do. One of your first jobs as a new programmer will be to learn the many “words” and symbols of the C programming language, the language your compiler understands. Once you learn the meaning underlying the code, you will be able to “talk to” the compiler and give it your own orders and build any kind of program you are inventive and resourceful enough to create.
But note that knowing the meanings of arcane symbols is not all there is to programming. You can’t master another language by reading a translation dictionary. To become fluent in another language, you have to practice conversing in that language. Learning a programming language is no different. You have to practice “talking” to the compiler with the source code you write. So be sure to type in the code example above and feel free to experiment and alter it with your curiosity as your guide.
OK, so let’s dive in and look at the first line in our program:
Before understanding what this line does, you have to know that your machine already comes pre-installed with some C software code. The code is there to save you from the drudgery of writing code that performs basic, common tasks. This reusable code is referred to as a library. And so our first line in our example program signals to the compiler that we’d like to “check out” some code from the library and make use of it in our program. Here, we are borrowing code that will help us print text to the screen.
The way we tell the C compiler to include library code into our own code is by using what’s called a preprocessor directive. One of the very first tasks your compiler will perform is to search through your source code for preprocessor directives which modify your source code in some way. In our case, the #include
preprocessor directive tells the compiler to copy source code from a library and insert it directly into the code where the preprocessor directive is found. Since our directive is at the very top of the file, the library code will be inserted at the top of the source file. (Note that this all happens in the computer’s memory, so the original file on your disk never actually gets altered.)
But which library code should the compiler insert? The next bit in the line, the
, tells the compiler to copy and paste the C code from the stdio.h file into your code. The angle brackets surrounding the file name tell the compiler to look for the file in the standard library as opposed, to say, your own personal library of reusable code. Note that files with the .h extension are called header files. The stdio.h header file contains many functions related to input and output that are defined according to the C standard. Though this header file gives us access to many different functions, the only library function we are interested in from stdio.h is the printf
function.
OK, but what, exactly, is a function? Let’s take a look at the next line in our code so we can begin to get an idea:
Here we create a function named main
that is the starting point for all C programs. All C programs require a function called “main” or they will not compile. Our function name is surrounded by two mysterious symbols, int and (void). The “int” bit tells the compiler what kind of value our function will return while the “(void)” bit tells our compiler what kind of values we will “pass” into our function. We’ll skip over what exactly this means for now as these values will be covered in more detail later in the book. The most important thing to understand right now is that together, these symbols declare our function to the compiler and tell it that it exists.
So what is a function? In computer science, the term “function” is used a bit more loosely than in mathematics, since functions often express imperative ideas (as in the case of C) – that is, how-to process, instead of declarations. For now, suffice it to say, functions define a set of computer statements that work together to carry out a specific task. In C, the statements associated with a function are placed between a set curly braces, { }
, which mark the beginning and end of the statements. Together, the curly braces and the statements are called a block. Let’s take a look at the first line in our function’s block:
printf("Hello World!n");
This line of code is the heart of our program, the one that outputs our greeting to the user’s console (also known as the terminal in the context of Unix-like operating systems), the text-based interface installed on your computer. This statement is a function call and has two main parts: the name of the library function used to print our greeting, printf, followed by the data that we will pass to the function, seen here between the pair of parentheses. The data we are passing to the function is the string, “Hello World!n”. The “n” part at the end of the string is a special kind of character called an escape sequence. The “n” escape sequence generates the new line at the end of our text. Strings and escape sequences will be covered in more detail later. We terminate the function call statement with a semicolon so the compiler knows that it should begin looking for a new statement which it finds on the next line:
Here, we say that our main
function returns an integer value using the return
keyword. The integer value we are returning is “0”. But what does this mean, exactly? In the specific context of the main
function, the value we return is called the exit status, which we report back to the operating system to indicate whether our code ran without error. As our programs grow in complexity, we can use other integers as codes to indicate various types of errors. This style of providing exit status is a long standing convention[1]. We will go into much more detail on return values of functions later in the book.
So that’s a lot to take in, even for such a short program. Don’t worry if you don’t understand all of it and don’t worry about memorizing it. You do not learn programming by memorizing, you learn by repetition and by doing. Memorizing all the notes to Beethoven’s 5th symphony does not make you a concert pianist, you must get on the keyboard and practice and play!
Next we will show you how to take the source code you typed in and turn it into an executable file with your compiler.
Compiling[edit]
Compiling is the process we used to describe translating the orders you gave to the compiler in your source code into the machine language that can be run by your operating system and microprocessor. In this way, your C compiler is a middle-man. You talk to the compiler in a language it understands, C source code, and the compiler translates the source into machine code to save you a lot of painstaking, tedious work writing assembly code.
If the compiler finds your source code confusing, it will throw an error along with a message to help you fix up your source code and clear up any confusion. You will then need to try to recompile the code and repeat the process until it compiles without error. Note that code that compiles without error doesn’t mean it’s free of bugs. It just means the compiler understands the instructions provided by your source code.
Unix-like[edit]
If you are using a Unix(-like) system, such as GNU/Linux, Mac OS X, or Solaris, it will probably have GCC installed, otherwise on Linux you can install it using the package manager of your distribution. Open the virtual console or a terminal emulator and enter the following (be certain your current working directory is the one containing your source code):
gcc hello.c
By default gcc will generate our executable binary with the name a.out. To run your new generated program type:
./a.out
You should see Hello, World!
printed after the last prompt.
To see the exit status of the last program you ran, type on your shell command:
echo $?
This shows the value the main
function has returned, which is 0 in the above example.
There are a lot of options you can use with the gcc compiler. For example, if you want the output to have a name other than a.out, you can use the -o option. The following shows a few examples:
-o
- indicates that the next parameter is the name of the resulting program (or library). If this option is not specified, the compiled program will, for historic reasons, end up in a file called “a.out” or “a.exe” (for cygwin users).
-Wall
- indicates that gcc should warn about many types of suspicious code that are likely to be incorrect.
You can use these options to create a program called “helloworld” instead of “a.out” by typing:
gcc -o helloworld hello.c -Wall
Now you can run it by typing:
./helloworld
All the options are well documented in the manual[2] for GCC.
On IDEs[edit]
If you are using an IDE you may have to select console project, and to compile you just select build from the menu or the toolbar. The executable will appear inside the project folder, but you should have a menu button so you can just run the executable from the IDE. The process is roughly the same on all IDEs.
References[edit]
Before learning C syntax and programming constructs, it is important to learn the meaning of a few key terms that are central in understanding C.
Block Structure, Statements, Whitespace, and Scope[edit]
Next we’ll discuss the basic structure of a C program. If you’re familiar with PASCAL, you may have heard it referred to as a block-structured language. C does not have complete block structure (and you’ll find out why when you go over functions in detail) but it is still very important to understand what blocks are and how to use them.
So what is in a block? Generally, a block consists of executable statements.
But before we delve into blocks, let’s examine statements. One way to describe statements is they are the text (and surrounding whitespace) the compiler will attempt to turn into executable instructions. A simpler definition is statements are bits of code that do things.
For example:
This declares an integer variable, which can be accessed with the identifier ‘i’, and initializes it to the value 6. The various data types are introduced in the chapter Variables.
You might have noticed the semicolon at the end of the statement. Statements in C always end with a semicolon (;). Leaving off the semicolon is a common mistake many people make, beginners and experts alike! So until it becomes second nature, be sure to double check your statements!
Since C is a “free-format” language, several statements can share a single line in the source file, like this:
/* this declares the variables 'i', 'test', 'foo', and 'bar'
note that ONLY the variable named 'bar' is set to six! */
int i, test, foo, bar = 6;
There are several kinds of statements. You’ve already seen some of them, such as the assignment (i = 6;
). A substantial portion of this book deals with statement construction.
Back to our discussion of blocks. In C, blocks begin with an opening brace "{" and end with a closing brace "}". Blocks can contain other blocks which can contain their own blocks, and so on.
Let’s look at a block example.
int main(void)
{
/* this is a 'block' */
int i = 5;
{
/* this is also a 'block', nested inside the outer block */
int i = 6;
}
return 0;
}
You can use blocks with the preceding statements, such as the main function declaration (and other statements we’ve not yet covered), but you can also use blocks by themselves.
Whitespace refers to the tab, space and newline characters that separate the text characters that make up the source code.
Like many things in life, it’s hard to appreciate whitespace until it’s gone. To a C compiler, the source code
printf("Hello world"); return 0;
is the same as
printf("Hello world"); return 0;
which is also the same as
printf (
"Hello world") ;
return 0;
The compiler simply ignores most whitespace (except, for example, when it separates return
from 0
). However, it is common practice to use spaces (or tabs) to organize source code for human readability.
Most of the time we do not want other functions or other programmer’s routines accessing data we are currently manipulating, which is why it is important to understand the concept of scope.
Scope describes the level at which a piece of data or a function is visible. There are two types of scope in C, local and global. When we speak of global scope, we’re referring to something that can be seen or manipulated from anywhere in the program. Local scope applies to a program element that can be seen or manipulated only within the block in which it was declared.
Let’s look at some examples to get a better idea of scope.
int i = 5; /* this is a 'global' variable, it can be accessed from anywhere in the program */
/* this is a function, all variables inside of it
are "local" to the function. */
int main(void)
{
int i = 6; /* 'i' now equals 6 */
printf("%dn", i); /* prints a '6' to the screen, instead of the global variable of 'i', which is 5 */
return 0;
}
That shows an example of local and global. But what about different scopes inside of functions?
(you’ll learn more about functions later, for now, just focus on the “main” part.)
/* the main function */
int main(void)
{
/* this is the beginning of a 'block', you read about those above */
int i = 6; /* this is the first variable of this 'block', 'i' */
{
/* this is a new 'block', and because it's a different block, it has its own scope */
/* this is also a variable called 'i', but in a different 'block',
because it's in a different 'block' than the first variable named 'i', it doesn't affect the first one! */
int i = 5;
printf("%dn", i); /* prints a '5' onto the screen */
}
/* now we're back into the first block */
printf("%dn", i); /* prints a '6' onto the screen */
return 0;
}
Basics of Using Functions[edit]
Functions are a big part of programming. A function is a special kind of block that performs a well-defined task. If a function is well-designed, it can enable a programmer to perform a task without knowing anything about how the function works. The act of requesting a function to perform its task is called a function call. Many functions require a function call to hand it certain pieces of data needed to perform its task; these are called arguments. Many functions also return a value to the function call when they’re finished; this is called a return value (the return value in the above program is 0).
The things you need to know before calling a function are:
- What the function does
- The data type (discussed later) of the arguments and what they mean
- The data type of the return value and what it means
Many functions use the return value for the result of a computation. Some functions use the return value to indicate whether they successfully completed their work. As you have seen in the intro exercise, the main
function uses the return value to provide an exit status to the operating system.
All code other than global data definitions and declarations needs to be a part of a function.
Usually, you’re free to call a function whenever you wish to. The only restriction is that every executable program needs to have one, and only one, main function, which is where the program begins executing.
We will discuss functions in more detail in a later chapter, C Programming/Procedures and functions.
The Standard Library[edit]
In 1983, when C was in the process of becoming standardized, the American National Standards Institute (ANSI) formed a committee to establish a standard specification of C known as “ANSI C”. That standard specification created a basic set of functions common to each implementation of C, which is referred to as the Standard Library. The Standard Library provides functions for tasks such as input/output, string manipulation, mathematics, files, and memory allocation. The Standard Library does not provide functions that are dependent on specific hardware or operating systems, like graphics, sound, or networking. In the “Hello, World” program, a Standard Library function is used (printf
) which outputs lines of text to the standard output stream.
Having covered the basic concepts of C programming, we can now briefly discuss the process of compilation.
Like any programming language, C by itself is completely incomprehensible to a microprocessor. Its purpose is to provide an intuitive way for humans to provide instructions that can be easily converted into machine code that is comprehensible to a microprocessor. The compiler is what translates our human-readable source code into machine code.
To those new to programming, this seems fairly simple. A naive compiler might read in every source file, translate everything into machine code, and write out an executable. That could work, but has two serious problems. First, for a large project, the computer may not have enough memory to read all of the source code at once. Second, if you make a change to a single source file, you would have to recompile the entire application.
To deal with these problems, compilers break the job into steps. For each source file (each .c
file), the compiler reads the file, reads the files it references via the #include
directive, and translates them to machine code. The result of this is an “object file” (.o
). After all the object files are created, a “linker” program collects all of the object files and writes the actual executable program. That way, if you change one source file, only that file needs to be recompiled, after which, the application will need to be re-linked.
Without going into details, it can be beneficial to have a superficial understanding of the compilation process.
Preprocessor[edit]
The preprocessor provides the ability for the inclusion of so called header files, macro expansions, conditional compilation and line control. These features can be accessed by inserting the appropriate preprocessor directives into your code. Before compiling the source code, a special program, called the preprocessor, scans the source code for tokens, or special strings, and replaces them with other strings or code according to specific rules. The C preprocessor is not technically part of the C language and is instead a tool offered by your compiler’s software.
All preprocessor directives begin with the hash character (#). You can see one preprocessor directive in the Hello world program. Example:
This directive causes the stdio header to be included into your program. Other directives such as #pragma
control compiler settings and macros. The result of the preprocessing stage is a text string. You can think of the preprocessor as a non-interactive text editor that modifies your code to prepare it for compilation. The language of preprocessor directives is agnostic to the grammar of C, so the C preprocessor can also be used independently to process other kinds of text files.
Syntax Checking[edit]
This step ensures that the code is valid and will sequence into an executable program. Under most compilers, you may get messages or warnings indicating potential issues with your program (such as a conditional statement always being true or false, etc.)
When an error is detected in the program, the compiler will normally report the file name and line that is preventing compilation.
Object Code[edit]
The compiler produces a machine code equivalent of the source code that can be linked into the final program. At this point the code itself can’t be executed, as it requires linking to do so.
It’s important to note after discussing the basics that compilation is a “one way street”. That is, compiling a C source file into machine code is easy, but “decompiling” (turning machine code into the C source that creates it) is not. Decompilers for C do exist, but the code they create is hard to understand and only useful for reverse engineering.
Linking[edit]
Linking combines the separate object files into one complete program by integrating libraries and the code and producing either an executable program or a library. Linking is performed by a linker program, which is often part of a compiler suite.
Common errors during this stage are either missing or duplicate functions.
Automation[edit]
For large C projects, many programmers choose to automate compilation, both in order to reduce user interaction requirements and to speed up the process by recompiling only modified files.
Most Integrated Development Environments (IDE’s) have some kind of project management which makes such automation very easy. However, the project management files are often usable only by users of the same integrated development environment, so anyone desiring to modify the project would need to use the same IDE.
On UNIX-like systems, make and Makefiles are often used to accomplish the same. Make is traditional and flexible and is available as one of the standard developer tools on most Unix and GNU distributions.
Makefiles have been extended by the GNU Autotools, composed of Automake and Autoconf for making software compilable, testable, translatable and configurable on many types of machines. Automake and Autoconf are described in detail in their respective manuals.
The Autotools are often perceived to be complicated and various simpler build systems have been developed. Many components of the GNOME project now use the declarative Meson build system which is less flexible, but instead focuses on providing the features most commonly needed from a build system in a simple way. Other popular build systems for programs written in the C language include CMake and Waf.
Once gcc is installed, it can be called with a list of c source files
that have been written but not yet compiled. e.g. if the file main.c
includes functions described in myfun.h and implemented in myfun_a.c
and myfun_b.c, then it is enough to write
gcc main.c myfun_a.c myfun_b.c
myfun.h is included in main.c, but if it is in a separate header file
directory, then that directory can be listed after a “-I ” switch.
In larger programs, Makefiles and gnu make program can compile
c files into intermediate files ending with suffix .o which can be linked
by gcc.
How to compile each object file is usually described in the Makefile
with the object file as a label ending with a colon followed by two spaces
(tabs often cause problems) followed by a list of other files that are
dependencies, e.g. .c files and .o files compiled in another section,
and on the next line, the invocation of gcc that is required.
Typing man make
or info make
often gives the information
needed to on how to use make, as well as gcc.
Although gcc has a lot of option switches, one often used is
-g to generate debugging information for gdb to allow
gdb to show source code during a step-through of the machine
code program. gdb has an ‘h’ command that shows what it can do,
and is usually started with ‘gdb a.out’ if a.out is the anonymous
executable machine code file that was compiled by gcc.
C Structure and Style[edit]
This is a basic introduction to good coding style in the C Programming Language. It is designed to provide information on how to effectively use indentation, comments, and other elements that will make your C code more readable. It is not a tutorial on actual C programming.
As a beginning programmer, the point of creating structure in the program code might not be clear, as the compiler doesn’t care about the difference. However, as programs become complex, chances are that writing the program has become a joint effort. (Or others might want to see how it was accomplished. Or you may have to read it again years later.) Well-written code also helps you get an overview of what the code does.
In the following sections, we will attempt to explain good programming practices that will in turn make your programs clearer.
Introduction[edit]
In C, programs are composed of statements. Statements are terminated with a semi-colon, and are collected in sections known as functions. By convention, a statement should be kept on its own line, as shown in the example below:
#include
int main(void) {
printf("Hello, World!n");
return 0;
}
The following block of code is essentially the same. While it contains exactly the same code, and will compile and execute with the same result, the removal of spacing causes an essential difference: it’s harder to read.
#include
int main(void) {printf("Hello, World!n");return 0;}
The simple use of indents and line breaks can greatly improve code readability without impacting code performance. Readable code makes it much easier to see where functions and procedures end and which lines are part of which loops and procedures.
This lesson is going to focus on improving the coding style of an example piece of code which applies a formula and prints the result. Later, you’ll see how to write code for such tasks in more detail. For now, focus on how the code looks, not what it does.
Line Breaks and Indentation[edit]
The addition of white space inside your code is arguably the most important part of good code structure. Effective use of white space can create a visual scale of how your code flows, which can be very important when returning to your code when you want to maintain it.
Line Breaks[edit]
With minimal line breaks, code is barely human-readable, and may be hard to debug or understand:
1#include
2int main(void) { int revenue = 80; int cost = 50; int roi; roi = (100 * (revenue - cost)) / cost; if (roi >= 0) { printf ("%dn", roi); } return 0; }
Rather than putting everything on one line, it is much more readable to break up long lines so that each statement and declaration goes on its own line. After inserting line breaks, the code will look like this:
1#include
2int main(void) {
3int revenue = 80;
4int cost = 50;
5int roi;
6roi = (100 * (revenue - cost)) / cost;
7if (roi >= 0) {
8printf ("%dn", roi);
9}
10return 0;
11}
Blank Lines[edit]
Blank lines should be used to offset the main components of your code. Always use them
- After preprocessor directives.
- After new variables are declared.
- Use your own judgment for finding other places where components should be separated.
Based on these two rules, there should now be at least two line breaks added.
- After line 1, because line 1 has a preprocessor directive.
- After line 5, because line 5 contains a variable declaration.
This will make the code much more readable than it was before:
The following lines of code have line breaks between functions, but without indentation.
1#include
2
3int main(void) {
4
5int revenue = 80;
6int cost = 50;
7
8int roi;
9
10roi = (100 * (revenue - cost)) / cost;
11
12if (roi >= 0) {
13printf ("%dn", roi);
14}
15
16return 0;
17}
But it’s still not as readable as it can be.
Indentation[edit]
Many text editors automatically indent appropriately when you hit the enter/return key.
Although adding simple line breaks between key blocks of code can make code easier to read, it provides no information about the block structure of the program. Using the tab key can be very helpful. Indentation visually separates paths of execution by moving their starting points to a new column. This simple practice will make it much easier to read and understand code. Indentation follows a fairly simple rule:
- All code inside a new block should be indented by one tab[1] more than the code in the previous path.
Based on the code from the previous section, there are two blocks requiring indentation:
1#include
2
3int main(void) {
4
5 int revenue = 80;
6 int cost = 50;
7
8 int roi;
9
10 roi = (100 * (revenue - cost)) / cost;
11
12 if (roi >= 0) {
13 printf ("%dn", roi);
14 }
15
16 return 0;
17}
It is now fairly obvious as to which parts of the program fit inside which blocks. You can tell which parts of the program the coder has intended to be conditional, and which ones he or she has not. Although it might not be immediately noticeable, once many nested paths get added to the structure of the program, the use of indentation can be very important. Thus, indentation makes the structure of your program clear.
It is claimed that research has shown that an indentation size between 2 to 4 characters is easier to read than 8 character indents[2]. However, an indent of 8 characters may still be in use for some systems[3].
Comments in code can be useful for a variety of purposes. They provide the easiest way to set off specific parts of code (and their purpose); as well as providing a visual “split” between various parts of your code. Having good comments throughout your code will make it much easier to remember what specific parts of your code do.
Comments in modern flavors of C (and many other languages) can come in two forms:
1//Single Line Comments (added by C99 standard, famously known as c++ style of comments)
and
1/*Multi-Line
2Comments
3(only form of comments supported by C89 standard)*/
Note that Single line comments are a more recent addition to C, so some compilers may not support them. A recent version of GCC will have no problems supporting them.
This section is going to focus on the various uses of each form of commentary.
[edit]
Single-line comments are most useful for simple ‘side’ notes that explain what certain parts of the code do. The best places to put these comments are next to variable declarations, and next to pieces of code that may need explanation. Comments should make clear the intention and ideas behind the corresponding code. What is immediately obvious from reading the code does not belong in a comment.
Based on our previous program, there are various good places to place comments
- Line 5 and/or 6, to explain what ‘int revenue’ and ‘int cost’ represent,
- Line 8, to explain what the variable ‘roi’ is going to be used for,
- Line 10, to explain the idea of the calculation,
- Line 12, to explain the purpose of the ‘if’.
This will make our program look something like
#include
int main(void) {
int revenue = 80; // as of 2016
int cost = 50;
int roi; // return on investment in percent
roi = (100 * (revenue - cost)) / cost; // formula from accounting book
if (roi >= 0) { // we don't care about negative roi
printf ("%dn", roi);
}
return 0;
}
[edit]
Single-line comments are a new feature, so many C programmers only use multi-line comments.
Multi-line comments are most useful for long explanations of code. They can be used as copyright/licensing notices, and they can also be used to explain the purpose of a block of code. This can be useful for two reasons: They make your functions easier to understand, and they make it easier to spot errors in code. If you know what a block is supposed to do, then it is much easier to find the piece of code that is responsible if an error occurs.
As an example, suppose we had a program that was designed to print “Hello, World! ” a certain number of lines, a specified number of times. There would be many for loops in this program. For this example, we shall call the number of lines i, and the number of strings per line as j.
A good example of a multi-line comment that describes ‘for’ loop i’s purpose would be:
/* For Loop (int i)
Loops the following procedure i times (for number of lines). Performs 'for' loop j on each loop,
and prints a new line at end of each loop.
*/
This provides a good explanation of what i’s purpose is, whilst not going into detail of what j does. By going into detail over what the specific path does (and not ones inside it), it will be easier to troubleshoot the path.
Similarly, you should always include a multi-line comment before each function, to explain the role, preconditions and postconditions of each function. Always leave the technical details to the individual blocks inside your program – this makes it easier to troubleshoot.
A function descriptor should look something like:
/* Function : int hworld (int i,int j)
Input : int i (Number of lines), int j (Number of instances per line)
Output : 0 (on success)
Procedure: Prints "Hello, World!" j times, and a new line to standard output over i lines.
*/
This system allows for an at-a-glance explanation of what the function should do. You can then go into detail over how each aspect of the program is achieved later on in the program.
Finally, if you like to have aesthetically-pleasing source code, the multi-line comment system allows for the easy addition of comment boxes. These make the comments stand out much more than they would otherwise. They look like this.
/***************************************
* This is a multi line comment
* That is nearly surrounded by a
* Cool, starry border!
***************************************/
Applied to our original program, we can now include a much more descriptive and readable source code:
#include
int main(void){
/************************************************************************************
* Function: int main(void)
* Input : none
* Output : Returns 0 on success
* Procedure: Prints 2016's return on investment in percent if it is not negative.
************************************************************************************/
int revenue = 80; // as of 2016
int cost = 50;
int roi; // return on investment in percent
roi = (100 * (revenue - cost)) / cost; // formula from accounting book
if (roi >= 0) { // we don't care about negative roi
printf ("%dn", roi);
}
return 0;
}
This will allow any outside users of the program an easy way to comprehend what the code functions are and how they operate. It also inhibits uncertainty with other like-named functions.
A few programmers add a column of stars on the right side of a block comment:
/***************************************
* This is a multi line comment *
* that is completely surrounded by a *
* cool, starry border! *
***************************************/
But most programmers don’t put any stars on the right side of a block comment.
They feel that aligning the right side is a waste of time.
Comments written in source files can be used for documenting source code automatically by using popular tools like Doxygen.[4][5]
References[edit]
Like most programming languages, C uses and processes variables. In C, variables are human-readable names for the computer’s memory addresses used by a running program. Variables make it easier to store, read and change the data within the computer’s memory by allowing you to associate easy-to-remember labels for the memory addresses that store your program’s data. The memory addresses associated with variables aren’t determined until after the program is compiled and running on the computer.
At first, it’s easiest to imagine variables as placeholders for values, much like in mathematics. You can think of a variable as being equivalent to its assigned value. So, if you have a variable i that is initialized (set equal) to 4, then it follows that i + 1 will equal 5. However, a skilled C programmer is more mindful of the invisible layer of abstraction going on just under the hood: that a variable is a stand-in for the memory address where the data can be found, not the data itself. You will gain more clarity on this point when you learn about pointers.
Since C is a relatively low-level programming language, before a C program can utilize memory to store a variable it must claim the memory needed to store the values for a variable. This is done by declaring variables. Declaring variables is the way in which a C program shows the number of variables it needs, what they are going to be named, and how much memory they will need.
Within the C programming language, when managing and working with variables, it is important to know the type of variables and the size of these types. A type’s size is the amount of computer memory required to store one value of this type. Since C is a fairly low-level programming language, the size of types can be specific to the hardware and compiler used – that is, how the language is made to work on one type of machine can be different from how it is made to work on another.
All variables in C are typed. That is, every variable declared must be assigned as a certain type of variable.
Declaring, Initializing, and Assigning Variables[edit]
Here is an example of declaring an integer, which we’ve called some_number. (Note the semicolon at the end of the line; that is how your compiler separates one program statement from another.)
This statement tells the compiler to create a variable called some_number
and associate it with a memory location on the computer. We also tell the compiler the type of data that will be stored at that address, in this case an integer. Note that in C we must specify the type of data that a variable will store. This lets the compiler know how much total memory to set aside for the data (on most modern machines an int
is 4 bytes in length). We’ll look at other data types in the next section.
Multiple variables can be declared with one statement, like this:
int anumber, anothernumber, yetanothernumber;
In early versions of C, variables had to be declared at the beginning of a block. In C99 it is allowed to mix declarations and statements arbitrarily – but doing so is not usual, because it is rarely necessary, some compilers still don’t support C99 (portability), and it may, because it is uncommon yet, irritate fellow programmers (maintainability).
After declaring variables, you can assign a value to a variable later on using a statement like this:
The assignment of a value to a variable is called initialization. The above statement directs the compiler to insert an integer representation of the number “3” into the memory address associated with some_number
.
We can save a bit of typing by declaring and assigning data to a memory address at the same time:
You can also assign variables to the value of other variable, like so:
some_number = some_new_number;
Or assign multiple variables the same value with one statement:
anumber = anothernumber = yetanothernumber = 8;
This is because the assignment x = y returns the value of the assignment, y. For example, some_number = 4 returns 4. That said, x = y = z is really a shorthand for x = (y = z).
Naming Variables[edit]
Variable names in C are made up of letters (upper and lower case) and digits. The underscore character (“_”) is also permitted. Names must not begin with a digit. Unlike some languages (such as Perl and some BASIC dialects), C does not use any special prefix characters on variable names.
Some examples of valid (but not very descriptive) C variable names:
foo
Bar
BAZ
foo_bar
_foo42
_
QuUx
Some examples of invalid C variable names:
2foo (must not begin with a digit)
my foo (spaces not allowed in names)
$foo ($ not allowed -- only letters, and _)
while (language keywords cannot be used as names)
As the last example suggests, certain words are reserved as keywords in the language, and these cannot be used as variable names.
It is not allowed to use the same name for multiple variables in the same scope. When working with other developers, you should therefore take steps to avoid using the same name for global variables or function names. Some large projects adhere to naming guidelines[1] to avoid duplicate names and for consistency.
In addition there are certain sets of names that, while not language keywords, are reserved for one reason or another. For example, a C compiler might use certain names “behind the scenes”, and this might cause problems for a program that attempts to use them. Also, some names are reserved for possible future use in the C standard library. The rules for determining exactly what names are reserved (and in what contexts they are reserved) are too complicated to describe here[citation needed], and as a beginner you don’t need to worry about them much anyway. For now, just avoid using names that begin with an underscore character.
The naming rules for C variables also apply to naming other language constructs such as function names, struct tags, and macros, all of which will be covered later.
Literals[edit]
Anytime within a program in which you specify a value explicitly instead of referring to a variable or some other form of data, that value is referred to as a literal. In the initialization example above, 3 is a literal. Literals can either take a form defined by their type (more on that soon), or one can use hexadecimal (hex) notation to directly insert data into a variable regardless of its type.[citation needed] Hex numbers are always preceded with 0x. For now, though, you probably shouldn’t be too concerned with hex.
The Four Basic Data Types[edit]
In Standard C there are four basic data types. They are int
, char
, float
, and double
.
The int
type[edit]
The int type stores integers in the form of “whole numbers”. An integer is typically the size of one machine word, which on most modern home PCs is 32 bits (4 octets). Examples of literals are whole numbers (integers) such as 1, 2, 3, 10, 100… When int is 32 bits (4 octets), it can store any whole number (integer) between -2147483648 and 2147483647. A 32 bit word (number) has the possibility of representing any one number out of 4294967296 possibilities (2 to the power of 32).
If you want to declare a new int variable, use the int keyword. For example:
int numberOfStudents, i, j=5;
In this declaration we declare 3 variables, numberOfStudents, i and j, j here is assigned the literal 5.
The char
type[edit]
The char
type is capable of holding any member of the execution character set. It stores the same kind of data as an int
(i.e. integers), but typically has a size of one byte. The size of a byte is specified by the macro CHAR_BIT
which specifies the number of bits in a char (byte). In standard C it never can be less than 8 bits. A variable of type char
is most often used to store character data, hence its name. Most implementations use the ASCII character set as the execution character set, but it’s best not to know or care about that unless the actual values are important.
Examples of character literals are ‘a’, ‘b’, ‘1’, etc., as well as some special characters such as ‘