0% found this document useful (0 votes)
3 views

C Programming

The document is a comprehensive tutorial on C programming, covering fundamental concepts such as data types, operators, control structures, functions, and memory management. It emphasizes the importance of C as a foundational language in computer science and its similarities to other programming languages. The tutorial includes practical examples and explanations to help beginners learn to write C programs effectively.

Uploaded by

Lê Hồng Minh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

C Programming

The document is a comprehensive tutorial on C programming, covering fundamental concepts such as data types, operators, control structures, functions, and memory management. It emphasizes the importance of C as a foundational language in computer science and its similarities to other programming languages. The tutorial includes practical examples and explanations to help beginners learn to write C programs effectively.

Uploaded by

Lê Hồng Minh
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 92

C Programming

https://www.w3schools.com/c/c_intro.php

Table of Contents
Introduction................................................................................................................................5
Why Learn C?............................................................................................................................5
Difference between C and C++..................................................................................................5
Get Started.................................................................................................................................5
Basic Data Types.......................................................................................................................6
Basic Format Specifiers.............................................................................................................6
The char Type............................................................................................................................7
ASCII......................................................................................................................................7
Notes on Characters..............................................................................................................8
Numeric Types...........................................................................................................................8
C Decimal Precision...............................................................................................................8
C The sizeof Operator................................................................................................................9
C Data Types Examples.......................................................................................................10
C Type Conversion..................................................................................................................10
Implicit Conversion...............................................................................................................10
Explicit Conversion...............................................................................................................11
itoa and atoi..........................................................................................................................11
C Constants.............................................................................................................................12
Notes On Constants.............................................................................................................12
C Operators..............................................................................................................................13
Arithmetic Operators................................................................................................................13
Assignment Operators.............................................................................................................14
Comparison Operators.............................................................................................................14
Logical Operators.....................................................................................................................15
C Booleans...............................................................................................................................15
Boolean Variables................................................................................................................16
Comparing Values and Variables.........................................................................................16
Conditions and If Statements...................................................................................................17
The if Statement.......................................................................................................................17
The else Statement..................................................................................................................18
C Else If....................................................................................................................................18
C Short Hand If Else................................................................................................................19
C Switch...................................................................................................................................19
The break Keyword..................................................................................................................20
The default Keyword................................................................................................................20
Loops.......................................................................................................................................21
While Loop...............................................................................................................................21
C Do/While Loop......................................................................................................................21
C For Loop...............................................................................................................................22
C Nested Loops.......................................................................................................................22
C Break and Continue..............................................................................................................23
C Arrays...................................................................................................................................23
Arrays...................................................................................................................................24
Len........................................................................................................................................24
Sort.......................................................................................................................................25
Loop Through an Array............................................................................................................26
Set Array Size..........................................................................................................................27
C Array Size.............................................................................................................................27
Making Better Loops................................................................................................................27
C Multidimensional Arrays.......................................................................................................28
Change Elements in a 2D Array..............................................................................................29
Loop Through a 2D Array........................................................................................................29
Magic Squares......................................................................................................................29
Odd Magic Square (OMS)....................................................................................................30
Even Magic Square (EMS)...................................................................................................33
C Strings..................................................................................................................................34
Access Strings.........................................................................................................................34
Modify Strings.......................................................................................................................34
Loop Through a String..........................................................................................................34
Another Way Of Creating Strings.........................................................................................35
Differences...........................................................................................................................35
C Special Characters...............................................................................................................36
C String Functions...................................................................................................................36
String Length........................................................................................................................37
Concatenate Strings.............................................................................................................37
Copy Strings.........................................................................................................................37
Compare Strings..................................................................................................................38
Complete String Reference..................................................................................................38
User Input.............................................................................................................................38
Multiple Inputs......................................................................................................................39
Take String Input..................................................................................................................39
C Memory Address..................................................................................................................40
C Pointers.............................................................................................................................40
Dereference..........................................................................................................................41
C Pointers and Arrays..............................................................................................................42
Pointers & Arrays.................................................................................................................42
How Are Pointers Related to Arrays.....................................................................................43
C Functions..............................................................................................................................45
Predefined Functions...........................................................................................................45
Create a Function.................................................................................................................45
Call a Function......................................................................................................................45
Calculate the Sum of Numbers............................................................................................47
C Function Parameters............................................................................................................47
Parameters and Arguments.................................................................................................47
Multiple Parameters.............................................................................................................48
Notes on Parameters...........................................................................................................48
Sum of numbers...................................................................................................................49
Qudratic Equation.................................................................................................................49
ADVERTISEMENT...................................................................................................................50
Pass Arrays as Function Parameters...................................................................................50
Return Values.......................................................................................................................51
C Variable Scope.....................................................................................................................53
Local Scope..........................................................................................................................53
Global Scope........................................................................................................................54
Naming Variables.................................................................................................................54
Conclusion............................................................................................................................55
Function Declaration and Definition.....................................................................................55
What About Parameters.......................................................................................................56
C Recursion.............................................................................................................................57
Hanoi Tower.........................................................................................................................58
Len(x)...................................................................................................................................58
Gcd(a,b)................................................................................................................................59
Fib(n)....................................................................................................................................59
Fac(n)...................................................................................................................................60
Attention...............................................................................................................................60
C Math Functions.....................................................................................................................60
Math Functions.........................................................................................................................60
C Files......................................................................................................................................61
File Handling............................................................................................................................62
Create a File.............................................................................................................................62
C Write To Files.......................................................................................................................63
Write To a File......................................................................................................................63
Append Content To a File....................................................................................................64
C Read Files.........................................................................................................................64
Structures.................................................................................................................................66
Create a Structure................................................................................................................66
Access Structure Members..................................................................................................66
What About Strings in Structures?.......................................................................................67
Simpler Syntax.....................................................................................................................68
Copy Structures....................................................................................................................68
Modify Values.......................................................................................................................68
New Quadratic Equation......................................................................................................69
C Enumeration (enum).............................................................................................................71
C Enums...............................................................................................................................71
Change Values.....................................................................................................................72
Memory in C.............................................................................................................................73
Memory Management..............................................................................................................73
C Allocate Memory...................................................................................................................74
Static Memory..........................................................................................................................74
Dynamic Memory.....................................................................................................................74
Stack Memory..........................................................................................................................75
Access Dynamic Memory........................................................................................................75
A note about data types.......................................................................................................76
C Reallocate Memory..............................................................................................................76
NULL Pointer & Error Checking...........................................................................................77
C Deallocate Memory..............................................................................................................77
Deallocate (free) Memory.....................................................................................................77
Free Memory........................................................................................................................77
Memory Leaks......................................................................................................................78
Summary..............................................................................................................................79
C Memory Management Example........................................................................................79
Final Program.......................................................................................................................82
IList.......................................................................................................................................83
C Keywords..............................................................................................................................84
C stdio (stdio.h) Library............................................................................................................86
C stdlib (stdlib.h) Library..........................................................................................................87
C string (string.h) Library.........................................................................................................88
C math (math.h) Library...........................................................................................................89
C ctype Functions....................................................................................................................92

Introduction
C is a general-purpose programming language created by Dennis Ritchie at the Bell
Laboratories in 1972.
It is a very popular language, despite being old. The main reason for its popularity is because it
is a fundamental language in the field of computer science.
C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Why Learn C?
 It is one of the most popular programming languages in the world
 If you know C, you will have no problem learning other popular programming languages
such as Java, Python, C++, C#, etc, as the syntax is similar
 C is very fast, compared to other programming languages, like Java and Python
 C is very versatile; it can be used in both applications and technologies

Difference between C and C++


 C++ was developed as an extension of C, and both languages have almost the same
syntax
 The main difference between C and C++ is that C++ support classes and objects, while
C does not

Get Started
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
This tutorial will teach you the basics of C.
When you are finished with this tutorial, you will be able to write C programs and create real-life
examples.
It is not necessary to have any prior programming experience.
Basic Data Types
The data type specifies the size and type of information the variable will store.
In this tutorial, we will focus on the most basic ones:
Data Size Description Example
Type

int 2 or 4 Stores whole numbers, without decimals 1


bytes

float 4 bytes Stores fractional numbers, containing one or 1.99


more decimals. Sufficient for storing 6-7
decimal digits

double 8 bytes Stores fractional numbers, containing one or 1.99


more decimals. Sufficient for storing 15 decimal
digits

char 1 byte Stores a single character/letter/number, or 'A'


ASCII values

Basic Format Specifiers


There are different format specifiers for each data type. Here are some of them:
Format Data Type Try it
Specifier

%d or %i int Try it »

%f or %F float Try it »

%lf double Try it »

%c char Try it »

%s Used for strings (text), which you will learn more Try it »
about in a later chapter
Note: It is important that you use the correct format specifier for the specified data type, or the
program may produce errors or even crash.
Lật số nguyên Rev(x)
#include <stdio.h>
/* lay phai ghep phai
chuyen chu so don vi cua x sang y */
int Rev(int x) {
int y = 0;
// lay dau
int sign = (x < 0) ? -1 : 1;
if (x < 0) {
x = abs(x);
}
while(x) {
y = y*10 + (x % 10);
x /= 10;
}
return sign*y;
}

int main() {

printf("\n %d", Rev(-2000));


return 0;
}

The char Type


The char data type is used to store a single character.
The character must be surrounded by single quotes, like 'A' or 'c', and we use the %c format
specifier to print it:
Example
char myGrade = 'A';
printf("%c", myGrade);
Alternatively, if you are familiar with ASCII, you can use ASCII values to display certain
characters. Note that these values are not surrounded by quotes (''), as they are numbers:
Example
char a = 65, b = 66, c = 67;
printf("%c", a);
printf("%c", b);
printf("%c", c);
Tip: A list of all ASCII values can be found in our ASCII Table Reference.

ASCII

#include <stdio.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void ASCII() {
int i;
for (i = 0; i < 128; i++) {
printf("\n %c %d", i, i); Go();
}
}

int main() {
ASCII();
return 0;
}

Notes on Characters
If you try to store more than a single character, it will only print the last character:
Example
char myText = 'Hello';
printf("%c", myText);
Note: Don't use the char type for storing multiple characters, as it may produce errors.
To store multiple characters (or whole words), use strings (which you will learn more about in a
later chapter):
Example
char myText[] = "Hello";
printf("%s", myText);

Numeric Types
Use int when you need to store a whole number without decimals, like 35 or 1000,
and float or double when you need a floating point number (with decimals), like 9.99 or 3.14515.
int
int myNum = 1000;
printf("%d", myNum);
float
float myNum = 5.75;
printf("%f", myNum);
double
double myNum = 19.99;
printf("%lf", myNum);
float vs. double
The precision of a floating point value indicates how many digits the value can have after the
decimal point. The precision of float is six or seven decimal digits, while double variables have a
precision of about 15 digits. Therefore, it is often safer to use double for most calculations - but
note that it takes up twice as much memory as float (8 bytes vs. 4 bytes).
Scientific Numbers
A floating point number can also be a scientific number with an "e" to indicate the power of 10:
Example
float f1 = 35e3;
double d1 = 12E4;

printf("%f\n", f1);
printf("%lf", d1);

C Decimal Precision

Set Decimal Precision


You have probably already noticed that if you print a floating point number, the output will show
many digits after the decimal point:
Example
float myFloatNum = 3.5;
double myDoubleNum = 19.99;
printf("%f\n", myFloatNum); // Outputs 3.500000
printf("%lf", myDoubleNum); // Outputs 19.990000
If you want to remove the extra zeros (set decimal precision), you can use a dot (.) followed by a
number that specifies how many digits that should be shown after the decimal point:
Example
float myFloatNum = 3.5;
printf("%f\n", myFloatNum); // Default will show 6 digits after the
decimal
printf("%.1f\n", myFloatNum); // Only show 1 digit
printf("%.2f\n", myFloatNum); // Only show 2 digits
printf("%.4f", myFloatNum); // Only show 4 digits

C The sizeof Operator

Get the Memory Size


We introduced in the data types chapter that the memory size of a variable varies depending on
the type:
Data Type Size

int 2 or 4 bytes

float 4 bytes

double 8 bytes

char 1 byte
The memory size refers to how much space a type occupies in the computer's memory.
To actually get the size (in bytes) of a data type or variable, use the sizeof operator:
Example
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));
printf("%d\n", sizeof(char));
Note that we use the %lu format specifer to print the result, instead of %d. It is because the
compiler expects the sizeof operator to return a long unsigned int (%lu), instead of int (%d). On
some computers it might work with %d, but it is safer to use %lu.
Why Should I Know the Size of Data Types?
Knowing the size of different data types is important because it says something about memory
usage and performance.
For example, the size of a char type is 1 byte. Which means if you have an array of
1000 char values, it will occupy 1000 bytes (1 KB) of memory.
Using the right data type for the right purpose will save memory and improve the
performance of your program.
You will learn more about the sizeof operator later in this tutorial, and how to use it in different
scenarios.
C Data Types Examples

Real-Life Example
Here's a real-life example of using different data types, to calculate and output the total cost of a
number of items:
Example
// Create variables of different data types
int items = 50;
float cost_per_item = 9.99;
float total_cost = items * cost_per_item;
char currency = '$';
// Print variables
printf("Number of items: %d\n", items);
printf("Cost per item: %.2f %c\n", cost_per_item, currency);
printf("Total cost = %.2f %c\n", total_cost, currency);

C Type Conversion
Type Conversion
Sometimes, you have to convert the value of one data type to another type. This is known
as type conversion.
For example, if you try to divide two integers, 5 by 2, you would expect the result to be 2.5. But
since we are working with integers (and not floating-point values), the following example will just
output 2:
Example
int x = 5;
int y = 2;
int sum = 5 / 2;

printf("%d", sum); // Outputs 2

To get the right result, you need to know how type conversion works.
There are two types of conversion in C:
 Implicit Conversion (automatically)
 Explicit Conversion (manually)

Implicit Conversion
Implicit conversion is done automatically by the compiler when you assign a value of one type to
another.
For example, if you assign an int value to a float type:
Example
// Automatic conversion: int to float
float myFloat = 9;

printf("%f", myFloat); // 9.000000

As you can see, the compiler automatically converts the int value 9 to a float value of 9.000000.
This can be risky, as you might lose control over specific values in certain situations.
Especially if it was the other way around - the following example automatically converts the float
value 9.99 to an int value of 9:
Example
// Automatic conversion: float to int
int myInt = 9.99;

printf("%d", myInt); // 9

