C++ Programming Series: Pointers (Part 3)

Pointers and Arrays are same things!

This statement might confuse you. How is this possible that pointers and arrays are same? They never looks to be same!

This post will clear this point to you. Lets get started with the code below.

int array[5] = { 3, 4, 7, 8, 12 };

//Look! We have not put square brackets
//with a number after the name of array
cout << array << endl;

What will it print? Will it print the first member of the array? No, it will print the memory address of the first member of the array.

Now, you see that there is no ampersand(&) needed for getting the memory address of the array. Don’t you think that it is something that is similar to pointers? Yeah, but this is not all!

int array[5] = { 3, 4, 7, 8, 12 };

//'pArray' is now pointed to the first member of the 'array'
int* pArray = array;

//Now, we can use 'pArray' similar to that of 'array'
cout << pArray[2] << endl; //Prints 7; same as 'array[2]'

The above code explains that pointers are actually arrays! We can have square brackets with pointers and just use it exactly as an array.

Another point to tell you that when we use a pair of empty square brackets([]) after a pointer or an array, it will still give us the memory address of the array. But when we mention the number in it, pointer or array will give us that particular value under the index.

Pointers and arrays are same things but there is only one difference between them.

An array knows that how many elements it has. If we use sizeof() method for an array, we will get right number of bytes that it occupy.

int array[5] = { 3, 4, 7, 8, 12 };

//We can use empty square brackets as well
cout << sizeof(array[]) << endl; //Prints (sizeof(int) * 5)

Note: Size of integer may be different for your device. Mine is 4 so, it will result in 20. It may result 10 as well.

A pointer never knows that how many elements it has. It may or may not be an array as well. If we use sizeof() with pointer. we will not get the right number of bytes that it occupy. A pointer do know about the size of type that it is of.

int array[5] = { 3, 4, 7, 8, 12 };
int* pArray = array;

cout << sizeof(pArray[]) << endl; //Prints 2, 4 or 8 (not true in any case)

What if we want to pass array to a function? We have never discussed that topic before. Now, there is something that I have to tell! We can’t pass array to a function! So, there you go. The topic ends.

Of course, there is a solution to this problem. We can’t pass arrays but we can pass pointers to a function. Unfortunately, we can’t get the size of array that is passed as a pointer. Therefore, we have to pass the total number of elements to the function as well.

void printIntegerArray(int* pArr, int totalElements)
{
  for(int i = 0; i < totalElements; i++)
  {
    cout << pArr[i] << endl;
  }
}

int main()
{
  int array[5] = { 3, 4, 7, 8, 12 };

  //We don't need to make any pointer
  //Pointer is just a memory address
  //So, we can pass array directly
  printIntegerArray(array, 5);

  return 0;
}

Just keep in mind, the concept that pointers are arrays but they don’t keep track of their number of elements. There are few things that are not clear. We still don’t know what happens behind that pair of square brackets with a number in it. We will discuss pointer arithmetic in the next post along with the working behind square brackets.

Exercise: Make a function that takes an integer array and prints only even numbers.

Advertisements

C++ Programming Series: References

I believe that my series is getting complex with every post being published! This has to be done because we should also be getting more complex and more logical with every topic we discuss.

Today’s topic is References. Before proceeding on, let us discuss few problems with functions. The first one is that we don’t know any methods of getting multiple outputs. The second one is that we don’t make any change in the variable that we pass into the function via parameters.

The following code expresses the second problem with functions:

void multiplyBy2(int variable)
{
  variable *= 2;
  //No returning
}

int main()
{
  int variable = 2;
  mulitplyBy2(variable); //This should change the variable's value to 4
  cout << variable << endl; //Prints 2, not 4
  return 0;
}

NOTE: We can have same names for variables having completely isolated scopes. Note that multiplyBy2 has a parameter called variable and main function also has a variable called variable. Sounds confusing!

We have a solution for that and that is, to return that variable in the function and then, put that into any variable or just call that temporary return value directly.

