C Programming
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
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
%d or %i int Try it »
%f or %F float 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() {
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
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;
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;
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;
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;
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
+= 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
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
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;
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
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."
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;
}
switch (day) {
case 6:
printf("Today is Saturday");
break;
case 7:
printf("Today is Sunday");
break;
default:
printf("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;
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)
}
}
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;
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);
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);
}
return n;
}
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};
// Outputs 25
Example
int myNumbers[] = {25, 50, 75, 100};
myNumbers[0] = 33;
printf("%d", myNumbers[0]);
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]);
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:
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;
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)
#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);
}
// 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;
}
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!";
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!
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;
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!";
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
\\ \ Backslash
The sequence \" inserts a double quote in a string:
Example
char txt[] = "We are the so-called \"Vikings\" from the north.";
\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!";
// 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];
// 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";
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;
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;
// Get and save the number AND character the user types
scanf("%d %c", &myNum, &myChar);
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];
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];
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
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
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
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.
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;
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;
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;
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};
Result:
16
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};
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};
// and so on..
Result:
50
75
Or loop through it:
Example
int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int 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};
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;
}
int main() {
myFunction();
myFunction();
myFunction();
return 0;
}
int main() {
myFunction(); // call myFunction
return 0;
}
int main() {
calculateSum(); // call the function
return 0;
}
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
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;
}
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);
}
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;
}
/*
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;
}
ADVERTISEMENT
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)
int main() {
printf("Result is: %d", myFunction(5, 3));
return 0;
}
// Outputs 8 (5 + 3)
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);
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);
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;
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;
int main() {
myFunction();
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();
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();
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();
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
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();
// Function definition
void myFunction() {
printf("I just got executed!");
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
// 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);
}
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);
}
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));
C Files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define FN "..."
#define GN "..."
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
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");
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;
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;
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;
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;
}
int main() {
// Create a structure variable of myStructure called s1
struct myStructure s1;
// 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;
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;
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;
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"};
// 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.
/*
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;
/*
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};
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;
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
};
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;
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
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
ptr1 = malloc(4);
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
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
int main() {
struct list myList;
int amount;
// 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);
}
return 0;
}
// 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) );
}
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
};
// 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) );
}
int main() {
struct list myList;
int amount;
// 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);
}
#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;
}
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);
main() {
Run();
printf("\n T h e E n d");
return 0;
}
C Keywords
C Keywords
A list of useful C keywords can be found in the table below.
Keyword Description
double A data type that is usually 64 bits long which can store fractional
numbers
float A data type that is usually 32 bits long which can store fractional
numbers
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)
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)
static Specifies that a variable in a function keeps its value after the
function ends
feof() Returns a true value when the position indicator has reached the
end of the file
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
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
getchar() Reads one character of user input and returns its ASCII value
scanf() Reads formatted data from user input and writes it into a number
of memory locations
sscanf() Reads a formatted string from a char array and writes it into a
number of memory locations
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
strncpy() Copies a number of characters from one string into the memory
of another string
copysign(x, y) Returns the first floating point x with the sign of the second
floating point y
modf(x, y) Returns the decimal part of x and writes the integer part to the
memory at the pointer 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.
C ctype Functions
The <ctype.h> header provides many functions for classifying and modifying characters.
Function Description