What happened to .99? We might want that data in our program! So be careful. It is important
that you know how the compiler work in these situations, to avoid unexpected results.
As another example, if you divide two integers: 5 by 2, you know that the sum is 2.5. And as you
know from the beginning of this page, if you store the sum as an integer, the result will only
display the number 2. Therefore, it would be better to store the sum as a float or a double, right?
Example
float sum = 5 / 2;

printf("%f", sum); // 2.000000

Why is the result 2.00000 and not 2.5? Well, it is because 5 and 2 are still integers in the
division. In this case, you need to manually convert the integer values to floating-point values.
(see below).

Explicit Conversion
Explicit conversion is done manually by placing the type in parentheses () in front of the value.
Considering our problem from the example above, we can now get the right result:
Example
// Manual conversion: int to float
float sum = (float) 5 / 2;

printf("%f", sum); // 2.500000

You can also place the type in front of a variable:


Example
int num1 = 5;
int num2 = 2;
float sum = (float) num1 / num2;

printf("%f", sum); // 2.500000


And since you learned about "decimal precision" in the previous chapter, you could make the
output even cleaner by removing the extra zeros (if you like):
Example
int num1 = 5;
int num2 = 2;
float sum = (float) num1 / num2;

printf("%.1f", sum); // 2.5

itoa and atoi


char s[30];
itoa(19,s,16);
printf("\n %s", s);
Real-Life Example
Here's a real-life example of data types and type conversion where we create a program to
calculate the percentage of a user's score in relation to the maximum score in a game:
Example
// Set the maximum possible score in the game to 500
int maxScore = 500;

// The actual score of the user


int userScore = 423;

/* Calculate the percantage of the user's score in relation to the maximum


available score.
Convert userScore to float to make sure that the division is accurate */
float percentage = (float) userScore / maxScore * 100.0;

// Print the percentage


printf("User's percentage is %.2f", percentage);

C Constants

Constants
If you don't want others (or yourself) to change existing variable values, you can use
the const keyword.
This will declare the variable as "constant", which means unchangeable and read-only:
Example
const int myNum = 15; // myNum will always be 15
myNum = 10; // error: assignment of read-only variable 'myNum'

You should always declare the variable as constant when you have values that are unlikely to
change:
Example
const int minutesPerHour = 60;
const float PI = 3.14;

Notes On Constants
When you declare a constant variable, it must be assigned with a value:
Example
Like this:
const int minutesPerHour = 60;
This however, will not work:
const int minutesPerHour;
minutesPerHour = 60; // error

Good Practice
Another thing about constant variables, is that it is considered good practice to declare them
with uppercase.
It is not required, but useful for code readability and common for C programmers:
Example
const int BIRTHYEAR = 1980;

C Operators
Operators
Operators are used to perform operations on variables and values.
In the example below, we use the + operator to add together two values:
Example
int myNum = 100 + 50;

Although the + operator is often used to add together two values, like in the example above, it
can also be used to add together a variable and a value, or a variable and another variable:
Example
int sum1 = 100 + 50; // 150 (100 + 50)
int sum2 = sum1 + 250; // 400 (150 + 250)
int sum3 = sum2 + sum2; // 800 (400 + 400)
C divides the operators into the following groups:
 Arithmetic operators
 Assignment operators
 Comparison operators
 Logical operators
 Bitwise operators

Arithmetic Operators
Arithmetic operators are used to perform common mathematical operations.
Operator Name Description Example Try it

+ Addition Adds together two values x+y Try it »

- Subtraction Subtracts one value from x-y Try it »


another

* Multiplication Multiplies two values x*y Try it »

/ Division Divides one value by x/y Try it »


another

% Modulus Returns the division x%y Try it »


remainder

++ Increment Increases the value of a ++x Try it »


variable by 1

-- Decrement Decreases the value of a --x Try it »


variable by 1
Assignment Operators
Assignment operators are used to assign values to variables.
In the example below, we use the assignment operator (=) to assign the value 10 to a variable
called x:
Example
int x = 10;

The addition assignment operator (+=) adds a value to a variable:


Example
int x = 10;
x += 5;
A list of all assignment operators:
Operator Example Same As Try it

= x=5 x=5 Try it »

+= x += 3 x=x+3 Try it »

-= x -= 3 x=x-3 Try it »

*= x *= 3 x=x*3 Try it »

/= x /= 3 x=x/3 Try it »

%= x %= 3 x=x%3 Try it »

&= x &= 3 x=x&3 Try it »

|= x |= 3 x=x|3 Try it »

^= x ^= 3 x=x^3 Try it »

>>= x >>= 3 x = x >> 3 Try it »

<<= x <<= 3 x = x << 3 Try it »

Comparison Operators
Comparison operators are used to compare two values (or variables). This is important in
programming, because it helps us to find answers and make decisions.
The return value of a comparison is either 1 or 0, which means true (1) or false (0). These
values are known as Boolean values, and you will learn more about them in
the Booleans and If..Else chapter.
In the following example, we use the greater than operator (>) to find out if 5 is greater than 3:
Example
int x = 5;
int y = 3;
printf("%d", x > y); // returns 1 (true) because 5 is greater than 3
A list of all comparison operators:
Operator Name Example Description Try it

== Equal to x == y Returns 1 if the values are Try it


equal »

!= Not equal x != y Returns 1 if the values are not Try it


equal »

> Greater than x>y Returns 1 if the first value is Try it


greater than the second value »

< Less than x<y Returns 1 if the first value is Try it


less than the second value »

>= Greater than x >= y Returns 1 if the first value is Try it


or equal to greater than, or equal to, the »
second value

<= Less than or x <= y Returns 1 if the first value is Try it


equal to less than, or equal to, the »
second value

Logical Operators
You can also test for true or false values with logical operators.
Logical operators are used to determine the logic between variables or values, by combining
multiple conditions:
Operator Name Example Description Try it

&& AND x < 5 && x < Returns 1 if both statements Try it »


10 are true

|| OR x < 5 || x < 4 Returns 1 if one of the Try it »


statements is true

! NOT !(x < 5 && x < Reverse the result, returns 0


10) if the result is 1

C Booleans
Booleans
Very often, in programming, you will need a data type that can only have one of two values, like:
 YES / NO
 ON / OFF
 TRUE / FALSE
For this, C has a bool data type, which is known as booleans.
Booleans represent values that are either true or false.
Boolean Variables
In C, the bool type is not a built-in data type, like int or char.
It was introduced in C99, and you must import the following header file to use it:
#include <stdbool.h>
A boolean variable is declared with the bool keyword and can take the values true or false:
bool isProgrammingFun = true;
bool isFishTasty = false;
Before trying to print the boolean variables, you should know that boolean values are returned
as integers:
 1 (or any other number that is not 0) represents true
 0 represents false
Therefore, you must use the %d format specifier to print a boolean value:
Example
// Create boolean variables
bool isProgrammingFun = true;
bool isFishTasty = false;

// Return boolean values


printf("%d", isProgrammingFun); // Returns 1 (true)
printf("%d", isFishTasty); // Returns 0 (false)
However, it is more common to return a boolean value by comparing values and variables.

Comparing Values and Variables


Comparing values are useful in programming, because it helps us to find answers and make
decisions.
For example, you can use a comparison operator, such as the greater than (>) operator, to
compare two values:
Example
printf("%d", 10 > 9); // Returns 1 (true) because 10 is greater than 9

From the example above, you can see that the return value is a boolean value (1).
You can also compare two variables:
Example
int x = 10;
int y = 9;
printf("%d", x > y);

In the example below, we use the equal to (==) operator to compare different values:
Example
printf("%d", 10 == 10); // Returns 1 (true), because 10 is equal to 10
printf("%d", 10 == 15); // Returns 0 (false), because 10 is not equal to
15
printf("%d", 5 == 55); // Returns 0 (false) because 5 is not equal to 55

You are not limited to only compare numbers. You can also compare boolean variables, or even
special structures, like arrays (which you will learn more about in a later chapter):
Example
bool isHamburgerTasty = true;
bool isPizzaTasty = true;
// Find out if both hamburger and pizza is tasty
printf("%d", isHamburgerTasty == isPizzaTasty);
C If ... Else

Conditions and If Statements


You have already learned that C supports the usual logical conditions from mathematics:
 Less than: a < b
 Less than or equal to: a <= b
 Greater than: a > b
 Greater than or equal to: a >= b
 Equal to a == b
 Not Equal to: a != b
You can use these conditions to perform different actions for different decisions.
C has the following conditional statements:
 Use if to specify a block of code to be executed, if a specified condition is true
 Use else to specify a block of code to be executed, if the same condition is false
 Use else if to specify a new condition to test, if the first condition is false
 Use switch to specify many alternative blocks of code to be executed

The if Statement
Use the if statement to specify a block of code to be executed if a condition is true.
Syntax
if (condition) {
// block of code to be executed if the condition is true
}

Note that if is in lowercase letters. Uppercase letters (If or IF) will generate an error.
In the example below, we test two values to find out if 20 is greater than 18. If the condition
is true, print some text:
Example
if (20 > 18) {
printf("20 is greater than 18");
}
We can also test variables:
Example
int x = 20;
int y = 18;
if (x > y) {
printf("x is greater than y");
}

Example explained
In the example above we use two variables, x and y, to test whether x is greater than y (using
the > operator). As x is 20, and y is 18, and we know that 20 is greater than 18, we print to the
screen that "x is greater than y".
C Else
The else Statement
Use the else statement to specify a block of code to be executed if the condition is false.
Syntax
if (condition) {
// block of code to be executed if the condition is true
} else {
// block of code to be executed if the condition is false
}

Example
int time = 20;
if (time < 18) {
printf("Good day.");
} else {
printf("Good evening.");
}
// Outputs "Good evening."
Example explained
In the example above, time (20) is greater than 18, so the condition is false. Because of this, we
move on to the else condition and print to the screen "Good evening". If the time was less than
18, the program would print "Good day".

C Else If
The else if Statement
Use the else if statement to specify a new condition if the first condition is false.
Syntax
if (condition1) {
// block of code to be executed if condition1 is true
} else if (condition2) {
// block of code to be executed if the condition1 is false and
condition2 is true
} else {
// block of code to be executed if the condition1 is false and
condition2 is false
}

Example
int time = 22;
if (time < 10) {
printf("Good morning.");
} else if (time < 20) {
printf("Good day.");
} else {
printf("Good evening.");
}
// Outputs "Good evening."
Example explained
In the example above, time (22) is greater than 10, so the first condition is false. The next
condition, in the else if statement, is also false, so we move on to the else condition
since condition1 and condition2 is both false - and print to the screen "Good evening".
However, if the time was 14, our program would print "Good day."

C Short Hand If Else


Short Hand If...Else (Ternary Operator)
There is also a short-hand if else, which is known as the ternary operator because it consists
of three operands. It can be used to replace multiple lines of code with a single line. It is often
used to replace simple if else statements:
Syntax
variable = (condition) ? expressionTrue : expressionFalse;

Instead of writing:
Example
int time = 20;
if (time < 18) {
printf("Good day.");
} else {
printf("Good evening.");
}

C Switch
Switch Statement
Instead of writing many if..else statements, you can use the switch statement.
The switch statement selects one of many code blocks to be executed:
Syntax
switch (expression) {
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
}
This is how it works:
 The switch expression is evaluated once
 The value of the expression is compared with the values of each case
 If there is a match, the associated block of code is executed
 The break statement breaks out of the switch block and stops the execution
 The default statement is optional, and specifies some code to run if there is no case
match
The example below uses the weekday number to calculate the weekday name:
Example
int day = 4;

switch (day) {
case 1:
printf("Monday");
break;
case 2:
printf("Tuesday");
break;
case 3:
printf("Wednesday");
break;
case 4:
printf("Thursday");
break;
case 5:
printf("Friday");
break;
case 6:
printf("Saturday");
break;
case 7:
printf("Sunday");
break;
}

// Outputs "Thursday" (day 4)

The break Keyword


When C reaches a break keyword, it breaks out of the switch block.
This will stop the execution of more code and case testing inside the block.
When a match is found, and the job is done, it's time for a break. There is no need for more
testing.
A break can save a lot of execution time because it "ignores" the execution of all the rest of the
code in the switch block.

The default Keyword


The default keyword specifies some code to run if there is no case match:
Example
int day = 4;

switch (day) {
case 6:
printf("Today is Saturday");
break;
case 7:
printf("Today is Sunday");
break;
default:
printf("Looking forward to the Weekend");
}

// Outputs "Looking forward to the Weekend"

C While Loop
Loops
Loops can execute a block of code as long as a specified condition is reached.
Loops are handy because they save time, reduce errors, and they make code more readable.

While Loop
The while loop loops through a block of code as long as a specified condition is true:
Syntax
while (condition) {
// code block to be executed
}

In the example below, the code in the loop will run, over and over again, as long as a variable (i)
is less than 5:
Example
int i = 0;

while (i < 5) {
printf("%d\n", i);
i++;
}

C Do/While Loop
The Do/While Loop
The do/while loop is a variant of the while loop. This loop will execute the code block once,
before checking if the condition is true, then it will repeat the loop as long as the condition is
true.
Syntax
do {
// code block to be executed
}
while (condition);

The example below uses a do/while loop. The loop will always be executed at least once, even
if the condition is false, because the code block is executed before the condition is tested:
Example
int i = 0;

do {
printf("%d\n", i);
i++;
}
while (i < 5);

Do not forget to increase the variable used in the condition, otherwise the loop will never end!
C For Loop
For Loop
When you know exactly how many times you want to loop through a block of code, use
the for loop instead of a while loop:
Syntax
for (expression 1; expression 2; expression 3) {
// code block to be executed
}

Expression 1 is executed (one time) before the execution of the code block.
Expression 2 defines the condition for executing the code block.
Expression 3 is executed (every time) after the code block has been executed.
The example below will print the numbers 0 to 4:
Example
int i;

for (i = 0; i < 5; i++) {


printf("%d\n", i);
}

Example explained
Expression 1 sets a variable before the loop starts (int i = 0).
Expression 2 defines the condition for the loop to run (i must be less than 5). If the condition is
true, the loop will start over again, if it is false, the loop will end.
Expression 3 increases a value (i++) each time the code block in the loop has been executed.

C Nested Loops
Nested Loops
It is also possible to place a loop inside another loop. This is called a nested loop.
The "inner loop" will be executed one time for each iteration of the "outer loop":
Example
int i, j;