But we expect the method above to change the variable’s value which is not the case here! Why? Well, the point is that when we pass the variable via the parameter of the function, we are actually copying that variable into another completely new variable. This new variable has a very limited scope i.e we can only access it inside the function.

Let us discuss a very simple example of what copying is:

int value1 = 2;

int value2 = value1; //Here, value1 is copied into value2
value2*=2; //value2 is a different variable; it will not effect value1 in any case!

cout << value1 << endl; //Prints 2, not 4
cout << value2 << endl; //Prints 4

The highlighted codes shows what is actually happening in the function, multiplyBy2() in the example, given above.

How to do it in the way that we want? The answer is right inside the topic of this post: References. There is another way and that one is through Pointers which is way more complex but we will discuss it later on.

What is a reference? Reference is just another name given to the same variable. In our real life, we can have the reference case of a bird called ‘raven’. Raven is a black bird. So, people can refer to ‘raven’ by calling it as ‘black bird’. In a very similar way, variables can have references as well.

//Consider that there is a bird called 'raven'
int raven = 10;

//That 'black_bird' is a reference to 'raven' 
int& black_bird = raven;

//Now, what we do with 'black_bird' is actually,
//what we are doing with 'raven' as well and vice versa...
black_bird*=2; //Both gets 20
raven+=5; //Both gets 25

cout << raven << endl; //Prints 25
cout << black_bird << endl; //Prints 25

The highlighted line shows how to make reference to a variable. It is pretty simple; just put ampersand or ‘&’ after the type of the variable that we are going to refer to.

int& is considered a type which we can call as ‘reference to an integer’. Same will be for any type reference as well.

Time to make some change in the multiplyBy2() function!

//Notice the ampersand before the variable's name
void multiplyBy2(int& variable)
{
  variable *= 2;
}

int main()
{
  int variable = 2;
  mulitplyBy2(variable); //Now, we are not copying, we are referencing!
  cout << variable << endl; //This time, it prints 4
  return 0;
}

Now that, the second problem is solved, the first problem is solved as well. We can have multiple outputs by having more parameters to the function. These parameters are going to be references and whatever is going to be changed with these references, this change is going to happen with the actual variables which are passed as parameters in the function.

//The first two parameters represent inputs
//and the next three represent outputs
void get3TimesDivision( float number1, float number2,
float& division1, float& division2, float& division3 )
{
  division1 = number1 / number2;
  division2 = division1 / number2;
  division3 = division2 / number2;
}

int main()
{
  //Multiple Outputs using References
  float div1 = 0.0f, div2 = 0.0f, div3 = 0.0f;
  get3TimesDivision( 8.0f, 2.0f, div1, div2, div3 );

  cout << div1 << endl; //Prints 4
  cout << div2 << endl; //Prints 2
  cout << div3 << endl; //Prints 1

  return 0;
}

Note the point that where we want to have references, we cannot have constants or temporary values there. In the above case, if the parameters, number1 and number2, are references to float, we cannot pass 8.0f and 2.0f into the function. We must pass variables of type float with the respective values, into the function.

That’s all! References are a great way to deal with outputs. Just try to modify all the previous functions that we created together, to have references and not copies. Practice them very well. They are going to be used extensively!

C++ Programming Series: Headers and Prototypes (Part 2, Last)

In this post, we are going to discuss some confusions that you might have got in the previous post. You might have read #include "func.h" in that post and not #include <func.h>. Actually, both have different meanings!

If we type angle brackets (<>) instead of double quotes (“”) for func.h, the compiler will check for that file in the C++ base files directory and project specified include directory. From C++ base files, I mean those files which also includes the most commonly used iostream, math.h, string, etc, that are the files of standard C++. All these C++ standard files are header files although they may not have .h at the end of their names.

If we type double quotes as in the previous post, the compiler will check for that file in local project directory. This directory is the same directory where the IDE adds all our files to.

