Showing posts with label Operator. Show all posts
Showing posts with label Operator. Show all posts

Dynamic allocation of objects with pointers: The new and delete operators

In this tutorial of our Object Orientation Course in C++, we will learn how to use pointers with objects, and see a new way to allocate memory.


Object Pointers

Initially, we will create a class, called Student, which will have two variables (math and english), which will store the student's grades. There will also be a get and set, and a getAverage() call to calculate the average for each student.

Our class, all complete and cute looks like this:

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

We will now declare a pointer named 'ptr' of type Student:

  • Student *ptrStudent

Now let's actually declare an object of the Student class:

  • Student s1;

We can associate the pointer with the object as follows:

  • ptrStudent = &s1

(don't forget &, remember that pointers store memory addresses, and by placing & before a variable, it gives the address of that variable)


Working with Pointers with Classes and Objects: ->

As we are already studying pointers, we saw that they can work wonders.
For example, in the previous example, for the pointer to access the elements of an object, we must use the operator ->

Let's define two grades for a student:
  • ptrStudent-> setMath (8);
  • ptrStudent-> setEnglish (10);

And to know the average, using a pointer, just do:
  • ptrStudent-> getAverage()

Our complete code is:
#include <iostream>
using namespace std;

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

int main()
{
    Student *ptrStudent;
    Student s1;

    ptrStudent = &s1;
    
    ptrStudent->setMath(8);
    ptrStudent->setEnglish(10);

    cout << ptrStudent->getAverage()<<endl;

    return 0;
}
Note that we used only one student, we could have created a thousand students and make the pointer point to each one of these students, and the code would always be the same, for example:
Student s1, s2, s3, s4;

Do: ptrStudent = &s1
Then: ptrStudent = &s2
Then: ptrStudent = &s3
Then ptrStudent = &s4

And ready, then just use usr
ptrStudent-> setMath();
ptrStudent-> setEnglish();
ptrStudent-> getAverage()

This avoids writing code for nothing.

Allocating space for objects: new operator

There is a new way to instantiate objects, it is from the new operator.
First you declare your pointer:
  • MyClass *ptr;
At this point, do we have a pointer to point to an object? What object is that? Let's create it now, as follows:
  • ptr = new MyClass

Deleting objects - delete

When we create an object, via normal instantiation, it will always exist and occupy a space in memory. One of the advantages of making dynamic memory allocation, through new, is that we can destroy this pointer, destroying this object and freeing space in memory, for this, just use the delete operator:
  • delete ptr;

And ready, we have a free space on the machine. This may seem silly now, but when you create super complex systems that require maximum efficiency and the least possible use of memory (such as programming a watch or microwave, which has little memory), it is a very important technique.

See the code below, just with a pointer, we fill the grade of two students and calculate their average, and all this just as an object / pointer of the Student class. See how the code looks:

#include <iostream>
using namespace std;

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

int main()
{
    Student *ptrStudent;
    ptrStudent = new Student;

    ptrStudent->setMath(8);
    ptrStudent->setEnglish(10);
    cout << "Studant average 1: " <<ptrStudent->getAverage()<<endl;

    ptrStudent->setMath(6);
    ptrStudent->setEnglish(7);
    cout << "Studant average 2: " <<ptrStudent->getAverage()<<endl;

    delete ptrStudent;

    return 0;
}

Dynamic Memory Allocation and Operators new and delete

In this tutorial, we will learn a new way to declare variables, using the new operator and pointers, in C++.

Dynamic Memory Allocation in C++

Let's assume that you are going to make software for the multinational you work for.
It has 1000 employees.

Then, you will declare, among several things, a thousand variables of type int to store the age of each person, a thousand variables of type double to store the salary of each person, a thousand strings to store the name of each person, etc., etc.

However, his company has grown, and now has 2,000 employees.
And now, go back to the code and change everything?

So far, in our C++ course, we have declared fixed values, exact values ​​of memory blocks, but this is not always interesting in the world of computing. Often you don't know how many variables you will need to use, so you don't know how many variables you will need to declare.

For example, if you are going to create a new social network, how much memory space will you need to store user data? Hey, you don't know ... after all, it may have a thousand or a million users, who knows.

What you have to do is then allocate memory dynamically. That is, it will allocate as needed.

Pointers and the Operator new

Let's say you want to allocate space for a variable of type double.
You will ask, via C++ code, for the computer to find a free memory block on the machine that you can allocate for yourself.

It then goes there to search your system, finds a block and returns the starting address of that block, the address of the first byte. Now, if it returns you an address, what do you need to keep that kind of information?

Yes, our beloved type, the pointer.
This allocation request is made with the new operator.

Here is a code example that we allocate a block of memory for a variable of type double:
#include <iostream>
using namespace std;

int main()
{
    double *ptr;
    ptr = new double;
    *ptr = 3.14;

    cout << *ptr << endl;

    return 0;
}
When we type 'new double', the machine returns a memory address, the first of the block reserved for the double, and stores that address in the 'ptr' pointer, which obviously must be of the double type as well (that is, it points to the address of an 8-byte block, space required for a double).

See, we haven't defined any variables purely of type double. We only have a pointer that points to a block that has a value of type double.

We can even change this stored value using *ptr:
#include <iostream>
using namespace std;

int main()
{
    double *ptr;
    ptr = new double;
    cin >> *ptr;

    cout << *ptr << endl;

    return 0;
}
Everything we could do with a variable of type double, we can do with this pointer.

We can also allocate entire arrays, with the new operator, see:
#include <iostream>
using namespace std;

int main()
{
    int *ptr;
    ptr = new int[10];

    for(int aux=0 ; aux<10 ; aux++){
        ptr[aux] = aux+1;
    }

    for(int aux=0 ; aux<10 ; aux++){
        cout << ptr[aux] << endl;
    }

    return 0;
}
In the code above, we allocate an array of 10 integers, and fill in the numbers from 1 to 10.
That is, in the first example, ptr 'became' a double. In this example above, ptr 'became' an array of integers.

These pointers are flexible, aren't they?

Free memory spaces - Operator delete

Another advantage of using memory allocation dynamically, is the possibility of also freeing that memory that has been allocated, just by using the delete operator.

In the first example, we deallocate the memory block like this:
#include <iostream>
using namespace std;

int main()
{
    double *ptr;
    ptr = new double;
    cin >> *ptr;

    cout << *ptr << endl;

    delete ptr;

    return 0;
}
In case it is an array, we place the pair of square brackets [] before the pointer name:
#include <iostream>
using namespace std;

int main()
{
    int *ptr;
    ptr = new int[10];

    for(int aux=0 ; aux<10 ; aux++){
        ptr[aux] = aux+1;
    }

    for(int aux=0 ; aux<10 ; aux++){
        cout << ptr[aux] << endl;
    }

    delete [] ptr;

    return 0;
}
This may seem strange nowadays, if you imagine your PC with several and several Terabytes, there is no need to free up allocated memory during the execution of a program.

However, this knowledge and practice is essential in critical systems that consume a lot of memory, such as in a very high level game or in a super efficient operating system, you cannot leave everything allocated forever, you have to release it gradually.

In systems with little memory space (like your digital clock, the panel of a refrigerator or the timer of your microwave), it is vital to deallocate and free up memory, as this resource is very scarce.

We will study the new operator in more detail when we study Classes and Objects, in Object Oriented Programming.

C++ Ternary Conditional Operator ?:

In this tutorial of our C++ course, we will learn what it is, what it is for, and how to use the ternary conditional operator ?:

Conditional Operator ?: in C++

The ?: operator is the only ternary in the language, that is, the only one that accepts three operands.

The syntax of this ternary conditional operator is:

  • condition ? statement1 : statement2 ;

Its operation is quite simple, the condition condition is tested.
If it is true, instruction statement1 is executed.
If the condition is false, statement2 that is executed.

It's basically an IF ELSE conditional test, but a simple, short one for executing single-line statements.

Let's redo some program examples we made using IF and ELSE, but now using the ternary operator?:

How to use the Ternary Operator ?:

You were hired to make a show for a concert hall. In a certain piece of code, you will ask the age of the customer. If you are of legal age (21 years or older), please let him know that he can buy the ticket. If you have less, your program should state that it cannot enter the house.

Our code looks like this:

#include <iostream>
using namespace std;

int main()
{
    int age;

    cout << "Your age: ";
    cin >> age;

    age>=21 ? (cout << "Ok you can come in!") :
              (cout << "You cannot buy tickets!") ;

    return 0;
}

Pretty simple, isn't it?

Ternary Operator ?: How to use it in C ++

Your teacher hired you to create a program that gets the student's grade. If it is 7.0 or higher, it has been approved. Otherwise, he is failed.

Using the ternary operator:

#include <iostream>
using namespace std;

int main()
{
    float grade;

    cout << "Your grade: ";
    cin >> grade;

    grade>=7 ? (cout << "Approved"):(cout << "Failed");

    return 0;
}

Much cleaner code.

Example of using ?:

Write a program that asks a person's salary. If it is greater than 3,000, you have to pay 20% tax. If it is smaller, it has to pay 15%. Display the amount of tax the person has to pay. Tax is theft?

#include <iostream>
using namespace std;

int main()
{
    float sal, tax;

    cout << "Your paycheck: ";
    cin >> sal;

    tax = sal>3000 ? 0.20 : 0.15;
    cout << "Taxes $ " << tax*sal <<endl;

    return 0;
}
This solution has become much more genius.
The tax variable will receive the return value from the conditional operator, which is 0.20 or 0.15.

Using the ternary operator ?: in C++

Write, using the ternary conditional operator, a program that takes an integer and tells you if it is even or odd.

#include <iostream>
using namespace std;

int main()
{
    int num;

    cout << "Type a number ";
    cin >> num;

    num%2==0 ? cout <<"Even" : cout <<"Odd";

    return 0;
}

Operator Precedence and Grouping Expression with Parentheses

Now that you have learned everything from the last tutorial on mathematical operations in C++, answer, head on, for us how much the following expressions are worth:
  • 1 + 6*3
  • (1+6)*3
  • 1+6/2
  • (1+6/2)

Order of Mathematical Operators

Let's take the first and third expressions.
In the first one, we have two solutions you can find:
  • 1 + 6*3 = 1 + 18 = 19
Or:
  • 1 + 6*3 = 7 * 3 = 21
In the first calculation, we did the multiplication first and then the sum.
In the second calculation, we first summed 1 to 6, and then multiplied by 3.
Which one is right?

Already the third expression, can be resolved like this:
  • 1+6/2 = 1 + 3 = 4
Some might calculate like this:
  • 1+6/2 = 7 / 2 = 3.5
In the first case, we did the division operation first. In the second case, first we add 1 to 6, only then do the division.

Let's put both expressions in a program, so C ++ will tell us which one is correct.
But first, think about which one you think is right.

Then make a program to calculate both expressions and see the result.
Our code looks like this:

#include <iostream>
using namespace std;

int main()
{
    cout << "1 + 6*3 =  "<< 1 + 6*3 <<endl;
    cout << "1+6/2 =  "<< 1+6/2<<endl;

    return 0;
}

And the result:
Curso de C++ online grátis com apostila para download

Precedence of Mathematical Operators in C++

Imagine if NASA simulates a rocket launch and a calculation results in the value 21.
But then, during the official release, another machine does the same calculation and results in a value of 12?
Damn!

Therefore, C ++ has established an order to do the calculations, a precedence between operators.
As we can see, the multiplication and division calculation was first performed before the addition.

Order of operators is as follows:
  1. *  /  %
  2. + -
That is, C++ saw a mathematical expression, the first thing you will see is whether it has a division, multiplication or module operator. If you have one, solve it first.

If you have more than one of these, resolve from left to right.

Only then will you check for any addition or subtraction.
If you have more than one? It's going from left to right too, ok?

Parentheses () - Organization and Precedence

If we enclose an operation in parentheses, it will always be performed first.
It is as if the () had a higher precedence than the mathematical operators.

For example, on account: 1 + 6 * 3
If we want the sum to be done first, we do: (1 + 6) * 3
If we want to make sure that the multiplication is done first: 1 + (6 * 3)

Suppose we want to calculate the arithmetic mean of 5 numbers, in mathematics this is given by:

How calculate average in C++

A person who has not well learned operator precedence can do:
m = a + b + c + d + e / 5;


The mistake is that only the variable e will be divided by 5, can you understand that?
The correct thing is to use parentheses:
m = (a + b + c + d + e) / 5;

So, besides getting the bill right, it gets more organized too.
Do you agree?

C ++ Exercises

1. The equation of a line is given by: y = mx + c
Write this equation in C ++ using the operators correctly.

2. Write the following algebraic equations in the correct form in C ++:

Free and complete C++ tutorial for download PDF

3. An equation of the second degree is given by: ax² + bx + c = 0
Write it in C ++ language.

4. Still in the previous equation, how would we calculate the delta?

5. And the roots of the equation of the second degree?

Study References

Complete list of precedence of other operators as well:
https://en.cppreference.com/w/cpp/language/operator_precedence