// Outer loop
for (i = 1; i <= 2; ++i) {
printf("Outer: %d\n", i); // Executes 2 times

// Inner loop
for (j = 1; j <= 3; ++j) {
printf(" Inner: %d\n", j); // Executes 6 times (2 * 3)
}
}

C Break and Continue


Break
You have already seen the break statement used in an earlier chapter of this tutorial. It was
used to "jump out" of a switch statement.
The break statement can also be used to jump out of a loop.
This example jumps out of the for loop when i is equal to 4:
Example
int i;

for (i = 0; i < 10; i++) {


if (i == 4) {
break;
}
printf("%d\n", i);
}

Continue
The continue statement breaks one iteration (in the loop), if a specified condition occurs, and
continues with the next iteration in the loop.
This example skips the value of 4:
Example
int i;

for (i = 0; i < 10; i++) {


if (i == 4) {
continue;
}
printf("%d\n", i);
}

Break and Continue in While Loop


You can also use break and continue in while loops:
Break Example
int i = 0;

while (i < 10) {


if (i == 4) {
break;
}
printf("%d\n", i);
i++;
}

C Arrays

Arrays
int a[] = {25, 50, 75, 100};
printf("\n %d \n", a[0]);
a[3] = 102;
int i;
for(i = 0; i < 4; ++i) printf("%d ", a[i]);
int len = sizeof(a) / sizeof(int);
printf("\n %d \n", len);
for(i = 0; i < len; ++i) ++a[i];
for(i = 0; i < len; ++i) printf("%d ", a[i]);
printf("\n Input a: ");
Print(a,0, len-1);
Rev(a, 0, len-1);
printf("\n Rev a: ");
Print(a,0, len-1);

void Swap(int a[], int i, int j) {


int c = a[i]; a[i] = a[j]; a[j] = c;
}

void Print(int a[], int d, int c) {


int i;
for (i = d; i <= c; ++i) printf(" %d ", a[i]);
}

void Rev(int a[], int d, int c) {


int i;
while(d < c) {
Swap(a, d, c);
++d; --c;
}
}

Phương án Swap
void Swap(int *a, int *b) {
int c = *a; *a = *b; *b = c;
}

int main() {
int a = 1, b = 100;
printf("\n a = %d , b = %d ", a, b);
Swap(&a, &b);
printf("\n a = %d , b = %d ", a, b);
printf("\n T h e E n d");
return 0;
}

Len
int Len(int a[]) {
int n;
for(n = 0; a[n] = '\0'; ++n);
return n;
}

Sort
/* qsort */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FN "COPRIME.INP"
#define TRUE 1
#define FALSE 0
#define GetInt(x) fscanf(f,"%d",&x)
#define Print(x) printf(" %d", (x))
#define Println(x) printf("\n %d", (x))
#define NL() printf("\n")

void Go() {
printf(" ? ");
char c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Len(int a[]) {


int n;
for(n = 0; a[n] != '\0'; ++n);

return n;
}

void P(int a[]) {


int i;
for (i = 0; a[i] != '\0'; ++i)
printf ("%d ",a[i]);
}

int compare (const void * a, const void * b) {


return ( *(int*)a - *(int*)b );
}

int cmp(int *x, int *y) {


return *x - *y;
}

void Sort(int a[]) {


int n = Len(a);
qsort(a, Len(a), sizeof(int), cmp);
}

main() {
int a[] = { 3, 3, 40, 10, 10, -1, 100, 90, 20, 25, 1, 7, 9 };
P(a);
Sort(a);
NL(); P(a);
printf("\n T h e E n d");
return 0;
}
Arrays are used to store multiple values in a single variable, instead of declaring separate
variables for each value.
To create an array, define the data type (like int) and specify the name of the array followed
by square brackets [].
To insert values to it, use a comma-separated list, inside curly braces:
int myNumbers[] = {25, 50, 75, 100};

We have now created a variable that holds an array of four integers.

Access the Elements of an Array


To access an array element, refer to its index number.
Array indexes start with 0: [0] is the first element. [1] is the second element, etc.
This statement accesses the value of the first element [0] in myNumbers:
Example
int myNumbers[] = {25, 50, 75, 100};
printf("%d", myNumbers[0]);

// Outputs 25

Change an Array Element


To change the value of a specific element, refer to the index number:
Example
myNumbers[0] = 33;

Example
int myNumbers[] = {25, 50, 75, 100};
myNumbers[0] = 33;

printf("%d", myNumbers[0]);

// Now outputs 33 instead of 25

Loop Through an Array


You can loop through the array elements with the for loop.
The following example outputs all elements in the myNumbers array:
Example
int myNumbers[] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {


printf("%d\n", myNumbers[i]);
}

Set Array Size


Another common way to create arrays, is to specify the size of the array, and add elements
later:
Example
// Declare an array of four integers:
int myNumbers[4];
// Add elements
myNumbers[0] = 25;
myNumbers[1] = 50;
myNumbers[2] = 75;
myNumbers[3] = 100;

Using this method, you should know the number of array elements in advance, in order for
the program to store enough memory.
You are not able to change the size of the array after creation.

C Array Size
Get Array Size or Length
To get the size of an array, you can use the sizeof operator:
Example
int myNumbers[] = {10, 25, 50, 75, 100};
printf("%lu", sizeof(myNumbers)); // Prints 20

Why did the result show 20 instead of 5, when the array contains 5 elements?
- It is because the sizeof operator returns the size of a type in bytes.
You learned from the Data Types chapter that an int type is usually 4 bytes, so from the
example above, 4 x 5 (4 bytes x 5 elements) = 20 bytes.
Knowing the memory size of an array is great when you are working with larger programs that
require good memory management.
But when you just want to find out how many elements an array has, you can use the following
formula (which divides the size of the array by the size of one array element):
Example
int myNumbers[] = {10, 25, 50, 75, 100};
int length = sizeof(myNumbers) / sizeof(myNumbers[0]);

printf("%d", length); // Prints 5

Making Better Loops


In the array loops section in the previous chapter, we wrote the size of the array in the loop
condition (i < 4). This is not ideal, since it will only work for arrays of a specified size.
However, by using the sizeof formula from the example above, we can now make loops that
work for arrays of any size, which is more sustainable.
Instead of writing:
Example
int myNumbers[] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {


printf("%d\n", myNumbers[i]);
}
It is better to write:
Example
int myNumbers[] = {25, 50, 75, 100};
int length = sizeof(myNumbers) / sizeof(myNumbers[0]);
int i;

for (i = 0; i < length; i++) {


printf("%d\n", myNumbers[i]);
}

C Multidimensional Arrays
Multidimensional Arrays
In the previous chapter, you learned about arrays, which is also known as single dimension
arrays. These are great, and something you will use a lot while programming in C. However, if
you want to store data as a tabular form, like a table with rows and columns, you need to get
familiar with multidimensional arrays.
A multidimensional array is basically an array of arrays.
Arrays can have any number of dimensions. In this chapter, we will introduce the most common;
two-dimensional arrays (2D).

Two-Dimensional Arrays
A 2D array is also known as a matrix (a table of rows and columns).
To create a 2D array of integers, take a look at the following example:
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

The first dimension represents the number of rows [2], while the second dimension represents
the number of columns [3]. The values are placed in row-order, and can be visualized like this:

Access the Elements of a 2D Array


To access an element of a two-dimensional array, you must specify the index number of both
the row and column.
This statement accesses the value of the element in the first row (0) and third column (2) of
the matrix array.
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

printf("%d", matrix[0][2]); // Outputs 2

Remember that: Array indexes start with 0: [0] is the first element. [1] is the second element,
etc.
Change Elements in a 2D Array
To change the value of an element, refer to the index number of the element in each of the
dimensions:
The following example will change the value of the element in the first row (0) and first column
(0):
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };
matrix[0][0] = 9;

printf("%d", matrix[0][0]); // Now outputs 9 instead of 1

Loop Through a 2D Array


To loop through a multi-dimensional array, you need one loop for each of the array's
dimensions.
The following example outputs all elements in the matrix array:
Example
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
printf("%d\n", matrix[i][j]);
}
}

Magic Squares
Square nxn number 1..n2 all sums (row, colums, diagonals) are equals = Charcteristic Number
(dac so)

MS3 MS5 MS4 MS6


8 1 6 1 C = (1+..+n2)/n
3 5 7 = (n2+1)*n2 / (2n)
4 9 2 4 = (n2+1)*n / 2
3 C2 = 15, C4 = 35
2 C5 = 65, C6 = 111

