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 :
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
}
Syntax Explained
myFunction() is the name of the function
void means that the function does not have a return value.
You will learn more about return values later in the next
chapter
Inside the function (the body), add code that defines what
the function should do
Call a Function
Declared functions are not executed immediately. They are
"saved for later use", and will be executed when they are
called.
To call a function, write the function's name followed by two
parentheses () and a semicolon ;
In the following example, myFunction() is used to print a text
(the action), when it is called :
Example : Inside main, call myFunction() :
// Create a function
void myFunction() {
printf("I just got executed!");
}
int main() {
myFunction(); // call the function
return 0;
}
// Outputs "I just got executed!"
A function can be called multiple times :
Example :
void myFunction() {
printf("I just got executed!");
}
int main() {
myFunction();
myFunction();
myFunction();
return 0;
}
// I just got executed!
// I just got executed!
// I just got executed!
Parameters and Arguments
Information can
be passed to functions as a parameter.
Parameters act as variables inside the function.
Parameters are specified after the function name, inside the
parentheses. You can add as many parameters as you want, just
separate them with a comma :
Syntax :
returnType functionName(parameter1, parameter2,
parameter3) {
// code to be executed
}
The following function that takes a string of characters with
name as parameter. When the function is called, we pass along
a name, which is used inside the function to print "Hello" and
the name of each person.
Example :
void myFunction(char name[]) {
printf("Hello %s\n", name);
}
int main() {
myFunction("Liam");
myFunction("Jenny");
myFunction("Anja");
return 0;
}
// Hello Liam
// Hello Jenny
// Hello Anja
When a parameter is passed to the function, it is called an
argument. So, from the example above: name is a parameter,
while Liam, Jenny and Anja are arguments.
Multiple Parameters
Inside the function, you can add as many parameters as you
want.
Example :
void myFunction(char name[], int age) {
printf("Hello %s. You are %d years old.\n", name,
age);
}
int main() {
myFunction("Liam", 3);
myFunction("Jenny", 14);
myFunction("Anja", 30);
return 0;
}
// Hello Liam. You are 3 years old.
// Hello Jenny. You are 14 years old.
// Hello Anja. You are 30 years old.
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.
Pass Arrays as Function Parameters
You can also pass arrays to a function :
void myFunction(int myNumbers[5]) {
for (int i = 0; i < 5; i++) {
printf("%d\n", myNumbers[i]);
}
}
int main() {
int myNumbers[5] = {10, 20, 30, 40, 50};
myFunction(myNumbers);
return 0;
}
Example Explained
Note that when you are working with multiple parameters, the
function call 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]).
have the same number of arguments as there are parameters,
and the arguments must be passed in the same order.
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 :
int myFunction(int x) {
return 5 + x;
}
int main() {
printf("Result is: %d", myFunction(3));
return 0;
}
// Outputs 8 (5 + 3)
This example returns the sum of a function with two
parameters :
int myFunction(int x, int y) {
return x + y;
}
int main() {
printf("Result is: %d",
myFunction(5, 3));
return 0;
}
// Outputs 8 (5 + 3)
You can also store the result in a variable :
int myFunction(int x, int y) {
return x + y;
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
Function Declaration and Definition
You just learned that you can create and call a function in the
following way :
Example
// Create a function
void myFunction() {
printf("I just got executed!");
}
int main() {
myFunction(); // call the function
return 0;
}
Output : I just got executed!
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 :
// Function declaration
void myFunction();
// The main method
int main() {
myFunction(); //call the function
return 0;
}
// Function definition
void myFunction() {
printf("I just got executed!");
}
Another Example
int myFunction(int x, int y) {
return x + y;
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
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 :
// Function declaration
void myFunction();
// The main method
int main() {
myFunction(); //call the function
return 0;
}
// Function definition
void myFunction() {
printf("I just got executed!");
}
Another Example
int myFunction(int x, int y) {
return x + y;
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
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 :
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.
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 :
printf("%f", sqrt(16));
Output : 4.000000
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 :
printf("%f", ceil(1.4));
printf("%f", floor(1.4));
Output : 2.000000
1.000000
Power
The pow() function returns the value of x to the power of y
(xy) :
printf("%f", pow(4, 3));
Output : 64.000000
Other Math Functions
A list of other popular math functions (from the <math.h>
library) can be found in the table below :
Function Description
abs(x) Returns the absolute value of x
acos(x) Returns the arccosine of x
asin(x) Returns the arcsine of x
atan(x) Returns the arctangent of x
cbrt(x) Returns the cube root of x
cos(x) Returns the cosine of x
exp(x) Returns the value of E^x
sin(x)
Returns the sine of x (x is in radians)
tan(x) Returns the tangent of an angle
File Handling
In C, you can create, open, read, and write to files by declaring
a pointer of type FILE, and use the fopen() function :
FILE *fptr
fptr = fopen(filename, mode);
FILE is basically a data type, and we need to create a pointer
variable to work with it (fptr). For now, this line is not
important. It's just something you need when working with
files.
To actually open a file, use the fopen() function, which takes
two parameters :
Parameter Description
filename The name of the actual file you want to
open (or create), like filename.txt
mode A single character, which represents what
you want to do with the file (read, write or
append) :
w - Writes to a file
a - Appends new data to a file
r - Reads from a file
Create a File
To create a file, you can use the w mode inside the fopen()
function.
The w mode is used to write to a file. However, if the file does
not exist, it will create one for you.
Example
FILE *fptr;
// Create a file
fptr = fopen("filename.txt", "w");
// Close the file
fclose(fptr);
Note : The file is created in the same directory as your other
C files, if nothing else is specified.
On our computer, it looks like this :
Tip : If you want to create the file in a specific folder, just
provide an absolute path :
fptr = fopen("C:\directoryname\filename.txt", "w");
Closing the file
Did you notice the fclose() function in our example above?
This will close the file when we are done with it.
It is considered as good practice, because it makes sure that :
Changes are saved properly
Other programs can use the file (if you want)
Clean up unnecessary memory space
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 fprint() function and add the
pointer variable (fptr in our example) and some text.
Example
FILE *fptr;
// Open a file in writing mode
fptr = fopen("filename.txt", "w");
// Write some text to the file
fprintf(fptr, "Some text");
// Close the file
fclose(fptr);
As a result, when we open the file on our computer, it looks like
this :
Note : If you write to a file that already exists, the old content is
deleted, and the new content is inserted. This is important to
know, as you might accidentally erase existing content.
For example :
fprintf(fptr, "Hello World!");
As a result, when we open the file on our computer, it says
"Hello World!" instead of "Some text" :
Append Content To a File
If you want to add content to a file without deleting the old
content, you can use the a mode.
The a mode appends content at the end of the file.
Example
FILE *fptr;
// Open a file in append mode
fptr = fopen("filename.txt", "a");
// Append some text to the file
fprintf(fptr, "\nHi everybody!");
// Close the file
fclose(fptr);
As a result, when we open the file on our computer, it looks like
this :
Note : Just like with the w mode; if the file does not exist,
the a mode will create a new file with the "appended"
content.
Read a File
Earlier we wrote a file using w and a modes inside the fopen()
function.
.
To read from a file, you can use the r mode
Example
FILE *fptr;
// Open a file in read mode
fptr = fopen("filename.txt", "r");
This will make the filename.txt opened for reading.
It requires a little bit of work to read a file in C. Hang in there!
We will guide you step-by-step.
Next, we need to create a string that should be big enough to
store the content of the file.
For example, let's create a string that can store up to 100
characters:
FILE *fptr;
// Open a file in read mode
fptr = fopen("filename.txt", "r");
// Store the content of the file
char myString[100];
In order to read the content of filename.txt, we can use the
fgets() function.
The fgets() function takes three parameters:
Example
fgets(myString, 100, fptr);
1. The first parameter specifies where to store the file
content, which will be in the myString array we just
created.
2. The second parameter specifies the maximum size of data
to read, which should match the size of myString (100).
3. The third parameter requires a file pointer that is used to
read the file (fptr in our example).
Now, we can print the string, which will output the content of
the file.
Example Output : Hello World!
FILE *fptr;
// Open a file in read mode
fptr = fopen("filename.txt", "r");
// Store the content of the file
char myString[100];
// Read the content and store it inside myString
fgets(myString, 100, fptr);
// Print the file content
printf("%s", myString);
// Close the file
fclose(fptr);
Note : The fgets function only reads the first line of the file.
If you remember, there were two lines of text in
filename.txt.
To read every line of the file, you can use a while loop.
Example
FILE *fptr;
// Open a file in read mode
fptr = fopen("filename.txt", "r");
// Store the content of the file
char myString[100];
// Read the content and print it
while(fgets(myString, 100, fptr)) {
printf("%s", myString);
}
// Close the file
fclose(fptr);
Output : Hello World!
Hi everybody!
Good Practice
If you try to open a file for reading that does not
exist, the fopen() function will return NULL.
Note : As a good practice, we can use an if statement to test
for NULL, and print some text instead (when the file
does not exist).
Example
FILE *fptr;
// Open a file in read mode
fptr = fopen("loremipsum.txt", "r");
// Print some text if the file does not exist
if(fptr == NULL) {
printf("Not able to open the file.");
}
// Close the file
fclose(fptr);
If the file does not exist, the following text is printed :
Not able to open the file.
With this in mind, we can create a more sustainable
code if we use our "read a file" example above again
Structures
Structures (also called structs) are a way to group several
related variables into one place. Each variable in the structure
is known as a member of the structure
.
Unlike an array, a structure can contain many different data
types (int, float, char, etc.).
Create a Structure
You can create a structure by using the struct keyword and
declare each of its members inside curly braces :
struct MyStructure { // Structure declaration
int myNum; // Member (int variable)
char myLetter; // Member (char variable)
}; // End the structure with a semicolon
To access the structure, you must create a variable of it.
Use the struct keyword inside the main() method, followed by
the name of the structure and then the name of the structure
variable.
Create a struct variable with the name "s1":
struct myStructure {
int myNum;
char myLetter;
};
int main() {
struct myStructure s1;
return 0;
}
Access Structure Members
To access members of a structure, use the dot syntax (.) :
Example
// Create a structure called myStructure
struct myStructure {
int myNum;
char myLetter;
};
int main() {
// Create a structure variable of myStructure called
s1
struct myStructure s1;
// Assign values to members of s1
s1.myNum = 13;
s1.myLetter = 'B';
// Print values
printf("My number: %d\n", s1.myNum);
printf("My letter: %c\n", s1.myLetter);
return 0;
}
Now you can easily create multiple structure variables with
different values, using just one structure.
Example
// Create different struct variables
struct myStructure s1;
struct myStructure s2;
// Assign values to different struct variables
s1.myNum = 13;
s1.myLetter = 'B';
s2.myNum = 20;
s2.myLetter = 'C';
What About Strings in Structures?
Remember that strings in C are actually an array of characters,
and unfortunately, you can't assign a value to an array like this :
Example
struct myStructure {
int myNum;
char myLetter;
char myString[30]; // String
};
int main() {
struct myStructure s1;
// Trying to assign a value to the string
s1.myString = "Some text";
// Trying to print the value
printf("My string: %s", s1.myString);
return 0;
}
An error will occur :
prog.c:12:15: error: assignment to expression with
array type
However, there is a solution for this! You can use the strcpy()
function and assign the value to s1.myString, like this :
Example
struct myStructure {
int myNum;
char myLetter;
char myString[30]; // String
};
int main() {
struct myStructure s1;
// Assign a value to the string using the strcpy
function
strcpy(s1.myString, "Some text");
// Print the value
printf("My string: %s", s1.myString);
return 0;
}
Output : 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.
struct myStructure { Output : 30 C Something else
int myNum;
char myLetter;
char myString[30];
};
int main() {
// Create a structure variable and assign values to it
struct myStructure s1 = {13, 'B', "Some text"};
// Modify values
s1.myNum = 30;
s1.myLetter = 'C';
strcpy(s1.myString, "Something else");
// Print values
printf("%d %c %s", s1.myNum, s1.myLetter, s1.myString);
return 0;
}
Modifying values are especially useful when you copy structure
values :
Example
// Create a structure variable and assign values to it
struct myStructure s1 = {13, 'B', "Some text"};
// Create another structure variable
struct myStructure s2;
// Copy s1 values to s2
s2 = s1;
// Change s2 values
s2.myNum = 30;
s2.myLetter = 'C';
strcpy(s2.myString, "Something else");
// Print values
printf("%d %c %s\n", s1.myNum, s1.myLetter, s1.myString);
printf("%d %c %s\n", s2.myNum, s2.myLetter, s2.myString);
Output : 13 B Some text
30 C Something else
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.
Real Life Example
Use a structure to store different information about Cars :
Example
struct Car {
char brand[50];
char model[50];
int year;
};
int main() {
struct Car car1 = {"BMW", "X5", 1999};
struct Car car2 = {"Ford", "Mustang", 1969};
struct Car car3 = {"Toyota", "Corolla", 2011};
printf("%s %s %d\n", car1.brand, car1.model, car1.year);
printf("%s %s %d\n", car2.brand, car2.model, car2.year);
printf("%s %s %d\n", car3.brand, car3.model, car3.year);
return 0;
}
Output : BMW X5 1999
Ford Mustang 1969
Toyota Corolla 2011
Enums
An enum is a special type that represents a group of constants
(unchangeable values).
To create an enum, use the enum keyword, followed by the
name of the enum, and separate the enum items with a comma.
enum Level {
LOW,
MEDIUM,
HIGH
};
Note that the last item does not need a comma.
It is not required to use uppercase, but often considered as
good practice.
Enum is short for "enumerations", which means "specifically
listed".
To access the enum, you must create a variable of it.
Inside the main() method, specify the enum keyword, followed
by the name of the enum (Level) and then the name of the
enum variable (myVar in this example):
enum Level myVar;
Now that you have created an enum variable (myVar), you can
assign a value to it.
The assigned value must be one of the items inside the enum
(LOW, MEDIUM or HIGH) :
enum Level myVar = MEDIUM;
By default, the first item (LOW) has the value 0, the second
(MEDIUM) has the value 1, etc.
If you now try to print myVar, it will output 1, which represents
MEDIUM :
int main() {
// Create an enum variable and assign a value to it
enum Level myVar = MEDIUM;
// Print the enum variable
printf("%d", myVar);
return 0;
}
Output : 1
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
Output : 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
};
Output : 6
Enum in a Switch Statement
Enums are often used in switch statements to check for
corresponding values :
enum Level {
LOW = 1,
MEDIUM,
HIGH
};
int main() {
enum Level myVar = MEDIUM;
switch (myVar) {
case 1:
printf("Low Level");
break;
case 2:
printf("Medium level");
break;
case 3:
printf("High level");
break;
}
return 0;
}
Output : Medium level
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.