The C Programming Language Handbook
The C Programming Language Handbook
org
Table of Contents
Preface
Introduction to C
Variables and types
Constants
Operators
Conditionals
Loops
Arrays
Strings
Pointers
Functions
Input and output
Variables scope
Static variables
Global variables
Type definitions
Enumerated Types
Structures
Command line parameters
Header files
The preprocessor
Conclusion
1
Preface
The C Handbook follows the 80/20 rule: learn in 20%
of the time the 80% of a topic.
Enjoy!
2
www.dbooks.org
Introduction to C
C is probably the most widely known programming
language. It is used as the reference language for
computer science courses all over the world, and it's
probably the language that people learn the most in
school among with Python and Java.
3
I said compiler: C is a compiled programming
language, like Go, Java, Swift or Rust. Other popular
programming language like Python, Ruby or
JavaScript are interpreted. The difference is
consistent: a compiled language generates a binary
file that can be directly executed and distributed.
hello.c
#include <stdio.h>
int main(void) {
printf("Hello, World!");
}
4
www.dbooks.org
C is a very small language at its core, and anything
that's not part of the core is provided by libraries.
Some of those libraries are built by normal
programmers, and made available for others to use.
Some other libraries are built into the compiler. Like
stdio and others.
function.
5
int printf(const char *format, ...);
#include <stdio.h>
int main(void) {
printf("Hello, World!");
}
6
www.dbooks.org
That's good. It means the C compiler is there, and we
can start using it.
7
Confirm by pressing the y key, then press enter to
confirm the file name:
8
www.dbooks.org
Now type
./hello
to run it:
Awesome!
9
Now if you call ls -al hello , you can see that the
program is only 12KB in size:
10
www.dbooks.org
Variables and types
C is a statically typed language.
int age;
11
In this case:
#include <stdio.h>
int main(void) {
int age = 0;
age = 37.2;
printf("%u", age);
}
Integer numbers
C provides us the following types to define integer
values:
char
int
short
long
12
www.dbooks.org
int takes at least 2 bytes. short takes at least 2
bytes. long takes at least 4 bytes.
Unsigned integers
13
For all the above data types, we can prepend
unsigned to start the range at 0, instead of a negative
number. This might make sense in many cases.
#include <stdio.h>
int main(void) {
unsigned char j = 255;
j = j + 10;
printf("%u", j); /* 9 */
}
14
www.dbooks.org
If you have a signed value, the behavior is undefined.
It will basically give you a huge number which can
vary, like in this case:
#include <stdio.h>
int main(void) {
char j = 127;
j = j + 10;
printf("%u", j); /* 4294967177 */
}
#include <stdio.h>
int main(void) {
char j = 1000;
}
15
hello.c:4:11: warning: implicit conversion
from 'int' to
'char' changes value from 1000 to -24
[-Wconstant-conversion]
char j = 1000;
~ ^~~~
1 warning generated.
#include <stdio.h>
int main(void) {
char j;
j = 1000;
}
#include <stdio.h>
int main(void) {
char j = 0;
j += 1000;
}
16
www.dbooks.org
You might see floating point numbers written as
1.29e-3
-2.3e+5
float
double
long double
17
On your specific computer, how can you determine the
specific size of the types? You can write a program to
do that:
#include <stdio.h>
int main(void) {
printf("char size: %lu bytes\n", sizeof(char));
printf("int size: %lu bytes\n", sizeof(int));
printf("short size: %lu bytes\n", sizeof(short));
printf("long size: %lu bytes\n", sizeof(long));
printf("float size: %lu bytes\n", sizeof(float));
printf("double size: %lu bytes\n",
sizeof(double));
printf("long double size: %lu bytes\n",
sizeof(long double));
}
18
www.dbooks.org
Constants
Let's now talk about constants.
Like this:
It's just a convention, but one that can greatly help you
while reading or writing a C program as it improves
readability. Uppercase name means constant,
lowercase name means variable.
#define AGE 37
19
In this case, you don't need to add a type, and you
don't also need the = equal sign, and you omit the
semicolon at the end.
20
www.dbooks.org
Operators
C offers us a wide variety of operators that we can use
to operate on data.
arithmetic operators
comparison operators
logical operators
compound assignment operators
bitwise operators
pointer operators
structure operators
miscellaneous operators
Arithmetic operators
In this macro group I am going to separate binary
operators and unary operators.
21
Operator Name Example
= Assignment a = b
+ Addition a + b
- Subtraction a - b
* Multiplication a * b
/ Division a / b
% Modulo a % b
For example:
int a = 2;
int b;
b = a++ /* b is 2, a is 3 */
b = ++a /* b is 4, a is 4 */
Comparison operators
22
www.dbooks.org
Operator Name Example
== Equal operator a == b
Logical operators
! NOT (example: !a )
Compound assignment
operators
Those operators are useful to perform an assignment
and at the same time perform an arithmetic operation:
23
Operator Name Example
+= Addition assignment a += b
Multiplication
*= a *= b
assignment
/= Division assignment a /= b
Miscellaneous operators
The ternary operator
The ternary operator is the only operator in C that
works with 3 operands, and it’s a short way to express
conditionals.
Example:
a ? b : c
24
www.dbooks.org
sizeof
The sizeof operator returns the size of the operand
you pass. You can pass a variable, or even a type.
Example usage:
#include <stdio.h>
int main(void) {
int age = 37;
printf("%ld\n", sizeof(age));
printf("%ld", sizeof(int));
}
Operator precedence
With all those operators (and more, which I haven't
covered in this post, including bitwise, structure
operators and pointer operators), we must pay
attention when using them together in a single
expression.
int a = 2;
int b = 4;
int c = b + a * a / b - a;
25
the = assignment operator
the + and - binary operators
the * and / operators
the + and - unary operators
In:
int c = b + a * a / b - a;
int c = b + ((a * a) / b) - a;
26
www.dbooks.org
Conditionals
Any programming language provides the
programmers the ability to perform choices.
if
int a = 1;
if (a == 1) {
/* do something */
}
27
int a = 1;
if (a == 2) {
/* do something */
} else {
/* do something else */
}
int a = 0;
if (a = 0) {
/* never invoked */
}
28
www.dbooks.org
int a = 1;
if (a == 2) {
/* do something */
} else if (a == 1) {
/* do something else */
} else {
/* do something else again */
}
switch
int a = 1;
switch (a) {
case 0:
/* do something */
break;
case 1:
/* do something else */
break;
case 2:
/* do something else */
break;
}
29
some creative ways.
int a = 1;
switch (a) {
case 0:
/* do something */
break;
case 1:
/* do something else */
break;
case 2:
/* do something else */
break;
default:
/* handle all the other cases */
break;
}
30
www.dbooks.org
Loops
C offers us three ways to perform a loop: for loops,
while loops and do while loops. They all allow you
to iterate over arrays, but with a few differences. Let's
see them in details.
For loops
The first, and probably most common, way to perform
a loop is for loops.
Like this:
31
The variable is initialized at the 0 value, and the first
iteration is done. Then it is incremented as the
increment part says ( i++ in this case, incrementing
by 1), and all the cycle repeats until you get to the
number 10.
While loops
While loops is simpler to write than a for loop,
because it requires a bit more work on your part.
32
www.dbooks.org
Instead of defining all the loop data up front when you
start the loop, like you do in the for loop, using
while you just check for a condition:
int i = 0;
i++;
}
Do while loops
While loops are great, but there might be times when
you need to do one particular thing: you want to
always execute a block, and then maybe repeat it.
33
This is done using the do while keyword, in a way
that's very similar to a while loop, but slightly
different:
int i = 0;
do {
/* do something */
i++;
} while (i < 10);
Then, until i is less than 10, we'll repeat the block.
34
www.dbooks.org
Having this option to break out of a loop is particularly
interesting for while loops (and do while too),
because we can create seemingly infinite loops that
end when a condition occurs, and you define this
inside the loop block:
int i = 0;
while (1) {
/* do something */
i++;
if (i == 10) break;
}
35
Arrays
An array is a variable that stores multiple values.
int prices[5];
int prices[5] = { 1, 2, 3, 4, 5 };
36
www.dbooks.org
int prices[5];
prices[0] = 1;
prices[1] = 2;
prices[2] = 3;
prices[3] = 4;
prices[4] = 5;
int prices[5];
37
used like a normal pointer.
38
www.dbooks.org
Strings
In C, strings are one special kind of array: a string is
an array of char values:
char name[7];
printf("%s", name);
39
This is important to keep in mind especially when
manipulating strings.
#include <string.h>
40
www.dbooks.org
Pointers
Pointers are one of the most confusing/challenging
parts of C, in my opinion. Especially if you are new to
programming, but also if you come from a higher level
programming language like Python or JavaScript.
41
We can use the pointer operator * to get the value of
the variable an address is pointing to:
int age;
int *address = &age;
*address = 37;
printf("%u", *address);
int prices[3] = { 5, 4, 3 };
42
www.dbooks.org
printf("%u", *prices); /* 5 */
43
Functions
Functions are the way we can structure our code into
subroutines that we can:
1. give a name to
2. call when we need them
#include <stdio.h>
int main(void) {
printf("Hello, World!");
}
44
www.dbooks.org
The function body is the set of instructions that are
executed any time we invoke a function.
void doSomething(void) {
/* ... */
}
doSomething();
45
doSomething(3);
doSomething(3, 4);
46
www.dbooks.org
➜ ~ gcc hello.c -o hello; ./hello
hello.c:13:3: warning: implicit declaration of
function 'doSomething' is invalid in C99
[-Wimplicit-function-declaration]
doSomething(3, 4);
^
hello.c:17:6: error: conflicting types for
'doSomething'
void doSomething(int value1, char value2) {
^
hello.c:13:3: note: previous implicit declaration
is here
doSomething(3, 4);
^
1 warning and 1 error generated.
47
➜ ~ gcc hello.c -o hello; ./hello
hello.c:14:3: warning: implicit declaration of
function 'doSomething' is invalid in C99
[-Wimplicit-function-declaration]
doSomething(3, 4);
^
1 warning generated.
48
www.dbooks.org
Input and output
C is a small language, and the "core" of C does not
include any Input/Output (I/O) functionality.
#include <stdio.h>
printf()
scanf()
sscanf()
fgets()
fprintf()
49
With I/O functions we always work with streams. A
stream is a high level interface that can represent a
device or a file. From the C standpoint, we don't have
any difference in reading from a file or reading from
the command line: it's an I/O stream in any case.
printf()
printf("hey!");
50
www.dbooks.org
int age = 37;
scanf()
51
We must first define a variable that will hold the value
we get from the input:
int age;
scanf("%d", &age);
char name[20];
scanf("%s", name);
#include <stdio.h>
int main(void) {
char name[20];
printf("Enter your name: ");
scanf("%s", name);
printf("you entered %s", name);
}
52
www.dbooks.org
Variables scope
When you define a variable in a C program,
depending on where you declare it, it will have a
different scope.
global variables
local variables
int main(void) {
int age = 37;
}
int main(void) {
/* ... */
}
53
Global variables are accessible from any function of
the program, and they are available for the whole
execution of the program, until it ends.
54
www.dbooks.org
Static variables
Inside a function, you can initialize a static variable
using the static keyword.
int incrementAge() {
int age = 0;
age++;
return age;
}
int incrementAge() {
static int age = 0;
age++;
return age;
}
55
Now every time we call this function, we'll get an
incremented value:
printf("%d\n", incrementAge());
printf("%d\n", incrementAge());
printf("%d\n", incrementAge());
will give us
1
2
3
int incrementAge() {
static int ages[3];
ages[0]++;
return ages[0];
}
56
www.dbooks.org
Global variables
In this section I want to mention the difference
between global and local variables.
Like this:
#include <stdio.h>
int main(void) {
char j = 0;
j += 10;
printf("%u", j); //10
}
function.
#include <stdio.h>
char i = 0;
int main(void) {
i += 10;
printf("%u", i); //10
}
57
Due to this, global variables are one way we have of
sharing the same data between functions.
58
www.dbooks.org
Type definitions
The typedef keyword in C allows you to defined new
types.
variables:
NUMBER one = 1;
Now you might ask: why? Why not just use the built-in
type int instead?
59
Enumerated Types
Using the typedef and enum keywords we can
define a type that can have either one value or
another.
keyword.
typedef enum {
//...values
} TYPENAME;
typedef enum {
true,
false
} BOOLEAN;
60
www.dbooks.org
typedef enum {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
} WEEKDAY;
#include <stdio.h>
typedef enum {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
} WEEKDAY;
int main(void) {
WEEKDAY day = monday;
if (day == monday) {
printf("It's monday!");
} else {
printf("It's not monday");
}
}
61
This means the conditional could have been if (day
62
www.dbooks.org
Structures
Using the struct keyword we can create complex
data structures using basic C types.
struct <structname> {
//...variables
};
Example:
struct person {
int age;
char *name;
};
struct person {
int age;
char *name;
} flavio;
63
struct person {
int age;
char *name;
} flavio, people[20];
struct person {
int age;
char *name;
};
struct person {
int age;
char *name;
};
struct person {
int age;
char *name;
};
64
www.dbooks.org
We can also change the values using the dot syntax:
struct person {
int age;
char *name;
};
flavio.age = 38;
typedef struct {
int age;
char *name;
} PERSON;
PERSON flavio;
65
and we can initialize them at declaration in this way:
66
www.dbooks.org
Command line
parameters
In your C programs, you might have the need to
accept parameters from the command line when the
command launches.
int main(void)
to
67
If this was our program, we'd have argc being 4 and
argv being an array containing
gcc
hello.c
-o
hello
#include <stdio.h>
./hello
./hello
a
b
c
68
www.dbooks.org
Header files
Simple programs can be put in a single file, but when
your program grows larger, it's impossible to keep it all
in just one file.
You already used header files when you first used the
printf() function, or other I/O function, and you had
to type:
#include <stdio.h>
to use it.
#include "myfile.h"
69
#include "myfolder/myfile.h"
#include <stdio.h>
int main(void) {
printf("%u", calculateAge(1983));
}
70
www.dbooks.org
calculateAge() function available:
#include <stdio.h>
#include "calculate_age.h"
int main(void) {
printf("%u", calculateAge(1983));
}
71
The preprocessor
The preprocessor is a tool that helps us a lot when
programming with C. It is part of the C Standard, just
like the language, the compiler and the standard
library.
Conditionals
One of the things we can do is to use conditionals to
change how our program will be compiled, depending
on the value of an expression.
72
www.dbooks.org
For example we can check if the DEBUG constant is 0:
#include <stdio.h>
int main(void) {
#if DEBUG == 0
printf("I am NOT debugging\n");
#else
printf("I am debugging\n");
#endif
}
Symbolic constants
We can define a symbolic constant:
#define VALUE 1
#define PI 3.14
#define NAME "Flavio"
Macros
73
With #define we can also define a macro. The
difference between a macro and a symbolic constant
is that a macro can accept an argument and typically
contains code, while a symbolic constant is a value:
If defined
We can check if a symbolic constant or a macro is
defined using #ifdef :
#include <stdio.h>
#define VALUE 1
int main(void) {
#ifdef VALUE
printf("Value is defined\n");
#else
printf("Value is not defined\n");
#endif
}
74
www.dbooks.org
We also have #ifndef to check for the opposite
(macro not defined).
#if 0
#endif
#define DEBUG 0
#if DEBUG
//code only sent to the compiler
//if DEBUG is not 0
#endif
Predefined symbolic
constants you can use
The preprocessor also defines a number of symbolic
constants you can use, identified by the 2 underscores
before and after the name, including:
75
__DATE__ translates to the compilation date, in
the Mmm gg aaaa format
__TIME__ translates to the compilation time, in
the hh:mm:ss format
76
www.dbooks.org
Conclusion
Thanks a lot for reading this book.
77