Algorithm OMS (Odd Magic


Squere)
1. set all 0 to a
2. write 1 at (0, n/2)
3. for k = 2..n2:
3.1 Find cell a(i,j)
3.2 set a(i,j) = k
Go to direction North-East
(NE)
Odd Magic Square (OMS)
Program
/*
Name: C fan
Copyright:
Author:
Date: 21-08-24 16:14
Description:
Magic Squares
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MN = 50;
int a[50][50];

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Print(int n) {
int i, j;
for (i = 0; i < n; ++i) {
printf("\n ");
for (j = 0; j < n; ++j)
printf(" %d", a[i][j]);
}
}

int Verify(int n) {
// dac so
int s = (1+n*n)*n/2;
printf("\n Characteristic Number = %d", s);
int i, j, er = 0;
int d, c, c1 = 0, c2 = 0;
for (i = 0; i < n; ++i) {
c1 += a[i][i]; c2 += a[i][n-1-i];
d = 0; c = 0;
for (j = 0; j < n; ++j) {
d += a[i][j]; c += a[j][i];
}
if (d != s) {
printf("\n Error in row %d", i);
++er;
}
if (d != s) {
printf("\n Error in column %d", j);
++er;
}
}
if (c1 != s) {
printf("\n Error in diagona l");
++er;
}
if (c2 != s) {
printf("\n Error in diagona 2");
++er;
}
if (er == 0) printf("\n Correct");
else printf("\n Total errors: %d", er);
}

void OddMS(int n) {
// Init
memset(a, 0, sizeof(a));
// Print(n);
int i = 0, j = n/2, k;
a[i][j] = 1;
int nn = n*n;
for(k = 2; k <= nn; ++k) {
// tim vi tri (i,j) dat k
// Theo huong Dong Bac
--i; ++j;
if (i < 0) {
if (j == n) { i += 2; --j; }
else i = n-1;
}
else {
if (j == n) j = 0;
}
if (a[i][j] > 0) { i += 2; --j; }
a[i][j] = k;
}
Print(n);
Verify(n);
}

int Num(int n, int i, int j) {


return i*n + j + 1;
}

// vertical symmety
void V(int n, int i, int j) {
// a[i][j] | a[i][n-1-j]
int jj = n-1-j;
a[i][j] = Num(n, i, jj);
a[i][jj] = Num(n, i,j);
}

// horizontal symmety
void H(int n, int i, int j) {
// a[i][j]
//--------
// a[n-1-i][j]
int ii = n-1-i;
a[i][j] = Num(n, ii, j);
a[ii][j] = Num(n, i, j);
}

// Central symmety
void C(int n, int i, int j) {
int ii = n-1-i, jj = n-1-j;
a[i][j] = Num(n, ii, jj);
a[ii][jj] = Num(n, i, j);
a[ii][j] = Num(n,i, jj);
a[i][jj] = Num(n,ii,j);
}

void EvenMS(int n) {
// Init
int nn = n*n;
int i, j, k = 1;
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j)
a[i][j] = k++;
}
// Print(n);
int n2 = n/2;
int n4 = n/4;
char s[n2]; // xau mau
int c;
char ch;
for(i = 0; i < n4; ++i) s[i] = 'C'; // Center
c = n4;
if (n2 % 2 == 1) { s[c] = 'V'; ++c; s[c] = 'H'; ++c; }
for(i = c; i < n2; ++i) s[i] = 'B';
s[i] = '\0';
// printf("\n Init Xau mau: %s", s);
for(i = 0; i < n2; ++i) {
for(j = 0; j < n2; ++j) {
switch(s[j]) {
case 'V': // doi xung doc
V(n, i,j);
break;
case 'H': // doi xung ngay
H(n, i,j);
break;
case 'C': // Doi xung tam
C(n, i,j);
break;

} // switch
} // j
// quay xau mau 1234 4123
ch = s[n2-1];
for(k = n2-1; k > 0; --k) s[k] = s[k-1];
s[0] = ch;
// printf("\n Rotate Xau mau: %s", s);
} // i
Print(n);
Verify(n);
}

void MS(int n) {
printf("\n Magic Square of %d" , n);
if (n >= MN) {
printf("\n Big size %d", n);
return;
}
if (n == 1) {
printf("\n 1");
return;
}

if (n == 2) {
printf("\n No solutions");
return;
}
if (n % 2 == 1) OddMS(n);
else EvenMS(n);
}

main() {
int n;
for(n = 1; n < 10; ++n) {
MS(n); Go();
}
printf("\n T h e E n d");
return 0;
}

Even Magic Square (EMS)


1 2 3 4 5 6 tạo xâu mẫu s n = 6, n2 = 6/2 =
7 8 9 1 1 1 len = n2 = n/2 3 = len
0 1 2 k = n2/2 kí tự T k = n2/2 = 3/2 = 1
1 1 1 1 1 1 nếu n2 lẻ thêm s = TDN
3 4 5 6 7 8 DN
1 2 2 2 2 2 Têm # cho đủ len
9 0 1 2 3 4 = n2
2 2 2 2 2 3
5 6 7 8 9 0
3 3 3 3 3 3
1 2 3 4 5 6

3 5 3 4 2 3 TD
6 3 1 N
2 8 9 1 1 1 NT
5 0 1 2 D
1 1 1 1 1 1 DN
3 4 5 6 7 8 T
1 2 2 2 2 2
9 0 1 2 3 4
7 2 2 2 2 3
6 7 8 9 0
6 3 3 3 3 1
2 4 5

C Strings
Strings
Strings are used for storing text/characters.
For example, "Hello World" is a string of characters.
Unlike many other programming languages, C does not have a String type to easily create
string variables. Instead, you must use the char type and create an array of characters to make
a string in C:
char greetings[] = "Hello World!";

Note that you have to use double quotes ("").


To output the string, you can use the printf() function together with the format specifier %s to tell
C that we are now working with strings:
Example
char greetings[] = "Hello World!";
printf("%s", greetings);

Access Strings
Since strings are actually arrays in C, you can access a string by referring to its index number
inside square brackets [].
This example prints the first character (0) in greetings:
Example
char greetings[] = "Hello World!";
printf("%c", greetings[0]);

Note that we have to use the %c format specifier to print a single character.

Modify Strings
To change the value of a specific character in a string, refer to the index number, and
use single quotes:
Example
char greetings[] = "Hello World!";
greetings[0] = 'J';
printf("%s", greetings);
// Outputs Jello World! instead of Hello World!

Loop Through a String


You can also loop through the characters of a string, using a for loop:
Example
char carName[] = "Volvo";
int i;
for (i = 0; i < 5; ++i) {
printf("%c\n", carName[i]);
}

And like we specified in the arrays chapter, you can also use the sizeof formula (instead of
manually write the size of the array in the loop condition (i < 5)) to make the loop more
sustainable:
Example
char carName[] = "Volvo";
int length = sizeof(carName) / sizeof(carName[0]);
int i;

for (i = 0; i < length; ++i) {


printf("%c\n", carName[i]);
}

Another Way Of Creating Strings


In the examples above, we used a "string literal" to create a string variable. This is the easiest
way to create a string in C.
You should also note that you can create a string with a set of characters. This example will
produce the same result as the example in the beginning of this page:
Example
char greetings[] = {'H', 'e', 'l', 'l', 'o', '
', 'W', 'o', 'r', 'l', 'd', '!', '\0'};
printf("%s", greetings);

Why do we include the \0 character at the end? This is known as the "null terminating
character", and must be included when creating strings using this method. It tells C that this is
the end of the string.

Differences
The difference between the two ways of creating strings, is that the first method is easier to
write, and you do not have to include the \0 character, as C will do it for you.
You should note that the size of both arrays is the same: They both have 13 characters (space
also counts as a character by the way), including the \0 character:
Example
char greetings[] = {'H', 'e', 'l', 'l', 'o', '
', 'W', 'o', 'r', 'l', 'd', '!', '\0'};
char greetings2[] = "Hello World!";

printf("%lu\n", sizeof(greetings)); // Outputs 13


printf("%lu\n", sizeof(greetings2)); // Outputs 13

C Special Characters
Strings - Special Characters
Because strings must be written within quotes, C will misunderstand this string, and generate an
error:
char txt[] = "We are the so-called "Vikings" from the north.";

The solution to avoid this problem, is to use the backslash escape character.
The backslash (\) escape character turns special characters into string characters:
Escape character Result Description

\' ' Single quote

\" " Double quote

\\ \ Backslash
The sequence \" inserts a double quote in a string:
Example
char txt[] = "We are the so-called \"Vikings\" from the north.";

The sequence \' inserts a single quote in a string:


Example
char txt[] = "It\'s alright.";

The sequence \\ inserts a single backslash in a string:


Example
char txt[] = "The character \\ is called backslash.";

Other popular escape characters in C are:


Escape Result Try it
Character

\n New Line

\t Tab

\0 Null

C String Functions
C also has many useful string functions, which can be used to perform certain operations on
strings.
To use them, you must include the <string.h> header file in your program:
#include <string.h>
String Length
For example, to get the length of a string, you can use the strlen() function:
Example
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf("%d", strlen(alphabet));

In the Strings chapter, we used sizeof to get the size of a string/array. Note
that sizeof and strlen behaves differently, as sizeof also includes the \0 character when
counting:
Example
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf("%d", strlen(alphabet)); // 26
printf("%d", sizeof(alphabet)); // 27

It is also important that you know that sizeof will always return the memory size (in bytes), and
not the actual string length:
Example
char alphabet[50] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf("%d", strlen(alphabet)); // 26
printf("%d", sizeof(alphabet)); // 50

Concatenate Strings
To concatenate (combine) two strings, you can use the strcat() function:
Example
char str1[20] = "Hello ";
char str2[] = "World!";

// Concatenate str2 to str1 (result is stored in str1)


strcat(str1, str2);

// Print str1
printf("%s", str1);

Note that the size of str1 should be large enough to store the result of the two strings combined
(20 in our example).

Copy Strings
To copy the value of one string to another, you can use the strcpy() function:
Example
char str1[20] = "Hello World!";
char str2[20];

// Copy str1 to str2


strcpy(str2, str1);

// Print str2
printf("%s", str2);
Note that the size of str2 should be large enough to store the copied string (20 in our example).

Compare Strings
To compare two strings, you can use the strcmp() function.
It returns 0 if the two strings are equal, otherwise a value that is not 0:
Example
char str1[] = "Hello";
char str2[] = "Hello";
char str3[] = "Hi";

// Compare str1 and str2, and print the result


printf("%d\n", strcmp(str1, str2)); // Returns 0 (the strings are equal)

// Compare str1 and str3, and print the result


printf("%d\n", strcmp(str1, str3)); // Returns -1 (the strings are not
equal)

Complete String Reference


For a complete reference of string functions, go to our C <string.h> Library Reference.

User Input
You have already learned that printf() is used to output values in C.
To get user input, you can use the scanf() function:
Example
Output a number entered by the user:
// Create an integer variable that will store the number we get from the
user
int myNum;

// Ask the user to type a number


printf("Type a number: \n");

// Get and save the number the user types


scanf("%d", &myNum);

// Output the number the user typed


printf("Your number is: %d", myNum);

The scanf() function takes two arguments: the format specifier of the variable (%d in the
example above) and the reference operator (&myNum), which stores the memory address of
the variable.
Tip: You will learn more about memory addresses and functions in the next chapter.

Multiple Inputs
The scanf() function also allow multiple inputs (an integer and a character in the following
example):
Example
// Create an int and a char variable
int myNum;
char myChar;

// Ask the user to type a number AND a character


printf("Type a number AND a character and press enter: \n");

// Get and save the number AND character the user types
scanf("%d %c", &myNum, &myChar);

// Print the number


printf("Your number is: %d\n", myNum);

// Print the character


printf("Your character is: %c\n", myChar);

Take String Input


You can also get a string entered by the user:
Example
Output the name of a user:
// Create a string
char firstName[30];

// Ask the user to input some text


printf("Enter your first name: \n");

// Get and save the text


scanf("%s", firstName);

// Output the text


printf("Hello %s", firstName);

Note: When working with strings in scanf(), you must specify the size of the string/array (we
used a very high number, 30 in our example, but atleast then we are certain it will store enough
characters for the first name), and you don't have to use the reference operator (&).
However, the scanf() function has some limitations: it considers space (whitespace, tabs, etc) as
a terminating character, which means that it can only display a single word (even if you type
many words). For example:
Example
char fullName[30];

printf("Type your full name: \n");


scanf("%s", &fullName);

printf("Hello %s", fullName);

// Type your full name: John Doe


// Hello John

From the example above, you would expect the program to print "John Doe", but it only prints
"John".
That's why, when working with strings, we often use the fgets() function to read a line of text.
Note that you must include the following arguments: the name of the string
variable, sizeof(string_name), and stdin:
Example
char fullName[30];

printf("Type your full name: \n");


fgets(fullName, sizeof(fullName), stdin);

printf("Hello %s", fullName);

// Type your full name: John Doe


// Hello John Doe

Use the scanf() function to get a single word as input, and use fgets() for multiple words.

C Memory Address
Memory Address
When a variable is created in C, a memory address is assigned to the variable.
The memory address is the location of where the variable is stored on the computer.
When we assign a value to the variable, it is stored in this memory address.
To access it, use the reference operator (&), and the result represents where the variable is
stored:
Example
int myAge = 43;
printf("%p", &myAge); // Outputs 0x7ffe5367e044

Note: The memory address is in hexadecimal form (0x..). You will probably not get the same
result in your program, as this depends on where the variable is stored on your computer.
You should also note that &myAge is often called a "pointer". A pointer basically stores the
memory address of a variable as its value. To print pointer values, we use the %p format
specifier.
You will learn much more about pointers in the next chapter.
Why is it useful to know the memory address?
Pointers are important in C, because they allow us to manipulate the data in the computer's
memory - this can reduce the code and improve the performance.
Pointers are one of the things that make C stand out from other programming languages,
like Python and Java.

C Pointers

Creating Pointers
You learned from the previous chapter, that we can get the memory address of a variable with
the reference operator &:
Example
int myAge = 43; // an int variable

printf("%d", myAge); // Outputs the value of myAge (43)


printf("%p", &myAge); // Outputs the memory address of myAge
(0x7ffe5367e044)

A pointer is a variable that stores the memory address of another variable as its value.
A pointer variable points to a data type (like int) of the same type, and is created with
the * operator.
The address of the variable you are working with is assigned to the pointer:
Example
int myAge = 43; // An int variable
int* ptr = &myAge; // A pointer variable, with the name ptr, that stores
the address of myAge

// Output the value of myAge (43)


printf("%d\n", myAge);

// Output the memory address of myAge (0x7ffe5367e044)


printf("%p\n", &myAge);

// Output the memory address of myAge with the pointer (0x7ffe5367e044)


printf("%p\n", ptr);

Example explained
Create a pointer variable with the name ptr, that points to an int variable (myAge). Note that the
type of the pointer has to match the type of the variable you're working with (int in our example).
Use the & operator to store the memory address of the myAge variable, and assign it to the
pointer.
Now, ptr holds the value of myAge's memory address.

Dereference
In the example above, we used the pointer variable to get the memory address of a variable
(used together with the & reference operator).
You can also get the value of the variable the pointer points to, by using the * operator
(the dereference operator):
Example
int myAge = 43; // Variable declaration
int* ptr = &myAge; // Pointer declaration

// Reference: Output the memory address of myAge with the pointer


(0x7ffe5367e044)
printf("%p\n", ptr);

// Dereference: Output the value of myAge with the pointer (43)


printf("%d\n", *ptr);

Note that the * sign can be confusing here, as it does two different things in our code:
 When used in declaration (int* ptr), it creates a pointer variable.
 When not used in declaration, it act as a dereference operator.

Good To Know: There are two ways to declare pointer variables in C:


int* myNum;
int *myNum;
Notes on Pointers
Pointers are one of the things that make C stand out from other programming languages,
like Python and Java.
They are important in C, because they allow us to manipulate the data in the computer's
memory. This can reduce the code and improve the performance. If you are familiar with data
structures like lists, trees and graphs, you should know that pointers are especially useful for
implementing those. And sometimes you even have to use pointers, for example when working
with files and memory management.
But be careful; pointers must be handled with care, since it is possible to damage data stored
in other memory addresses.

C Pointers and Arrays

Pointers & Arrays


You can also use pointers to access arrays.
Consider the following array of integers:
Example
int myNumbers[4] = {25, 50, 75, 100};

You learned from the arrays chapter that you can loop through the array elements with
a for loop:
Example
int myNumbers[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {


printf("%d\n", myNumbers[i]);
}

Result:
25
50
75
100
Instead of printing the value of each array element, let's print the memory address of each array
element:
Example
int myNumbers[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {


printf("%p\n", &myNumbers[i]);
}

Result:
0x7ffe70f9d8f0
0x7ffe70f9d8f4
0x7ffe70f9d8f8
0x7ffe70f9d8fc
Note that the last number of each of the elements' memory address is different, with an addition
of 4.
It is because the size of an int type is typically 4 bytes, remember:
Example
// Create an int variable
int myInt;

// Get the memory size of an int


printf("%lu", sizeof(myInt));

Result:
4
So from the "memory address example" above, you can see that the compiler reserves 4 bytes
of memory for each array element, which means that the entire array takes up 16 bytes (4 * 4)
of memory storage:
Example
int myNumbers[4] = {25, 50, 75, 100};

// Get the size of the myNumbers array


printf("%lu", sizeof(myNumbers));

Result:
16

How Are Pointers Related to Arrays


Ok, so what's the relationship between pointers and arrays? Well, in C, the name of an array,
is actually a pointer to the first element of the array.
Confused? Let's try to understand this better, and use our "memory address example" above
again.
The memory address of the first element is the same as the name of the array:
Example
int myNumbers[4] = {25, 50, 75, 100};

// Get the memory address of the myNumbers array


printf("%p\n", myNumbers);

// Get the memory address of the first array element


printf("%p\n", &myNumbers[0]);

Result:
0x7ffe70f9d8f0
0x7ffe70f9d8f0
This basically means that we can work with arrays through pointers!
How? Since myNumbers is a pointer to the first element in myNumbers, you can use
the * operator to access it:
Example
int myNumbers[4] = {25, 50, 75, 100};

// Get the value of the first element in myNumbers


printf("%d", *myNumbers);

Result:
25
To access the rest of the elements in myNumbers, you can increment the pointer/array (+1, +2,
etc):
Example
int myNumbers[4] = {25, 50, 75, 100};

// Get the value of the second element in myNumbers


printf("%d\n", *(myNumbers + 1));

// Get the value of the third element in myNumbers


printf("%d", *(myNumbers + 2));

// and so on..

Result:
50
75
Or loop through it:
Example
int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int i;

for (i = 0; i < 4; i++) {


printf("%d\n", *(ptr + i));
}

Result:
25
50
75
100
It is also possible to change the value of array elements with pointers:
Example
int myNumbers[4] = {25, 50, 75, 100};

// Change the value of the first element to 13


*myNumbers = 13;

// Change the value of the second element to 17


*(myNumbers +1) = 17;

// Get the value of the first element


printf("%d\n", *myNumbers);

// Get the value of the second element


printf("%d\n", *(myNumbers + 1));

Result:
13
17
This way of working with arrays might seem a bit excessive. Especially with simple arrays like in
the examples above. However, for large arrays, it can be much more efficient to access and
manipulate arrays with pointers.
It is also considered faster and easier to access two-dimensional arrays with pointers.
And since strings are actually arrays, you can also use pointers to access strings.
For now, it's great that you know how this works. But like we specified in the previous
chapter; pointers must be handled with care, since it is possible to overwrite other data
stored in memory.

C Functions
A function is a block of code which only runs when it is called.
You can pass data, known as parameters, into a function.
Functions are used to perform certain actions, and they are important for reusing code: Define
the code once, and use it many times.

Predefined Functions
So it turns out you already know what a function is. You have been using it the whole time while
studying this tutorial!
For example, main() is a function, which is used to execute code, and printf() is a function; used
to output/print text to the screen:
Example
int main() {
printf("Hello World!");
return 0;
}

Create a Function
To create (often referred to as declare) your own function, specify the name of the function,
followed by parentheses () and curly brackets {}:
Syntax
void myFunction() {
// code to be executed
}

Example Explained
 myFunction() is the name of the function
 void means that the function does not have a return value. You will learn more about
return values later in the next chapter
 Inside the function (the body), add code that defines what the function should do

Call a Function
Declared functions are not executed immediately. They are "saved for later use", and will be
executed when they are called.
To call a function, write the function's name followed by two parentheses () and a semicolon ;
In the following example, myFunction() is used to print a text (the action), when it is called:
Example
Inside main, call myFunction():
// Create a function
void myFunction() {
printf("I just got executed!");
}

int main() {
myFunction(); // call the function
return 0;
}

// Outputs "I just got executed!"

A function can be called multiple times:


Example
void myFunction() {
printf("I just got executed!");
}

int main() {
myFunction();
myFunction();
myFunction();
return 0;
}

// I just got executed!


// I just got executed!
// I just got executed!

You can also use functions to call other functions:


Example
// Create a function (myFunction)
void myFunction() {
printf("Some text in myFunction\n");
myOtherFunction(); // call myOtherFunction
}

// Create another function (myOtherFunction)


void myOtherFunction() {
printf("Hey! Some text in myOtherFunction\n");
}

int main() {
myFunction(); // call myFunction
return 0;
}

Calculate the Sum of Numbers


You can put almost whatever you want inside a function. The purpose of the function is to save
the code, and execute it when you need it.
Like in the example below, we have created a function to calculate the sum of two numbers.
Whenever you are ready to execute the function (and perform the calculation), you just call it:
Example
void calculateSum() {
int x = 5;
int y = 10;
int sum = x + y;
printf("The sum of x + y is: %d", sum);
}

int main() {
calculateSum(); // call the function
return 0;
}

// Outputs The sum of x + y is: 15

This was just an example to demonstrate a simple function with different statements in C. The
real power of a function is revealed in the next chapter, when we pass "parameters" to it. This
allows the function to calculate the sum of any numbers, instead of being limited to the fixed
values 5 and 10.

C Function Parameters

Parameters and Arguments


Information can be passed to functions as a parameter. Parameters act as variables inside the
function.
Parameters are specified after the function name, inside the parentheses. You can add as many
parameters as you want, just separate them with a comma:
Syntax
returnType functionName(parameter1, parameter2, parameter3) {
// code to be executed
}

In the example below, the function takes a string of characters with name as parameter. When
the function is called, we pass along a name, which is used inside the function to print "Hello"
and the name of each person:
Example
void myFunction(char name[]) {
printf("Hello %s\n", name);
}

int main() {
myFunction("Liam");
myFunction("Jenny");
myFunction("Anja");
return 0;
}

// Hello Liam
// Hello Jenny
// Hello Anja

When a parameter is passed to the function, it is called an argument. So, from the example
above: name is a parameter, while Liam, Jenny and Anja are arguments.

Multiple Parameters
Inside the function, you can add as many parameters as you want:
Example
void myFunction(char name[], int age) {
printf("Hello %s. You are %d years old.\n", name, age);
}

int main() {
myFunction("Liam", 3);
myFunction("Jenny", 14);
myFunction("Anja", 30);
return 0;
}

// Hello Liam. You are 3 years old.


// Hello Jenny. You are 14 years old.
// Hello Anja. You are 30 years old.

If we consider the "Calculate the Sum of Numbers" example from the previous page, we can
make a more sustainable program by using function parameters:
Example
void calculateSum(int x, int y) {
int sum = x + y;
printf("The sum of %d + %d is: %d\n", x, y, sum);
}

int main() {
calculateSum(5, 3);
calculateSum(8, 2);
calculateSum(15, 15);
return 0;
}

Notes on Parameters
Note that when you are working with multiple parameters, the function call must have the same
number of arguments as there are parameters, and the arguments must be passed in the same
order.

Sum of numbers
Nạp dãy số nguyên, tính tổng và ghi nhận giá trị max

#include <stdio.h>
#define TRUE 1
int max; /* maximum length seen so far */
void Go() {
printf(" ? ");
char c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

// Nap cac so x, tinh tong, ghi nhan max


int GetNums() {
int x;
max = 0;
int sum = 0;
while (TRUE) {
printf("\n input (x < 0 to break): ");
scanf(" %d", &x);
if (x < 0) break;
sum += x;
if (x > max) max = x;
}
return sum;
}

main() {
int t = GetNums();
printf("\n Sum = %d", t);
printf("\n max input = %d", max);
printf("\n T h e E n d");
return 0;
}

Qudratic Equation
2
ax +bx +c=0
input: float a, b, c; // các hệ số
output: int n; // số nghiệm
float x1, x2; // nghiệm
// Qudratic Equation
#include <stdio.h>
#include <string.h>

void E2(float a, float b, float c, int *n, float *x1, float *x2) {
float delta = b*b - 4*a*c;
if (delta < 0) {
*n = 0; *x1 = *x2 = 0.0;
return;
}
float sd = sqrt(delta);
if (delta == 0) {
*n = 1; *x1 = *x2 = -b/(2*a);
return;
}
// if (delta < 0)
*n = 2; *x1 = (-b+sd)/(2*a);
*x2 = (-b-sd)/(2*a);
return;
}

void Call(float a, float b, float c) {


printf("\n --------------------");
printf("\n %fx^2 + %fx + %f = 0 ", a, b, c);
int n;
float x1, x2;
E2(a, b, c, &n, &x1, &x2);
switch(n) {
case 0: printf("\n No solutions ");
break;
case 1: printf("\n Double solutions %f %f ", x1, x2);
break;
case 2: printf("\n Two solutions %f %f ", x1, x2);
break;
} // switch
}

/*
x^2 + 2x +3 = 0
(x-3)^2 = x^2 -6x + 9
(x-3)(x+2) = x^2 -x -6
*/
main() {
Call(1, 2, 4);
Call(1, -6, 9);
Call(1, -1, 6);
printf("\n T h e E n d");
return 0;
}

Ghi nhớ: Muốn có tham biến ra: Mô tả *, Gọi &

ADVERTISEMENT

Pass Arrays as Function Parameters


You can also pass arrays to a function:
Example
void myFunction(int myNumbers[5]) {
for (int i = 0; i < 5; i++) {
printf("%d\n", myNumbers[i]);
}
}

int main() {
int myNumbers[5] = {10, 20, 30, 40, 50};
myFunction(myNumbers);
return 0;
}

Example Explained
The function (myFunction) takes an array as its parameter (int myNumbers[5]), and loops
through the array elements with the for loop.
When the function is called inside main(), we pass along the myNumbers array, which outputs
the array elements.
Note that when you call the function, you only need to use the name of the array when passing
it as an argument myFunction(myNumbers). However, the full declaration of the array is needed
in the function parameter (int myNumbers[5]).

Return Values
The void keyword, used in the previous examples, indicates that the function should not return a
value. If you want the function to return a value, you can use a data type (such as int or float,
etc.) instead of void, and use the return keyword inside the function:
Example
int myFunction(int x) {
return 5 + x;
}

int main() {
printf("Result is: %d", myFunction(3));
return 0;
}

// Outputs 8 (5 + 3)

This example returns the sum of a function with two parameters:


Example
int myFunction(int x, int y) {
return x + y;
}

int main() {
printf("Result is: %d", myFunction(5, 3));
return 0;
}

// Outputs 8 (5 + 3)

You can also store the result in a variable:


Example
int myFunction(int x, int y) {
return x + y;
}

int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)