In a nutshell,

  • #include <file_name> – searches the file in base and project specified include directory.
  • #include “file_name” – searches the file in local project directory.

Now, we know what double quotes and angle brackets do with #include. But we actually, don’t know what #include do! #include simply, copy the codes from the file and then, paste it into that file where it is called.

This is something that we don’t need to know. What we need to know is the fact that C++ don’t allow more than one definitions. You can’t just do like that:

void func()
{
  //code here...
}

//Another time: gives error!
void func()
{
  //code here...
}

It might be possible that we include things twice or, the other and most common case is that the file that we are including, includes another file that is already included in our file! To make it clear, see the code below:

#include "a" //'a' file contains function 'func()'
#include "b" //'b' file includes file 'a'
//'func()' is defined twice
//So, gives error!

That hash(#) before the include suggests that the command after it, is a preprocessor directive and not a C++ code. These directives runs before the compilation of the actual program. There are many of these. You can check out preprocessor directives in details here.

In order to make sure that something is defined just once, you can use preprocessor directives like that:

#ifndef SOMETHING //This means 'if not defined preprocessor term called SOMETHING'
#define
  //code here
#endif //This ends the '#ifndef' statement

The above code just acts similar to the C++ if-statement that we discussed before.

SOMETHING can be anything. It can be an integer, a group of characters, a float, etc.

#define PI 3.14 //Now, PI is equal to 3.14

int main()
{
  cout << PI << endl; //We can use it as a regular double
  PI++; //Gives error; preprocessor definations are constants!
  return 0;
}

I hope that you got all of the above things. Just practice using headers and prototypes. Find errors and then, try to fix them yourself. I got a new exciting series called My Pixels where I have showcased some of my hand drawn pixel arts or sprites! Just check that out and see ya!

C++ Programming Series: Headers and Prototypes (Part 1)

Until now, we have been working with codes which are present in just a single file. We have been doing single file projects till now, in which all the codes are being typed in one file. This approach is good for tiny projects. However, when we are going to have some medium sized project to be worked on, this approach is really horrible! Imagine a file with a ten thousand lines of codes. Of course, we did all 10000 lines of codes in the form of functions but still, the infrastructure of our program is ugly and hardly, manageable now. It is less likely to be modified by some other programmer or even you. Maybe, you can do some modifications but when you leave your program for a month and then, came back to it, you would like not to read the code because it looks to be too big and lengthy!

The solution for bigger projects is to have multiple files in a project and this approach is called as multiple file project. In this approach, there are three kinds of files: the one with extension ‘.cpp’ which contains the main() function, the other with extension ‘.h’ or ‘.hpp’ which contains all the possible declarations of a group of related functions or entities, and the last one with extension ‘.cpp’ which contains all the definitions of the declarations. Creating, importing and exporting static and dynamic libraries is another topic which we will not discuss in this series.

The files with extension ‘.h’ or ‘.hpp’, are called as Header files which contains the declarations only and not the definitions. Now, the advantage of the header file is to help the programmer to know all the details of the functions that he/she want to use in his/her program without even skipping through all the enormous definitions!

The declaration of a function is often, referred to as Prototypes.

Example of a declaration of an integer:

//Declaration
extern int value0;

//'extern' is a keyword used to write declarations of variables

//Declaration and Definition
int value1;

//Declaration along with Definition and Initialization
int value2 = 15;

Example of a declaration of a function/Prototype:

//Declaration only/Prototype
int square(int value);

//Declaration along with Defination
int square(int value)
{
  return (value*value);
}

In Visual Studio, in order to have multiple file project, just create new files of approriate file extensions. Suppose that we have three files namely, main.cpp, func.h and func.cpp.

Here the codes are shown for both single and multiple file approaches using Prototypes:

Single File Project:
In main.cpp:

//Includings
#include <iostream>

//Prototypes
int square(int value);
int enterAnInt();
void printAnInt(int value);

//Main Function
int main()
{
  //Prints the square of the value given by the user
  printAnInt(square(enterAnInt()));
  return 0;
}

//Definations
int square(int value)
{
  return (value*value);
}
int enterAnInt()
{
  int value;
  cin >> value;
  return value;
}
void printAnInt(int value)
{
  cout << value << endl;
}

Multiple File Project:
In func.h:

//Includings on which the functions depends on
#include <iostream>

//Prototypes
int square(int value);
int enterAnInt();
void printAnInt(int value);

In main.cpp:

//Main Function
#include "func.h" //Including header to access all functions

int main()
{
  //Prints the square of the value given by the user
  printAnInt(square(enterAnInt()));
  return 0;
}

In func.cpp:

#include "func.h" //Including header to access all functions

//Definations
int square(int value)
{
  return (value*value);
}
int enterAnInt()
{
  int value;
  cin >> value;
  return value;
}
void printAnInt(int value)
{
  cout << value << endl;
}

That’s the basics of having multiple file projects! This approach is also a modern approach for projects bigger than tiny! Also, I will use this approach for game development and will avoid the single file approach because it increases the quality of our code and make it more readable.

Your only task is to make a simplistic multiple file project like the one above without errors. Just try to handle the errors and find there fixes on the internet. You can ask me here as well if you encounter some errors.

C++ Programming Series: Functions/Subroutines (Part 4, Last)

In the previous post, I confused you into the depth of the functions and my abstractions although, I hope that you got the concept fairly. The hint that I gave you in the previous post┬áis about the order of the functions. If you modified checkRegistrationEligibility() function by adding enterAString() and enterAnInt(), you may have got some error because checkRegistrationEligibility() function don’t know anything about enterAString() and enterAnInt() since, they are both defined as well as declared below the function. The issue with the order of the functions can be fixed but I will explain this later!

The functions with which we get father’s name, place of living and education in the previous post are very similar to each other. In fact, they are just the same with the exception to the statement being printed out!

Fortunately, there are more ways! Until now, we are just getting outputs from the functions in the form of returning values. But in many cases, it is necessary to have inputs in the functions. If you recall the first post on the topic of Functions/Subroutines, we discussed that a function takes the input, modifies it and then, outputs the modified input. We can always have the user input but there are many many cases where user input is not the solution! A pair of round brackets after the end of each function is not useless; it is for taking data into the function(inputs) or in other words, for taking parameters.

I had given you the task for creating a function which takes the user input for the number to be squared and then, returns the square of that number. Here it is done with a function that takes the input from the parameter, squares it and then, returns it.

int square( int value ) //a parameter of type 'int'
{
  return (value * value);
}

int main()
{
  //In 'square' function, we pass 5 as a parameter, giving us 25 as a return value.
  cout << square(5) << endl; //Outputs 25
  return 0;
}

This might have given you the idea of how parameters of a function works. Let us remove the three functions as described in the previous post namely, enterYourFatherName(), enterYourPlace() and enterYourEducation() and replace it with only one function!

string enterRequiredData( string required_data ) //a parameter of type string
{
  string data = "NULL";
  do
  {
    cout << "Enter your " << required_data << ": " << endl;
    data = enterAString();
    cout << "Is your " << required_data << " " << data << "?" << endl;
 
  } while (!isDataSure());

  cout << "Your " << required_data << " is " << data << "." << endl;
  return data;
}

Now, in the registrationSection() function:

void registrationSection()
{
  enterRequiredData("father\'s name");
  enterRequiredData("place of living");
  enterRequiredData("education");
}

All the other codes will remain same! You can see that a single function is doing quite a job because of the fact that it is more flexible now. The output of a function should depend on the parameters being given into it or else, the function should have no inputs/parameters at all. However, it is not necessary to use the output of a function for something else. In the codes above, we haven’t used the strings being returned by the functions inside the registrationSection(). We can store them in a separate file which is the prime purpose of registration (We will discuss about getting data into and out of a file soon).

That’s all! Function parameters are awesome! But there are still few problems that we may encounter, the first one is the order of functions and the second one is getting multiple outputs. You haven’t seen any example of multiple inputs/parameters as well. There you go!

int clamp(int value, int min, int max)
{
  if(value < min)
    return min;
  else if(value > max)
    return max;

  return value;
}

Try to code functions with multiple parameters and have fun with them!

C++ Programming Series: Functions/Subroutines (Part 3)

In the previous post, we have played with a function called checkRegistrationEligibility(). It was first, a function of return-type, void and now, bool. What is good with this, is the fact that this function is able to connect. From being connected, we mean that the data available in a limited scope of a function, can get available to that other function from which this function is called!

We can get the output from that function in the form of a boolean value. It is not necessary to collect the output of a function by having a specific variable for it. You can have a stupid line of code like 5+5; or true; without having any cout at the back! Sometimes, a function is of return-type int which returns a value 1, 0 or -1 only to indicate whether there is some error in the function or not and so, is not necessarily, taken into account.

In this post, we are not going to change even a bit of checkRegistrationEligibility() function. It is now, perfect. What we will do now, is to create another function for the next section of the registration program. But this time, we will create many small functions which will be grouped into more functions until a big function is created! If you don’t know about the checkRegistrationEligibility() function, please visit this post first!

Two very simple input functions which takes user input and then, return that input:

string enterAString()
{
  string str;
  getline(cin, str);
  return str;
}

int enterAnInt()
{
  int integer;
  cin >> integer; //Remember, getline() is for strings only!

  //the 'cin >>' causes rubbish in the input stream
  //which causes problems with getline()
  //the line below is a fix to it
  //it should be after every 'cin >>'
  cin.ignore();

  return integer;
}

Another function which makes sure than the user said ‘Yes’, ‘yes’, ‘Y’ or ‘y’ for reasons that are going to be obvious in the other functions.

bool isDataSure()
{
  string yes_or_no = enterAString();

  if (yes_or_no == "yes" || yes_or_no == "Yes" ||
    yes_or_no == "y" || yes_or_no == "Y")
    return true;

  //Remember, function stops to go further immediately after the 'return' keyword
  //So, there is no need for 'else'
  return false;
}

If you don’t know or just forgot the complex if conditions or just confused about the condition as the above one, just go through this post.

Now, three more functions for getting father’s name, place of living and education.

string enterYourFatherName()
{
  string father = "NULL";
  do
  {
    cout << "Enter your father\'s name: ";

    //If 'father' is declared inside, we can't return it from outside
    father = enterAString();

    cout << "Is your father\'s name " << father << "?" << endl;

  } while (!isDataSure()); //Remember, semi-colon is necessary after do-while-statement

  cout << "Your father\'s name is " << father << "." << endl;
  return father;
}

string enterYourPlace()
{
  string place = "NULL";
  do
  {
    cout << "Enter your place of living: ";
    place = enterAString();
    cout << "Is your place of living " << place << "?" << endl;
  } while (!isDataSure());
  cout << "Your place of living is " << place << "." << endl;
  return place;
}

string enterYourEducation()
{
  string education = "NULL";
  do
  {
    cout << "Enter your education: ";
    education = enterAString();
    cout << "Is your education " << education << "?" << endl;
  } while (!isDataSure());
  cout << "Your education is " << education << "." << endl;
  return education;
}

Finally, a function to have all the three functions and the main function is all set!

void registerationSection()
{
  //To keep some distance from the first section
  cout << endl;

  //Discarding the returning strings for now...
  //It can be used for various purposes!
  enterYourFatherName();
  enterYourPlace();
  enterYourEducation();
}

int main()
{
  //Instead of making a 'bool' variable and then, storing the value received
  //by checkRegistrationEligibility() method, how about using it directly?

  if (checkRegistrationEligibility() == true)
    registerationSection();

  //We can also use 'if (checkRegistrationEligibility())'
  //instead of 'if (checkRegistrationEligibility() == true)'
  return 0;
}

Here you go! All set for now accept for one thing which you will do yourself! The checkRegistrationEligibility() function requires some changes. Make sure to have enterAString() and enterAnInt() methods in it instead of the old regular methods. It is very important because we need cin.ignore() to ignore the leftovers in the input stream after cin >> to avoid problems with getline() method.

NOTE: The getline() is also a function from the standard C++ library. Same is the case for ignore() after cin. We will face many of standard C++ library functions!

After modifiying the checkRegistrationEligibility() function, it will run fine and you will be happy by the results for sure! It is easy to understand something like enterAString than the regular getline(cin,... method. Same is the case with isDataSure() which actually, gives us the hint that this function belongs to something like conforming the data to be right. In a nut shell, with the help of functions, we can make our own unique language which is understandable to everyone and not just programmers! This is something that we call as abstractions! Abstractions make things very easy. In programming, it is not simple to have even a very small task done with our basic English language. Computers don’t understand what we mean by what we say. But an approach like creating abstractions is possible. All the things we see are 0’s and 1’s which are later on, combined to form complex structures given complex names and so on. The binary can be used to define anything with reference to a name!

We defined our 0’s and 1’s into functions like enterAString(), isDataSure(), etc. The concept is to make abstractions and then, use them as much as possible to make even more abstractions. We can’t say our monitor’s screen consists of something like 0101001… but we can say it as ‘pixels’.

For now, this is it! I hope that this fulfills my promise which I talked about in the previous post and I think this much code is hard to absorb for a beginner! But don’t lose here… If code goes wrong just try, try again! Here’s a hint: See what can go wrong when we change the order of the functions! Or if you are already getting an error, see what can go right when we change the order of the functions!

C++ Programming Series: Functions/Subroutines (Part 2)

In the previous post, we have made the code in the main subroutine or int main() very short using another subroutine. Yes, the int main() at the start is also a function that we are dealing with. But now, we will be dealing with multiple functions rather than one. We did all codes in just one function.

The question arises here that what is the fun of making many functions rather than doing all in just one?

If you know science (which you should), you will find out that science is no more a book! The knowledge of science gradually, increases so much that a person can’t simply deal with it! It is extremely hard to deal with all the sciences within one section. Therefore, it is divided into many sections of which the main ones are Mathematics, Physics, Chemistry and Biology. And then, the knowledge within these sections increases tremendously. Then, these sections got further sub-sections and so on. The page about branches (or sections) of science.

But why is that much division? This is for the sake of simplicity, flexibility and convenience. Flexibility means that you can choose to study what you want within science. Of course, everyone don’t love everything within science. Some want Physics, others may want Biology and so on. It gets simple in the way that you learn things in small parts. Just imagine that what if science is a name of a topic with no further topics. It might consists of a million pages. This will definitely, make you hate science. And just think, what if someone says, “There is a spelling mistake somewhere in just one word! Find it!”.

NOTE: Even this post is divided into many paragraphs!

Same is the case with codes! One can’t simply deal with even a thousand lines of code in the main function! Finding out a bug (other than the syntax one) in these lines is a headache! The only way to make branches out of the main function is simply, to make more functions.

In the previous post, we make a functions named checkRegistrationEligibility(). Functions are recognized by a pair of round brackets at the end. Therefore, checkRegistrationEligibility method or function must have a pair of round brackets at the end when declaring it, defining it and calling it.

Below is given the format of any function (when defining it):

-return_type- -function_name- (-parameters-)
{
  -all_code_goes_here-
  return -return_type_variable-;
}

…where…

-return_type- can be replaced with void, int, float, double, non-primitive string or any other primitive type or types that are user-defined (We will learn how to define our own types).

-parameters- can be replaced by the parameter getting into the function or simply nothing.

-return_type_variable- can be replaced by the variable of the same type as that of the type mentioned at the start of the function (i.e type which replaced -return_type-).

The format may looks confusing. If you remove all the codes in the checkRegistrationEligibility() and see it know, it may looks similar to the format.

void checkRegistrationEligibility() //no parameters in round brackets
{
  //all code goes here...

  //no 'return' as the return-type is 'void' which means nothing to return!
}

But having a return keyword doesn’t matter accept that it should be at the end, and without any variable next to it! Calling a function in the main function is very easy. Just have the name of the function with a pair of round brackets at the end and then, of course, a semi-colon!

Let us put all the codes again in the function and make some changes to it. This function should let the main function know whether the person is eligible for going to the next section or not! We will create a boolean variable to know it.

void checkRegistrationEligibility() //make sure that the spellings are right
{
  bool isEligible = false; //By default, it is false.

  string name;
  cout << "Enter your name: ";
  getline(cin, name);
  cout << "Your name is " << name << "." << endl;
 
  int age;
  cout << "Enter your age: "; cin >> age;
  if (age >= 18)
  {
    cout << name << ", you are eligible for registration." << endl;
    cout << "In other words, you can go to next section for registration!" << endl;
    cout << endl << "***Thank you for visiting us!***" << endl;

    isEligible = true;
  }
  else
  {
    cout << name << ", we are sorry that you are not eligible for registration!" << endl;
    cout << "You can register after " << 18 - age << " years." << endl;
    cout << endl << "***Thank you for visiting us!***" << endl;
  }
}

int main()
{
  checkRegistrationEligibility();
  cout << "Is that person eligible = " << isEligible << endl;
}

Try running it! And you got an error! isEligible is unknown to the main function! To remind you, every variable has a scope and the scope of isEligible variable is limited to that function. If you don’t know anything about the scope of a variable, you should read this post first.

The solution is to declare this boolean variable at the top of both the two functions. But then, it will be something not new! Also, you may not want to do that for a 1000 functions. You may wanted to use the functions in the other programs without having a variable to be declared each time for these functions to be used. The freely floating functions should be completely independent of any global variables and must depend all on themselves. From freely floating functions, I meant all those functions which don’t have any associations with user-defined types (Don’t worry! We will discuss them soon). The better solution is to return a boolean variable!

bool checkRegistrationEligibility() //not the keyword 'bool' at the start of the line
{
  string name;
  cout << "Enter your name: ";
  getline(cin, name);
  cout << "Your name is " << name << "." << endl;
 
  int age;
  cout << "Enter your age: "; cin >> age;
  if (age >= 18)
  {
    cout << name << ", you are eligible for registration." << endl;
    cout << "In other words, you can go to next section for registration!" << endl;
    cout << endl << "***Thank you for visiting us!***" << endl;

    return true; //Returning a constant value like 'true' is possible
  }
  else
  {
    cout << name << ", we are sorry that you are not eligible for registration!" << endl;
    cout << "You can register after " << 18 - age << " years." << endl;
    cout << endl << "***Thank you for visiting us!***" << endl;

    return false;
  }

  return false; //Having a return at the end of the function without
//any additional flower brackets nesting, is a very good habit.
}

int main()
{
  cout << "Is that person eligible = " << checkRegistrationEligibility() << endl;
  //Printing a temporary variable returned from the function after the process
}

The function stops when the return keyword is called and throws it out of its scope to where it is called. Note the last line of the function. We use return in order to make the compiler know that the function will return something in any case. Returning nothing or a variable of type other than boolean will result in error!

I promise that the next post will be full of codes rather than the long explanations. But for now, try to figure out why is it good to make and use as many functions as possible. I believe that the syntax of the function is very easy. Here is an exercise. Make a function which takes the user input of a number and then, squares it. The function then, let the other function (from which it is called, i.e main function) know the square of that number by returning it. Soon we are going to enter the arena of even more lovely things!