If we consider the "Calculate the Sum of Numbers" example one more time, we can
use return instead and store the results in different variables. This will make the program even
more flexible and easier to control:
Example
int calculateSum(int x, int y) {
return x + y;
}

int main() {
int result1 = calculateSum(5, 3);
int result2 = calculateSum(8, 2);
int result3 = calculateSum(15, 15);

printf("Result1 is: %d\n", result1);


printf("Result2 is: %d\n", result2);
printf("Result3 is: %d\n", result3);

return 0;
}

Tip: If you have many "result variables", it is better to store the results in an array:
Example
int calculateSum(int x, int y) {
return x + y;
}

int main() {
// Create an array
int resultArr[6];

// Call the function with different arguments and store the results in
the array
resultArr[0] = calculateSum(5, 3);
resultArr[1] = calculateSum(8, 2);
resultArr[2] = calculateSum(15, 15);
resultArr[3] = calculateSum(9, 1);
resultArr[4] = calculateSum(7, 7);
resultArr[5] = calculateSum(1, 1);

for (int i = 0; i < 6; i++) {


printf("Result%d is = %d\n", i + 1, resultArr[i]);
}

return 0;
}

Real-Life Example
To demonstrate a practical example of using functions, let's create a program that converts a
value from fahrenheit to celsius:
Example
// Function to convert Fahrenheit to Celsius
float toCelsius(float fahrenheit) {
return (5.0 / 9.0) * (fahrenheit - 32.0);
}

int main() {
// Set a fahrenheit value
float f_value = 98.8;

// Call the function with the fahrenheit value


float result = toCelsius(f_value);

// Print the fahrenheit value


printf("Fahrenheit: %.2f\n", f_value);

// Print the result


printf("Convert Fahrenheit to Celsius: %.2f\n", result);

return 0;
}

C Variable Scope
Now that you understand how functions work, it is important to learn how variables act inside
and outside of functions.
In C, variables are only accessible inside the region they are created. This is called scope.

Local Scope
A variable created inside a function belongs to the local scope of that function, and can only be
used inside that function:
Example
void myFunction() {
// Local variable that belongs to myFunction
int x = 5;

// Print the variable x


printf("%d", x);
}

int main() {
myFunction();
return 0;
}

A local variable cannot be used outside the function it belongs to.


If you try to access it outside the function, an error occurs:
Example
void myFunction() {
// Local variable that belongs to myFunction
int x = 5;
}
int main() {
myFunction();

// Print the variable x in the main function


printf("%d", x);
return 0;
}

Global Scope
A variable created outside of a function, is called a global variable and belongs to the global
scope.
Global variables are available from within any scope, global and local:
Example
A variable created outside of a function is global and can therefore be used by anyone:
// Global variable x
int x = 5;

void myFunction() {
// We can use x here
printf("%d", x);
}

int main() {
myFunction();

// We can also use x here


printf("%d", x);
return 0;
}

Naming Variables
If you operate with the same variable name inside and outside of a function, C will treat them as
two separate variables; One available in the global scope (outside the function) and one
available in the local scope (inside the function):
Example
The function will print the local x, and then the code will print the global x:
// Global variable x
int x = 5;

void myFunction() {
// Local variable with the same name as the global variable (x)
int x = 22;
printf("%d\n", x); // Refers to the local variable x
}

int main() {
myFunction();

printf("%d\n", x); // Refers to the global variable x


return 0;
}

However, you should avoid using the same variable name for both globally and locally variables
as it can lead to errors and confusion.
In general, you should be careful with global variables, since they can be accessed and
modified from any function:
Example
Change the value of x from myFunction:
// Global variable
int x = 5;

void myFunction() {
printf("%d\n", ++x); // Increment the value of x by 1 and print it
}

int main() {
myFunction();

printf("%d\n", x); // Print the global variable x


return 0;
}

// The value of x is now 6 (no longer 5)

Conclusion
To sum up, use local variables (with good variable names) as much as you can. This will make
your code easier to maintain and better to understand. However, you may find global variables
when working on existing C programs or while collaborating with others. Therefore, it is good to
understand how the scope works and how to use it effectively to make sure your code is clear
and functional.
C Function Declaration and Definition

Function Declaration and Definition


You have already learned from the previous chapters that you can create and call a function in
the following way:
Example
// Create a function
void myFunction() {
printf("I just got executed!");
}

int main() {
myFunction(); // call the function
return 0;
}
A function consist of two parts:
 Declaration: the function's name, return type, and parameters (if any)
 Definition: the body of the function (code to be executed)
void myFunction() { // declaration
// the body of the function (definition)
}

For code optimization, it is recommended to separate the declaration and the definition of the
function.
You will often see C programs that have function declaration above main(), and function
definition below main(). This will make the code better organized and easier to read:
Example
// Function declaration
void myFunction();

// The main method


int main() {
myFunction(); // call the function
return 0;
}

// Function definition
void myFunction() {
printf("I just got executed!");
}

What About Parameters


If we use the example from the function parameters chapter regarding parameters and return
values:
Example
int myFunction(int x, int y) {
return x + y;
}

int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)

It is considered good practice to write it like this instead:


Example
// Function declaration
int myFunction(int x, int y);

// The main method


int main() {
int result = myFunction(5, 3); // call the function
printf("Result is = %d", result);
return 0;
}

// Function definition
int myFunction(int x, int y) {
return x + y;
}

C Recursion
Recursion
Recursion is the technique of making a function call itself. This technique provides a way to
break complicated problems down into simple problems which are easier to solve.
Recursion may be a bit difficult to understand. The best way to figure out how it works is to
experiment with it.

Recursion Example
Adding two numbers together is easy to do, but adding a range of numbers is more
complicated. In the following example, recursion is used to add a range of numbers together by
breaking it down into the simple task of adding two numbers:
Example
int sum(int k);

int main() {
int result = sum(10);
printf("%d", result);
return 0;
}

int sum(int k) {
if (k > 0) {
return k + sum(k - 1);
} else {
return 0;
}
}
Example Explained
When the sum() function is called, it adds parameter k to the sum of all numbers smaller
than k and returns the result. When k becomes 0, the function just returns 0. When running, the
program follows these steps:
10 + sum(9)
10 + ( 9 + sum(8) )
10 + ( 9 + ( 8 + sum(7) ) )
...
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + sum(0)
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
Since the function does not call itself when k is 0, the program stops there and returns the
result.
The developer should be very careful with recursion as it can be quite easy to slip into writing a
function which never terminates, or one that uses excess amounts of memory or processor
power. However, when written correctly, recursion can be a very efficient and mathematically-
elegant approach to programming.

Hanoi Tower
a b c

// Hanoi Tower
#include <stdio.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Hanoi(int n, int a, int b) {


int c = 6-a-b;
if (n == 1) printf("\n %d -> %d ", a, b);
else {
Hanoi(n-1, a, c);
printf("\n %d -> %d ", a, b);
Hanoi(n-1, c, b);
}
}

main() {
Hanoi(3, 1, 2);
printf("\n T h e E n d");
return 0;
}

Len(x)
#include <stdio.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Len(int x) {
return (x < 10) ? 1 : Len(x/10)+1;
}

main() {
int x = 10203;
printf("\n %d : %d ", x, Len(x));
printf("\n T h e E n d");
return 0;
}

Gcd(a,b)
#include <stdio.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Gcd(int a, int b) {


return (b == 0) ? a : Gcd(b, a % b);
}

main() {
int a = 21 , b = 49;
printf("\n Gcd(%d , %d) = %d ", a, b, Gcd(a,b));
printf("\n T h e E n d");
return 0;
}

Fib(n)
// Hanoi Tower
#include <stdio.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Fib(int n) {
return (n < 2) ? n : Fib(n-2)+Fib(n-1);
}

main() {
int n;
for (n = 0; n < 10; ++n) {
printf("\n Fib of %d = %d ", n, Fib(n));
}
printf("\n T h e E n d");
return 0;
}

Fac(n)
// Hanoi Tower
#include <stdio.h>
#include <string.h>

void Go() {
printf(" ? ");
char c;
scanf("%c", &c);
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

int Fac(int n) { // 0! = 1! = 1
return (n < 2) ? 1 : n*Fac(n-1);
}

main() {
int n;
for (n = 0; n <= 10; ++n) {
printf("\n %d! = %d ", n, Fac(n));
}
printf("\n T h e E n d");
return 0;
}

Attention
Tránh gọi một hàm nhiều lần (using Array)

C Math Functions

Math Functions
There is also a list of math functions available, that allows you to perform mathematical tasks on
numbers.
To use them, you must include the math.h header file in your program:
#include <math.h>

Square Root
To find the square root of a number, use the sqrt() function:
Example
printf("%f", sqrt(16));
Round a Number
The ceil() function rounds a number upwards to its nearest integer, and the floor() method
rounds a number downwards to its nearest integer, and returns the result:
Example
printf("%f", ceil(1.4));
printf("%f", floor(1.4));

Power
The pow() function returns the value of x to the power of y (xy):
Example
printf("%f", pow(4, 3));

Complete Math Reference


For a complete reference of math functions, go to our C <math.h> Library Reference.

C Files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TRUE 1
#define FALSE 0
#define FN "..."
#define GN "..."

FILE *f = fopen(FN, "r");


FILE *g = fopen(GN, "w");
if (f == NULL) {
printf("unable open input file %s ", FN);
}
if (g == NULL) {
printf("unable create output file %s ", GN);
return 0;
}
int n;
fscanf(f, "%d", &n);
fprintf(g, "%d\n", s[n-1]);
fclose(f); fclose(g);

File Handling
In C, you can create, open, read, and write to files by declaring a pointer of type FILE, and use
the fopen() function:
FILE *fptr;
fptr = fopen(filename, mode);
FILE is basically a data type, and we need to create a pointer variable to work with it (fptr). For
now, this line is not important. It's just something you need when working with files.
To actually open a file, use the fopen() function, which takes two parameters:
Parameter Description
filename The name of the actual file you want to open (or create),
like filename.txt

mode A single character, which represents what you want to do with


the file (read, write or append):
w - Writes to a file
a - Appends new data to a file
r - Reads from a file

Create a File
To create a file, you can use the w mode inside the fopen() function.
The w mode is used to write to a file. However, if the file does not exist, it will create one for
you:
Example
FILE *fptr;

// Create a file
fptr = fopen("filename.txt", "w");

// Close the file


fclose(fptr);
Note: The file is created in the same directory as your other C files, if nothing else is specified.
On our computer, it looks like this:

Tip: If you want to create the file in a specific folder, just provide an absolute path:
fptr = fopen("C:\directoryname\filename.txt", "w");
Closing the file
Did you notice the fclose() function in our example above?
This will close the file when we are done with it.
It is considered as good practice, because it makes sure that:
 Changes are saved properly
 Other programs can use the file (if you want)
 Clean up unnecessary memory space
In the next chapters, you will learn how to write content to a file and read from it.

C Write To Files
Write To a File
Let's use the w mode from the previous chapter again, and write something to the file we just
created.
The w mode means that the file is opened for writing. To insert content to it, you can use
the fprintf() function and add the pointer variable (fptr in our example) and some text:
Example
FILE *fptr;

// Open a file in writing mode


fptr = fopen("filename.txt", "w");

// Write some text to the file


fprintf(fptr, "Some text");

// Close the file


fclose(fptr);
As a result, when we open the file on our computer, it looks like this:

Note: If you write to a file that already exists, the old content is deleted, and the new content is
inserted. This is important to know, as you might accidentally erase existing content.
For example:
Example
fprintf(fptr, "Hello World!");
As a result, when we open the file on our computer, it says "Hello World!" instead of "Some
text":
Append Content To a File
If you want to add content to a file without deleting the old content, you can use the a mode.
The a mode appends content at the end of the file:
Example
FILE *fptr;

// Open a file in append mode


fptr = fopen("filename.txt", "a");

// Append some text to the file


fprintf(fptr, "\nHi everybody!");

// Close the file


fclose(fptr);
As a result, when we open the file on our computer, it looks like this:

C Read Files

Read a File
In the previous chapter, we wrote to a file using w and a modes inside the fopen() function.
To read from a file, you can use the r mode:
Example
FILE *fptr;

// Open a file in read mode


fptr = fopen("filename.txt", "r");
This will make the filename.txt opened for reading.
It requires a little bit of work to read a file in C. Hang in there! We will guide you step-by-step.
Next, we need to create a string that should be big enough to store the content of the file.
For example, let's create a string that can store up to 100 characters:
Example
FILE *fptr;

// Open a file in read mode


fptr = fopen("filename.txt", "r");

// Store the content of the file


char myString[100];
In order to read the content of filename.txt, we can use the fgets() function.
The fgets() function takes three parameters:
Example
fgets(myString, 100, fptr);
1. The first parameter specifies where to store the file content, which will be in
the myString array we just created.
2. The second parameter specifies the maximum size of data to read, which should match
the size of myString (100).
3. The third parameter requires a file pointer that is used to read the file (fptr in our
example).
Now, we can print the string, which will output the content of the file:
Example
FILE *fptr;

// Open a file in read mode


fptr = fopen("filename.txt", "r");

// Store the content of the file


char myString[100];

// Read the content and store it inside myString


fgets(myString, 100, fptr);

// Print the file content


printf("%s", myString);

// Close the file


fclose(fptr);
Hello World!
Note: The fgets function only reads the first line of the file. If you remember, there were two
lines of text in filename.txt.
To read every line of the file, you can use a while loop:
Example
FILE *fptr;

// Open a file in read mode


fptr = fopen("filename.txt", "r");

// Store the content of the file


char myString[100];

// Read the content and print it


while(fgets(myString, 100, fptr)) {
printf("%s", myString);
}

// Close the file


fclose(fptr);

C Structures (structs)

Structures
Structures (also called structs) are a way to group several related variables into one place. Each
variable in the structure is known as a member of the structure.
Unlike an array, a structure can contain many different data types (int, float, char, etc.).

Create a Structure
You can create a structure by using the struct keyword and declare each of its members inside
curly braces:
struct MyStructure { // Structure declaration
int myNum; // Member (int variable)
char myLetter; // Member (char variable)
}; // End the structure with a semicolon
To access the structure, you must create a variable of it.
Use the struct keyword inside the main() method, followed by the name of the structure and
then the name of the structure variable:
Create a struct variable with the name "s1":
struct myStructure {
int myNum;
char myLetter;
};

int main() {
struct myStructure s1;
return 0;
}

Access Structure Members


To access members of a structure, use the dot syntax (.):
Example
// Create a structure called myStructure
struct myStructure {
int myNum;
char myLetter;
};

int main() {
// Create a structure variable of myStructure called s1
struct myStructure s1;

// Assign values to members of s1


s1.myNum = 13;
s1.myLetter = 'B';

// Print values
printf("My number: %d\n", s1.myNum);
printf("My letter: %c\n", s1.myLetter);

return 0;
}
Now you can easily create multiple structure variables with different values, using just one
structure:
Example
// Create different struct variables
struct myStructure s1;
struct myStructure s2;

// Assign values to different struct variables


s1.myNum = 13;
s1.myLetter = 'B';

s2.myNum = 20;
s2.myLetter = 'C';
What About Strings in Structures?
Remember that strings in C are actually an array of characters, and unfortunately, you can't
assign a value to an array like this:
Example
struct myStructure {
int myNum;
char myLetter;
char myString[30]; // String
};

int main() {
struct myStructure s1;

// Trying to assign a value to the string


s1.myString = "Some text";

// Trying to print the value


printf("My string: %s", s1.myString);

return 0;
}
An error will occur:
prog.c:12:15: error: assignment to expression with array type
However, there is a solution for this! You can use the strcpy() function and assign the value
to s1.myString, like this:
Example
struct myStructure {
int myNum;
char myLetter;
char myString[30]; // String
};

int main() {
struct myStructure s1;

// Assign a value to the string using the strcpy function


strcpy(s1.myString, "Some text");

// Print the value


printf("My string: %s", s1.myString);

return 0;
}
Result:
My string: Some text

Simpler Syntax
You can also assign values to members of a structure variable at declaration time, in a single
line.
Just insert the values in a comma-separated list inside curly braces {}. Note that you don't have
to use the strcpy() function for string values with this technique:
Example
// Create a structure
struct myStructure {
int myNum;
char myLetter;
char myString[30];
};

int main() {
// Create a structure variable and assign values to it
struct myStructure s1 = {13, 'B', "Some text"};

// Print values
printf("%d %c %s", s1.myNum, s1.myLetter, s1.myString);

return 0;
}
Note: The order of the inserted values must match the order of the variable types declared in
the structure (13 for int, 'B' for char, etc).

Copy Structures
You can also assign one structure to another.
In the following example, the values of s1 are copied to s2:
Example
struct myStructure s1 = {13, 'B', "Some text"};
struct myStructure s2;

s2 = s1;

Modify Values
If you want to change/modify a value, you can use the dot syntax (.).
And to modify a string value, the strcpy() function is useful again:
Example
struct myStructure {
int myNum;
char myLetter;
char myString[30];
};

int main() {
// Create a structure variable and assign values to it
struct myStructure s1 = {13, 'B', "Some text"};

// Modify values
s1.myNum = 30;
s1.myLetter = 'C';
strcpy(s1.myString, "Something else");

// Print values
printf("%d %c %s", s1.myNum, s1.myLetter, s1.myString);
return 0;
}
Modifying values are especially useful when you copy structure values:
Example
// Create a structure variable and assign values to it
struct myStructure s1 = {13, 'B', "Some text"};

// Create another structure variable


struct myStructure s2;

// Copy s1 values to s2
s2 = s1;

// Change s2 values
s2.myNum = 30;
s2.myLetter = 'C';
strcpy(s2.myString, "Something else");

// Print values
printf("%d %c %s\n", s1.myNum, s1.myLetter, s1.myString);
printf("%d %c %s\n", s2.myNum, s2.myLetter, s2.myString);
Ok, so, how are structures useful?
Imagine you have to write a program to store different information about Cars, such as brand,
model, and year. What's great about structures is that you can create a single "Car template"
and use it for every cars you make. See below for a real life example.

New Quadratic Equation

/*
Name: Quadratic Equation
Copyright: (C) 2024
Author: C Fan
Date: 22-08-24 14:59
Description:
using struct
*/

#include <stdio.h>
#include <string.h>

typedef struct {
int N; // so nghiem
float X1, X2; // nghiem
} E2Out;

E2Out E2(float a, float b, float c) {


float delta = b*b - 4*a*c;
E2Out e;
e.N = 0; e.X1 = e.X2 = 0;
if (delta < 0) return e;
float sd = sqrt(delta);
if (delta == 0) {
e.N = 1; e.X1 = e.X2 = -b/(2*a);
return e;
}
// delta > 0
e.N = 2; e.X1 = (-b+sd)/(2*a);
e.X2 = (-b-sd)/(2*a);
return e;
}

void Call(float a, float b, float c) {


printf("\n --------------------");
printf("\n %fx^2 + %fx + %f = 0 ", a, b, c);
int n;
float x1, x2;
E2Out e = E2(a, b, c);
switch(e.N) {
case 0: printf("\n No solutions ");
break;
case 1: printf("\n Double solutions %f %f ", e.X1, e.X2);
break;
case 2: printf("\n Two solutions %f %f ", e.X1, e.X2);
break;
} // switch
}

/*
x^2 + 2x +3 = 0
(x-3)^2 = x^2 -6x + 9
(x-3)(x+2) = x^2 -x -6
*/
main() {
Call(1, 2, 4);
Call(1, -6, 9);
Call(1, -1, 6);
printf("\n T h e E n d");
return 0;
}
Output

--------------------
1.000000x^2 + 2.000000x + 4.000000 = 0
No solutions
--------------------
1.000000x^2 + -6.000000x + 9.000000 = 0
Double solutions 3.000000 3.000000
--------------------
1.000000x^2 + -1.000000x + 6.000000 = 0
No solutions
T h e E n d
--------------------------------
Process exited after 0.02081 seconds with return value 0
Press any key to continue . . .

Real-Life Example
Use a structure to store different information about Cars:
Example
struct Car {
char brand[50];
char model[50];
int year;
};

int main() {
struct Car car1 = {"BMW", "X5", 1999};
struct Car car2 = {"Ford", "Mustang", 1969};
struct Car car3 = {"Toyota", "Corolla", 2011};

printf("%s %s %d\n", car1.brand, car1.model, car1.year);


printf("%s %s %d\n", car2.brand, car2.model, car2.year);
printf("%s %s %d\n", car3.brand, car3.model, car3.year);

return 0;
}

C Enumeration (enum)

C Enums
An enum is a special type that represents a group of constants (unchangeable values).
To create an enum, use the enum keyword, followed by the name of the enum, and separate
the enum items with a comma:
enum Level {
LOW,
MEDIUM,
HIGH
};
Note that the last item does not need a comma.
It is not required to use uppercase, but often considered as good practice.
Enum is short for "enumerations", which means "specifically listed".
To access the enum, you must create a variable of it.
Inside the main() method, specify the enum keyword, followed by the name of the enum (Level)
and then the name of the enum variable (myVar in this example):
enum Level myVar;
Now that you have created an enum variable (myVar), you can assign a value to it.
The assigned value must be one of the items inside the enum (LOW, MEDIUM or HIGH):
enum Level myVar = MEDIUM;
By default, the first item (LOW) has the value 0, the second (MEDIUM) has the value 1, etc.
If you now try to print myVar, it will output 1, which represents MEDIUM:
int main() {
// Create an enum variable and assign a value to it
enum Level myVar = MEDIUM;

// Print the enum variable


printf("%d", myVar);

return 0;
}
Change Values
As you know, the first item of an enum has the value 0. The second has the value 1, and so on.
To make more sense of the values, you can easily change them:
enum Level {
LOW = 25,
MEDIUM = 50,
HIGH = 75
};
printf("%d", myVar); // Now outputs 50
Note that if you assign a value to one specific item, the next items will update their numbers
accordingly:
enum Level {
LOW = 5,
MEDIUM, // Now 6
HIGH // Now 7
};

Enum in a Switch Statement


Enums are often used in switch statements to check for corresponding values:
enum Level {
LOW = 1,
MEDIUM,
HIGH
};

int main() {
enum Level myVar = MEDIUM;

switch (myVar) {
case 1:
printf("Low Level");
break;
case 2:
printf("Medium level");
break;
case 3:
printf("High level");
break;
}
return 0;
}
Why And When To Use Enums?
Enums are used to give names to constants, which makes the code easier to read and
maintain.
Use enums when you have values that you know aren't going to change, like month days, days,
colors, deck of cards, etc.
C Memory Management

Memory management is the process of handling how much memory a program uses through
different operations.
Memory in C
Understanding how memory works in C is important. When you create a basic variable, C will
automatically reserve space for that variable. An int variable for example, will typically occupy 4
bytes of memory, while a double variable will occupy 8 bytes of memory.
You can use the sizeof operator to find the size of different types:
Example
int myInt;
float myFloat;
double myDouble;
char myChar;

printf("%lu\n", sizeof(myInt)); // 4 bytes


printf("%lu\n", sizeof(myFloat)); // 4 bytes
printf("%lu\n", sizeof(myDouble)); // 8 bytes
printf("%lu\n", sizeof(myChar)); // 1 byte
Why is it important to know?
If you create a program that occupies too much, or unnecessary memory, it can result in slow
and poor performance.
In C, you have to manage memory yourself. It is a complicated task, but is also quite powerful
when used correctly: Properly managing the computer memory optimizes the performance of
the program, so it is useful that you know how to release memory when it is no longer required
and only use as little as necessary for the task.
In previous chapters you learned about memory addresses and pointers.
Both have an importance when it comes to memory management, since it is possible to work
directly with memory through pointers.
But be careful; pointers must be handled with care, since it is possible to damage data stored
in other memory addresses.

Memory Management
Memory management is the process of handling how much memory a program uses through
allocation, reallocation and deallocation (often referred to as "freeing"). We will introduce each
of these topics in the following chapters.

C Allocate Memory
The process of reserving memory is called allocation. The way to allocate memory depends on
the type of memory.
C has two types of memory: Static memory and dynamic memory.

Static Memory
Static memory is memory that is reserved for variables before the program runs. Allocation of
static memory is also known as compile time memory allocation.
C automatically allocates memory for every variable when the program is compiled.
For example, if you create an integer array of 20 students (e.g. for a summer semester), C will
reserve space for 20 elements which is typically 80 bytes of memory (20 * 4):
Example
int students[20];
printf("%lu", sizeof(students)); // 80 bytes

But when the semester starts, it turns out that only 12 students are attending. Then you have
wasted the space of 8 unused elements.
Since you are not able to change the size of the array, you are left with unnecessary reserved
memory.
Note that the program will still run, and it is not damaged in any way. But if your program
contains a lot of this kind of code, it may run slower than it optimally could.
If you want better control of allocated memory, take a look at Dynamic Memory below.

Dynamic Memory
Dynamic memory is memory that is allocated after the program starts running. Allocation of
dynamic memory can also be referred to as runtime memory allocation.
Unlike with static memory, you have full control over how much memory is being used at any
time. You can write code to determine how much memory you need and allocate it.
Dynamic memory does not belong to a variable, it can only be accessed with pointers.
To allocate dynamic memory, you can use the malloc() or calloc() functions. It is necessary to
include the <stdlib.h> header to use them. The malloc() and calloc() functions allocate some
memory and return a pointer to its address.
int *ptr1 = malloc(size);
int *ptr2 = calloc(amount, size);
The malloc() function has one parameter, size, which specifies how much memory to allocate,
measured in bytes.
The calloc() function has two parameters:
 amount - Specifies the amount of items to allocate
 size - Specifies the size of each item measured in bytes
Note: The data in the memory allocated by malloc() is unpredictable. To avoid unexpected
values, make sure to write something into the memory before reading it.
Unlike malloc(), the calloc() function writes zeroes into all of the allocated memory. However,
this makes calloc() slightly less efficient.
The best way to allocate the right amount of memory for a data type is to use
the sizeof operator:
int *ptr1, *ptr2;
ptr1 = malloc(sizeof(*ptr1));
ptr2 = calloc(1, sizeof(*ptr2));
Be careful sizeof(*ptr1) tells C to measure the size of the data at the address. If you forget
the * and write sizeof(ptr1) instead, it will measure the size of the pointer itself, which is the
(usually) 8 bytes that are needed to store a memory address.
Note: The sizeof operator cannot measure how much dynamic memory is allocated. When
measuring dynamic memory, it only tells you the size of the data type of the memory. For
example, if you reserve space for 5 float values, the sizeof operator will return 4, which is the
number of bytes needed for a single float value.
Let's use dynamic memory to improve the students example above.
As noted previously, we cannot use sizeof to measure how much memory was allocated, we
have to calculate that by multiplying the amount of items by the size of the data type:
Example
int *students;
int numStudents = 12;
students = calloc(numStudents, sizeof(*students));
printf("%d", numStudents * sizeof(*students)); // 48 bytes

Notes
When working with dynamic memory allocation, you should also check for errors and free
memory at the end of the program. You will learn more about this in the next chapters.

Stack Memory
For completeness, it is worth mentioning stack memory. Stack memory is a type of dynamic
memory which is reserved for variables that are declared inside functions. Variables declared
inside a function use stack memory rather than static memory.
When a function is called, stack memory is allocated for the variables in the function. When the
function returns the stack memory is freed.
It is good to be aware of stack memory to be able to handle the memory usage of nested
function calls and recursion. Recursion that repeats itself too many times may take up too much
stack memory. When that happens it is called a stack overflow.
C Access Memory

Access Dynamic Memory


Dynamic memory behaves like an array, with its data type specified by the type of the pointer.
As with arrays, to access an element in dynamic memory, refer to its index number:
ptr[0] = 12;
You can also dereference the pointer to access the first element:
*ptr = 12;
Example
Read from and write to dynamic memory:
// Allocate memory
int *ptr;
ptr = calloc(4, sizeof(*ptr));

// Write to the memory


*ptr = 2;
ptr[1] = 4;
ptr[2] = 6;

// Read from the memory


printf("%d\n", *ptr);
printf("%d %d %d", ptr[1], ptr[2], ptr[3]);

A note about data types


Dynamic memory does not have its own data type, it is just a sequence of bytes. The data in the
memory can be interpreted as a type based on the data type of the pointer.
In this example a pointer to four bytes can be interpreted as one int value (4 bytes) or as an
array of 4 char values (1 byte each).
Example
int *ptr1 = malloc(4);
char *ptr2 = (char*) ptr1;
ptr1[0] = 1684234849;
printf("%d is %c %c %c %c", *ptr1, ptr2[0], ptr2[1], ptr2[2], ptr2[3]);

C Reallocate Memory
Reallocate Memory
If the amount of memory you reserved is not enough, you can reallocate it to make it larger.
Reallocating reserves a different (usually larger) amount of memory while keeping the data that
was stored in it.
You can change the size of allocated memory with the realloc() function.
The realloc() function takes two parameters:
int *ptr2 = realloc(ptr1, size);
 The first parameter is a pointer to the memory that is being resized.
 The second parameter specifies the new size of allocated memory, measured in bytes.
The realloc() function tries to resize the memory at ptr1 and return the same memory address. If
it cannot resize the memory at the current address then it will allocate memory at a different
address and return the new address instead.
Note: When realloc() returns a different memory address, the memory at the original address is
no longer reserved and it is not safe to use. When the reallocation is done it is good to assign
the new pointer to the previous variable so that the old pointer cannot be used accidentally.
Example
Increase the size of allocated memory:
int *ptr1, *ptr2, size;

// Allocate memory for four integers


size = 4 * sizeof(*ptr1);
ptr1 = malloc(size);

printf("%d bytes allocated at address %p \n", size, ptr1);

// Resize the memory to hold six integers


size = 6 * sizeof(*ptr1);
ptr2 = realloc(ptr1, size);

printf("%d bytes reallocated at address %p \n", size, ptr2);

NULL Pointer & Error Checking


The realloc() function returns a NULL pointer if it is not able to allocate more memory. This is
very unlikely, but it is worth keeping in mind when you need your code to be failproof.
The following example checks whether realloc() is able to resize the memory or not, by checking
for a NULL pointer:
Example
Check for a NULL pointer:
int *ptr1, *ptr2;

// Allocate memory
ptr1 = malloc(4);

// Attempt to resize the memory


ptr2 = realloc(ptr1, 8);
// Check whether realloc is able to resize the memory or not
if (ptr2 == NULL) {
// If reallocation fails
printf("Failed. Unable to resize memory");
} else {
// If reallocation is sucessful
printf("Success. 8 bytes reallocated at address %p \n", ptr2);
ptr1 = ptr2; // Update ptr1 to point to the newly allocated memory
}
Note: You should always include error checking (if pointer == NULL) when allocating memory.
Note: You should also always free, or release, allocated memory when you are done using it.
This is important to make sure that your program behaves as expected, but it will also make it
more maintainable and efficient.
To free memory, simply use the free() function:
Example
Free allocated memory:
// Free allocated memory
free(ptr1);
You will learn more about how to free allocated memory and why this is important in the next
chapter.

C Deallocate Memory
Deallocate (free) Memory
When you no longer need a block of memory you should deallocate it. Deallocation is also
referred to as "freeing" the memory.
Dynamic memory stays reserved until it is deallocated or until the program ends.
Once the memory is deallocated it can be used by other programs or it may even be allocated
to another part of your program.

Free Memory
To deallocate memory, use the free() function:
free(pointer);
The pointer parameter is a pointer to the address of the memory to be deallocated:
int *ptr;
ptr = malloc(sizeof(*ptr));

free(ptr);
ptr = NULL;
It is considered a good practice to set a pointer to NULL after freeing memory so that you
cannot accidentally continue using it.
If you continue using memory after it has been freed you may corrupt data from other programs
or even another part of your own program.
Example
A working example including error checking and freeing:
int *ptr;
ptr = malloc(sizeof(*ptr)); // Allocate memory for one integer

// If memory cannot be allocated, print a message and end the main()


function
if (ptr == NULL) {
printf("Unable to allocate memory");
return 1;
}

// Set the value of the integer


*ptr = 20;

// Print the integer value


printf("Integer value: %d\n", *ptr);

// Free allocated memory


free(ptr);

// Set the pointer to NULL to prevent it from being accidentally used


ptr = NULL;

Memory Leaks
A memory leak happens when dynamic memory is allocated but never freed.
If a memory leak happens in a loop or in a function that is called frequently it could take up too
much memory and cause the computer to slow down.
There is a risk of a memory leak if a pointer to dynamic memory is lost before the memory can
be freed. This can happen accidentally, so it is important to be careful and keep track of pointers
to dynamic memory.
Here are some examples of how a pointer to dynamic memory may be lost.
Example 1
The pointer is overwritten:
int x = 5;
int *ptr;
ptr = calloc(2, sizeof(*ptr));
ptr = &x;
In this example, after the pointer is changed to point at x, the memory allocated by calloc() can
no longer be accessed.
Example 2
The pointer exists only inside a function:
void myFunction() {
int *ptr;
ptr = malloc(sizeof(*ptr));
}

int main() {
myFunction();
printf("The function has ended");
return 0;
}
In this example, the memory that was allocated inside of the function remains allocated after the
function ends but it cannot be accessed anymore. One way to prevent this problem is to free the
memory before the function ends.
Example 3
The pointer gets lost when reallocation fails:
int* ptr;
ptr = malloc(sizeof(*ptr));
ptr = realloc(ptr, 2*sizeof(*ptr));
If realloc() is unable to reallocate memory it will return a pointer to NULL and the original
memory will remain reserved.
In this example, if realloc() fails then the NULL pointer is assigned to the ptr variable, overwriting
the original memory address so that it cannot be accessed anymore.

Summary
In summary, when managing memory in C, use best practices:
1. Remember to check for errors (NULL return values) to find out if memory allocation was
sucessful or not
2. Prevent memory leaks - always remember to free memory that is no longer used, or else
the program might underperform or even worse, crash if it runs out of memory
3. Set the pointer to NULL after freeing memory so that you cannot accidentally continue
using it

C Memory Management Example

Real-Life Memory Management Example


To demonstrate a practical example of dynamic memory, we created a program that can make
a list of any length.
Regular arrays in C have a fixed length and cannot be changed, but with dynamic memory we
can create a list as long as we like:
Example
struct list {
int *data; // Points to the memory where the list items are stored
int numItems; // Indicates how many items are currently in the list
int size; // Indicates how many items fit in the allocated memory
};

void addToList(struct list *myList, int item);

int main() {
struct list myList;
int amount;

// Create a list and start with enough space for 10 items


myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));

// Find out if memory allocation was successful


if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}

// Add any number of items to the list specified by the amount variable
amount = 44;
for (int i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}

// Display the contents of the list


for (int j = 0; j < myList.numItems; j++) {
printf("%d ", myList.data[j]);
}

// Free the memory when it is no longer needed


free(myList.data);
myList.data = NULL;

return 0;
}

// This function adds an item to a list


void addToList(struct list *myList, int item) {

// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
myList->size += 10;
myList->data = realloc( myList->data, myList->size * sizeof(int) );
}

// Add the item to the end of the list


myList->data[myList->numItems] = item;
myList->numItems++;
}
Pointers to structures: This example has a pointer to the structure myList. Because we are
using a pointer to the structure instead of the structure itself, we use the arrow syntax (->) to
access the structure's members.
Example explained
This example has three parts:
 A structure myList that contains a list's data
 The main() function with the program in it.
 A function addToList() which adds an item to the list
The myList structure
The myList structure contains all of the information about the list, including its contents. It has
three members:
 data - A pointer to the dynamic memory which contains the contents of the list
 numItems - Indicates the number of items that list has
 size - Indicates how many items can fit in the allocated memory
We use a structure so that we can easily pass all of this information into a function.
The main() function
The main() function starts by initializing the list with space for 10 items:
// Create a list and start with enough space for 10 items
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));
myList.numItems is set to 0 because the list starts off empty.
myList.size keeps track of how much memory is reserved. We set it to 10 because we will
reserve enough memory for 10 items.
We then allocate the memory and store a pointer to it in myList.data.
Then we include error checking to find out if memory allocation was successful:
// Find out if memory allocation was successful
if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}
If everything is fine, a loop adds 44 items to the list using the addToList() function:
// Add any number of items to the list specified by the amount variable
amount = 44;
int i;
for (i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}
In the code above, &myList is a pointer to the list and i + 1 is a number that we want to add to
the list. We chose i + 1 so that the list would start at 1 instead of 0. You can choose any number
to add to the list.
After all of the items have been added to the list, the next loop prints the contents of the list.
// Display the contents of the list
int j;
for (j = 0; j < myList.numItems; j++) {
printf("%d ", myList.data[j]);
}
When we finish printing the list we free the memory to prevent memory leaks.
// Free the memory when it is no longer needed
free(myList.data);
myList.data = NULL;
The addToList() function
Our addToList() function adds an item to the list. It takes two parameters:
void addToList(struct list *myList, int item)
1. A pointer to the list.
2. The value to be added to the list.
The function first checks if the list is full by comparing the number of items in the list to the size
of the list. If the list is full then it reallocates the memory to fit 10 more items:
// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
myList->size += 10;
myList->data = realloc( myList->data, myList->size * sizeof(int) );
}
Finally, the function adds the item to the end of list. The index at myList->numItems is always at
the end of the list because it increases by 1 each time a new item is added.
// Add the item to the end of the list
myList->data[myList->numItems] = item;
myList->numItems++;

Final Program

#include <stdio.h>
//#include <stdlib.h> >

struct list {
int *data; // Points to the memory where the list items are stored
int numItems; // Indicates how many items are currently in the list
int size; // Indicates how many items fit in the allocated memory
};

void addToList(struct list *myList, int item);

// This function adds an item to a list


void addToList(struct list *myList, int item) {

// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
myList->size += 10;
myList->data = realloc( myList->data, myList->size * sizeof(int) );
}

// Add the item to the end of the list


myList->data[myList->numItems] = item;
myList->numItems++;
}

int main() {
struct list myList;
int amount;

// Create a list and start with enough space for 10 items


myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));

// Find out if memory allocation was successful


if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}

// Add any number of items to the list specified by the amount variable
amount = 44;
int i;
for (i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}

// Display the contents of the list


for (i = 0; i < myList.numItems; i++) {
printf("%d ", myList.data[i]);
}

// Free the memory when it is no longer needed


free(myList.data);
myList.data = NULL;
printf("\n T h e E n d");
return 0;
}
IList

/* IList: list of integer */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TRUE 1
#define FALSE 0
#define FN "SCROOL.INP"
#define ENDSTR '\0'
#define NL() printf("\n")
#define Reads(x) fscanf(f, "%s", &x)
#define Int(c) (c)-'0'
#define Digit(c) (c)-'0'
#define Char(x) (x)+'0'
#define SIZE 16
#define ROWSIZE 16

typedef struct {
int *Data;
int Len;
int Id;
} IList;

void Go() {
printf(" ? ");
char c = getchar();
if (c == 10) return; // ENTER
if (c == '.') exit(0);
}

void Init(IList d) {
d.Data = malloc(SIZE*sizeof(int));
d.Len = 16; // Id = 0..15
d.Id = 0;
}

int Ins(IList *d, int x) {


if (d->Id == d->Len-1) {
d->Len += SIZE;
d->Data = realloc(d->Data, d->Len* sizeof(int));
}
d->Data[d->Id] = x;
++d->Id;
}

void Print(IList d) {
int i;
for(i = 0; i < d.Id; ++i)
printf(" %d", d.Data[i]);
}
void Run() {
IList d;
Init(d);
int x;
for (x = 1; x <= 10; ++x) Ins(&d, x);
printf("\n--------\n");
Print(d);

for (x = 11; x <= 30; ++x) Ins(&d, x);


printf("\n--------\n");
Print(d);

main() {
Run();
printf("\n T h e E n d");
return 0;
}

Why do we reserve 10 items at a time?


Optimizing is a balancing act between memory and performance. Even though we may be
allocating some memory that we are not using, reallocating memory too frequently can be
inefficient. There is a balance between allocating too much memory and allocating memory too
frequently.
We chose the number 10 for this example, but it depends on how much data you expect and
how often it changes. For example, if we know beforehand that we are going to have exactly 44
items then we can allocate memory for exactly 44 items and only allocate it once.

Complete stdlib Reference


For a complete reference of memory management functions and other functions found in the
standard library, go to our C <stdlib.h> Library Reference.

C Keywords
C Keywords
A list of useful C keywords can be found in the table below.
Keyword Description

break Breaks out of a loop or a switch block

case Marks a block of code in switch statements

char A data type that can store a single character

const Defines a variable or parameter as a constant (unchangeable)

continue Continues to the next iteration of a loop

default Specifies the default block of code in a switch statement


do Used together with while to create a do/while loop

double A data type that is usually 64 bits long which can store fractional
numbers

else Used in conditional statements

enum Declares an enumerated type

float A data type that is usually 32 bits long which can store fractional
numbers

for Creates a for loop

goto Jumps to a line of code specified by a label

if Makes a conditional statement

int A data type that is usually 32 bits long which can store whole
numbers

long Ensures that an integer is at least 32 bits long (use long long to
ensure 64 bits)

return Used to return a value from a function

short Reduces the size of an integer to 16 bits

signed Specifies that an int or char can represent both positive and
negative values (for int this is the default so the keyword is not
usually necessary)

sizeof An operator that returns the amount of memory occupied by a


variable or data type

static Specifies that a variable in a function keeps its value after the
function ends

struct Defines a structure

switch Selects one of many code blocks to be executed

typedef Defines a custom data type

unsigned Specifies that an int or char should only represent positive


values which allows for storing numbers up to twice as large

void Indicates a function that does not return a value or specifies a


pointer to a data with an unspecified type

while Creates a while loop


C stdio (stdio.h) Library
C stdio Functions
The <stdio.h> header provides a variety of functions for input, output and file handling.
A list of all stdio functions can be found in the table below:
Function Description

fclose() Closes a file

feof() Returns a true value when the position indicator has reached the
end of the file

ferror() Returns a true value if a recent file operation had an error

fgetc() Returns the ASCII value of a character in a file and advances the
position indicator

fgets() Reads a line from a file and advances the position indicator

fopen() Opens a file and returns a file pointer for use in file handling
functions

fprintf() Writes a formatted string into a file

fputc() Writes a character into a file and advances the position indicator

fputs() Writes a string into a file and advances the position indicator

fread() Reads data from a file and writes it into a block of memory

fscanf() Reads formatted data from a file and writes it into a number of
memory locations

fseek() Moves the position indicator of a file pointer

ftell() Returns the value of the position indicator of a file pointer

fwrite() Writes data from a block of memory into a file

getc() The same as fgetc()

getchar() Reads one character of user input and returns its ASCII value

printf() Writes a formatted string to the console

putc() The same as fputc()

putchar() Outputs a single character to the console

puts() Outputs a string to the console


remove() Deletes a file

rename() Changes the name of a file

rewind() Moves the position indicator to the beginning of the file

scanf() Reads formatted data from user input and writes it into a number
of memory locations

snprintf() Writes a formatted string into a char array (memory-safe)

sprintf() Writes a formatted string into a char array

sscanf() Reads a formatted string from a char array and writes it into a
number of memory locations

C stdlib (stdlib.h) Library


C stdlib Functions
The <stdlib.h> header (standard library) provides a variety of commonly used functions.
Function Description

abs() Return the absolute (positive) value of a whole number

atof() Return a double value from a string representation of a number

atoi() Return an int value from a string representation of a whole


number

atol() Return a long int value from a string representation of a whole


number

atoll() Return a long long int value from a string representation of a


whole number

calloc() Allocate dynamic memory and fill it with zeroes

div() Return the quotient and remainder of an integer division


div_t result = div(a, 10);

printf("%d / %d = %d \n", a, b, result.quot);


printf("Remainder: %d \n", result.rem);

exit() End the program

free() Deallocate dynamic memory

malloc() Allocate dynamic memory


qsort() Sort the contents of an array

rand() Generate a random integer

realloc() Reallocate dynamic memory

srand() Initialize the random number generator

C string (string.h) Library


C string Functions
The <string.h> library has many functions that allow you to perform tasks on strings.
A list of all string functions can be found in the table below:
Function Description

memchr() Returns a pointer to the first occurrence of a value in a block of


memory

memcmp() Compares two blocks of memory to determine which one


represents a larger numeric value

memcpy() Copies data from one block of memory to another

memmove() Copies data from one block of memory to another accounting for
the possibility that the blocks of memory overlap

memset() Sets all of the bytes in a block of memory to the same value

strcat() Appends one string to the end of another

strchr() Returns a pointer to the first occurrence of a character in a string

strcmp() Compares the ASCII values of characters in two strings to


determine which string has a higher value

strcoll() Compares the locale-based values of characters in two strings


to determine which string has a higher value

strcpy() Copies the characters of a string into the memory of another


string

strcspn() Returns the length of a string up to the first occurrence of one of


the specified characters

strerror() Returns a string describing the meaning of an error code

strlen() Return the length of a string

strncat() Appends a number of characters from a string to the end of


another string

strncmp() Compares the ASCII values of a specified number of characters


in two strings to determine which string has a higher value

strncpy() Copies a number of characters from one string into the memory
of another string

strpbrk() Returns a pointer to the first position in a string which contains


one of the specified characters

strrchr() Returns a pointer to the last occurrence of a character in a string

strspn() Returns the length of a string up to the first character which is


not one of the specified characters

strstr() Returns a pointer to the first occurrence of a string in another


string

strtok() Splits a string into pieces using delimiters

strxfrm() Convert characters in a string from ASCII encoding to the


encoding of the current locale

C math (math.h) Library


C Math Functions
The <math.h> library has many functions that allow you to perform mathematical tasks on
numbers.
Function Description

acos(x) Returns the arccosine of x, in radians

acosh(x) Returns the hyperbolic arccosine of x

asin(x) Returns the arcsine of x, in radians

asinh(x) Returns the hyperbolic arcsine of x

atan(x) Returns the arctangent of x as a numeric value between -PI/2


and PI/2 radians

atan2(y, x) Returns the angle theta from the conversion of rectangular


coordinates (x, y) to polar coordinates (r, theta)

atanh(x) Returns the hyperbolic arctangent of x

cbrt(x) Returns the cube root of x


ceil(x) Returns the value of x rounded up to its nearest integer

copysign(x, y) Returns the first floating point x with the sign of the second
floating point y

cos(x) Returns the cosine of x (x is in radians)

cosh(x) Returns the hyperbolic cosine of x

exp(x) Returns the value of Ex

exp2(x) Returns the value of 2x

expm1(x) Returns ex-1

erf(x) Returns the value of the error function at x

erfc(x) Returns the value of the complementary error function at x

fabs(x) Returns the absolute value of x

fdim(x) Returns the positive difference between x and y

floor(x) Returns the value of x rounded down to its nearest integer

fma(x, y, z) Returns x*y+z without losing precision

fmax(x, y) Returns the highest value of a floating x and y

fmin(x, y) Returns the lowest value of a floating x and y

fmod(x, y) Returns the floating point remainder of x/y

frexp(x, y) With x expressed as m*2n, returns the value of m (a value


between 0.5 and 1.0) and writes the value of n to the memory
at the pointer y

hypot(x, y) Returns sqrt(x2 +y2) without intermediate overflow or underflow

ilogb(x) Returns the integer part of the floating-point base logarithm of


x

ldexp(x, y) Returns x*2y

lgamma(x) Returns the logarithm of the absolute value of the gamma


function at x

llrint(x) Rounds x to a nearby integer and returns the result as a long


long integer

llround(x) Rounds x to the nearest integer and returns the result as a


long long integer

log(x) Returns the natural logarithm of x

log10(x) Returns the base 10 logarithm of x

log1p(x) Returns the natural logarithm of x+1

log2(x) Returns the base 2 logarithm of the absolute value of x

logb(x) Returns the floating-point base logarithm of the absolute value


of x

lrint(x) Rounds x to a nearby integer and returns the result as a long


integer

lround(x) Rounds x to the nearest integer and returns the result as a


long integer

modf(x, y) Returns the decimal part of x and writes the integer part to the
memory at the pointer y

nan(s) Returns a NaN (Not a Number) value

nearbyint(x) Returns x rounded to a nearby integer

nextafter(x, y) Returns the closest floating point number to x in the direction


of y

nexttoward(x, Returns the closest floating point number to x in the direction


y) of y

pow(x, y) Returns the value of x to the power of y

remainder(x, Return the remainder of x/y rounded to the nearest integer


y)

remquo(x, y, Calculates x/y rounded to the nearest integer, writes the result
z) to the memory at the pointer z and returns the remainder.

rint(x) Returns x rounded to a nearby integer

round(x) Returns x rounded to the nearest integer

scalbln(x, y) Returns x*Ry (R is usually 2)

scalbn(x, y) Returns x*Ry (R is usually 2)

sin(x) Returns the sine of x (x is in radians)

sinh(x) Returns the hyperbolic sine of x


sqrt(x) Returns the square root of x

tan(x) Returns the tangent of x (x is in radians)

tanh(x) Returns the hyperbolic tangent of x

tgamma(x) Returns the value of the gamma function at x

trunc(x) Returns the integer part of x


C ctype (ctype.h) Library

C ctype Functions
The <ctype.h> header provides many functions for classifying and modifying characters.
Function Description

isalnum() Checks whether a character is alphanumeric

isalpha() Checks whether a character is a letter

isblank() Checks whether a character is a space or tab

iscntrl() Checks whether a character is a control character

isdigit() Checks whether a character is a decimal digit

isgraph() Checks whether a character has a graphical representation

islower() Checks whether a character is a lowercase letter

isprint() Checks whether a character is a printable character

ispunct() Checks whether a character is a punctuation character

isspace() Checks whether a character is a whitespace character

isupper() Checks whether a character is an uppercase letter

isxdigit() Checks whether a character is a hexadecimal digit

tolower() Returns a lowercase version of a character

toupper() Returns an uppercase version of a character

You might also like