Mandar um cafézinho para o programador:


Me ajude a transformar café em código!
Mostrando postagens com marcador Operações matemáticas. Mostrar todas as postagens
Mostrando postagens com marcador Operações matemáticas. Mostrar todas as postagens

Ponteiros, Arrays e Aritmética

Dando continuidade ao estudo dos ponteiros, vamos ver a importante relação deles com os arrays, bem como aprender a manipular aritmeticamente os ponteiros, com operações matemáticas.

Arrays e Ponteiros, Ponteiros e Arrays

Por curiosidade, vamos declarar um array de inteiros, de nome 'numbers', inicializar e depois simplesmente imprimir o valor '*numbers':
#include <iostream>
using namespace std;

int main()
{
    int numbers[]={1, 2, 3, 2112};

    cout << *numbers << endl;

    return 0;
}
Olha que interessante o resultado:
Curso de C++ online grátis, com apostila para download

Ou seja: o nome do array funciona como um ponteiro.
E para onde ele aponta? Para o primeiro elemento do array.

Assim, sempre que tivermos um array de nome: arr
Se usarmos o nome da variável do array, ela vai se comportar como um array que aponta para: arr[0]

E para apontar para os demais membros do array?
Lembre-se da seguinte regra:
  • arr[indice] = *(arr + indice)

Ou seja:
arr[0] pode ser referenciado por *(arr + 0)
arr[1] pode ser referenciado por *(arr + 1)
arr[2] pode ser referenciado por *(arr + 2)
...
arr[n] pode ser referenciado por *(arr + n)

Podemos fazer um ponteiro de nome 'ptr' apontar para o primeiro elemento de um array das seguintes formas:
  1. int *ptr = numbers;
  2. int *ptr = &numbers[0];

Vamos imprimir todo um array, usando apenas um ponteiro:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<6 ; aux++)
        cout << *(ptr+aux) << endl;

    return 0;
}

Aritmética dos Ponteiros

No exemplo de código C++ anterior, você viu que fizemos várias vezes uma operação de adição com ponteiros: ptr+aux, onde aux é uma variável inteira que foi de 0 até 5, para percorrer o array.

Poderíamos ter feito o mesmo programa com o operador ++, veja:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<6 ; aux++){
        cout << *ptr << endl;
        ptr++;
    }

    return 0;
}
Ou seja, cada vez que adicionamos uma unidade ao ponteiro (++), ele aponta para o próximo elemento do array. Podemos fazer o inverso, apontar para o último elemento do array e irmos decrementando:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = &numbers[5];

    for(int aux=5 ; aux>=0 ; aux--){
        cout << *ptr << endl;
        ptr--;
    }

    return 0;
}
Poderíamos usar também os operadores -= ou +=

A lógica é a seguinte.
Quando apontamos o ponteiro para o array, ele vai apontar para o endereço de memória do primeiro elemento. Vamos supor que seja o bloco de memória 1000.

Quando fazemos: ptr++
Ele não incrementa o endereço de memória em uma unidade, ele não vai pra 1.
Ele vai para: 1000 + sizeof(int)

Como o array é de inteiros, cada bloco do array ocupa 4 Kbytes, logo ptr vai apontar para o endereço 1004. Depois para o bloco 1008, depois 1012...

Se o array fosse de double, ele ia apontar para os endereços: 1000, 1008, 1016, 1024...a cada vez que incrementássemos, pois a variável double ocupa 8 Kbytes.

Veja como fica o código do programa que imprime apenas os elementos de índice par, do array (0, 2 e 4):
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<3 ; aux++){
        cout << *ptr << endl;
        ptr += 2;
    }

    return 0;
}
Essa é a lógica e matemática dos ponteiros. Por isso é tão importante definir o tipo de ponteiro (int, char, double...), pois os ponteiros apontam para blocos inteiros de memória, o tamanho desses blocos variam de acordo com o tipo de dado.

Precedência de Operadores e Agrupamento de Expressões com Parêntesis

Agora que você aprendeu tudo no tutorial passado, sobre operações matemáticas em C++, responda, de cabeça, pra gente, quanto valem as seguinte expressões:
  • 1 + 6*3
  • (1+6)*3
  • 1+6/2
  • (1+6/2)

Ordem dos operadores matemáticos

Vamos pegar a primeira e a terceira expressão.
Na primeira, temos duas soluções que vocês podem achar:
  • 1 + 6*3 = 1 + 18 = 19
Ou:
  • 1 + 6*3 = 7 * 3 = 21
No primeiro cálculo, fizemos primeiro a multiplicação e só depois a soma.
No segundo cálculo, fizemos primeiro a soma do 1 com o 6, só depois multiplicamos por 3.
Qual o certo?

Já a terceira expressão, pode ser resolvida assim:
  • 1+6/2 = 1 + 3 = 4
Alguns podem calcular assim:
  • 1+6/2 = 7 / 2 = 3.5
No primeiro caso, fizemos primeiro a operação de divisão. No segundo caso, primeiro somamos 1 com 6, pra só depois fazer a divisão.

Vamos colocar ambas expressões num programa, pro C++ nos responder qual o correto.
Mas, antes, pense aí qual você acha que é o certo.

Depois, faça um programa para calcular as duas expressões e veja o resultado.
Nosso código fica assim:

#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;
}

E o resultado:
Curso de C++ online grátis com apostila para download

Precedência de Operadores Matemáticos no C++

Imagina se a NASA faz a simulação de um lançamento e um cálculo resulta no valor 21.
Mas aí, durante o lançamento oficial, outra máquina faz o mesmo cálculo e resulta no valor 12 ?
Não dá né?

Por isso, o C++ estabeleceu uma ordem para fazer os cálculos, uma precedência entre os operadores.
Como pudemos ver, foi realizado primeiro o cálculo da multiplicação e divisão, antes da adição.

Ordem dos operadores é a seguinte:
  1. *  /  %
  2. + -
Ou seja, o C++ viu uma expressão matemática, a primeira coisa que vai ver é se tem uma multiplicação divisão ou operador de módulo. Se tiver um, resolve ele primeiro.
Se tiver mais de um desses, resolve da esquerda pra direita.

Só depois, vai checar se tem alguma adição ou subtração.
Se tiver mais de uma? Vai resolvendo da esquerda pra direita também, ok?

Parêntesis () - Organização e Precedência

Se colocarmos uma operação entre parêntesis, ela vai sempre ser realizada primeiro.
É como se os ( ) tivesse uma precedência superior aos dos operadores matemáticos.

Por exemplo, na conta: 1 + 6*3
Se quisermos que a soma seja feita primeiro, fazemos: (1+6)*3
Se quisermos garantir que a multiplicação seja feita primeiro: 1 + (6*3)

Vamos supor que queiramos calcular a média aritmética de 5 números, em Matemática isso é dado por:
Calcular média em C++

Uma pessoa que não aprendeu bem precedência de operadores, pode fazer:
m = a+b+c+d+e/5 ;

O erro é que somente a variável e vai ser dividida por 5, consegue perceber isso?
O correto é usar parêntesis:
m = (a+b+c+d+e)/5 ;

Assim, além de ficar certa a conta, fica mais organizada também.

Exercícios de C++

1. A equação da uma reta é dada por: y=mx + c
Escreva essa equação em C++ usando os operadores corretamente.

2. Escreva as equação algébricas abaixo na forma correta em C++:
Apostila de C++ online grátis para download

3. Uma equação do segundo grau é dada por: ax² + bx + c = 0
Escreva ela na linguagem C++.

4. Ainda na equação anterior, como calcularíamos o delta?

5. E as raízes da equação do segundo grau ?

Respostas na apostila C++ Progressivo

Referências de estudo

Lista completa de precedência de outros operadores também:
https://en.cppreference.com/w/cpp/language/operator_precedence

Matemática em C++: Operadores de soma (+), subtração (-), multiplicação (*), divisão (/) e resto da divisão (%)

Sem exageros ou simplificações demasiadas, podemos dizer que um computador nada mais é que uma mega-super-hiper calculadora. Uma calculadora especial, bem incrementada e potente.

Fazer cálculos, contar, computar...é a base da computação, e consequentemente, da programação.
Neste tutorial, vamos aprender a fazer contas em C++.

Soma em C++: operador +

Para realizarmos a operação de adição, usamos o operador + entre dois valores.
Pode ser na forma literal: 1 + 1
Ou valores armazenados em variáveis: valor1 + valor2

Um programa que mostra a soma dos números 21 e 12:

#include <iostream>
using namespace std;

int main()
{
    cout << 21 + 12;
    return 0;
}


Operadores matemáticos em C++

Esses valores poderiam estar previamente armazenado em variáveis, var1 e var2, por exemplo e somados depois, veja:

Apostila de C++

Note como declaramos as variáveis var1 e var2.
Como as duas são inteiras, não precisamos fazer:
int var1=1;
int var2=2;

Podemos 'resumir', escrever menos e fazer:
int var1=1,
     var2=2;

Bem mais chique, não?

Subtração em C++: operador -

Assim como somamos, podemos subtrair, e para isto, basta usar o operador - (menos).
Vamos subtrair 21 de 12, e depois fazer 1 menos 2:

#include <iostream>
using namespace std;

int main()
{
    int var1=1,
        var2=2;

    cout << "21 - 12 = " << 21-12 << endl;
    cout << "1 - 2 = " << var1-var2;
    return 0;
}

Veja o resultado:
Curso de C++ online grátis

Note que usamos strings:
"21 - 12 = "
"1 - 2 = "

E cálculos matemáticos:
21 - 12
var1 - var2

São duas coisas diferentes, são dois tipos de dados diferentes.
Fizemos isso e colocamos tudo junto no comando cout (saída simples em C++), para deixarmos a saída bem bonitinha e organizada.

Multiplicação em C++: operador *

No nosso dia-a-dia, para descrever a operação de multiplicação, usamos o símbolo x, de vezes, não é verdade?

Porém, em programação C++, 'x' é uma letra.
Para identificar o operador de produto, usamos o asterisco: *

Assim, para multiplicarmos 2 por 2, ou 21 por 12, fazemos:

#include <iostream>
using namespace std;

int main()
{
    int var1=2, var2=2;

    cout << "2*2 = " << var1 * var2 <<endl;
    cout << "21 * 12 = " << 21*12;
    return 0;
}

O resultado da compilação:
Operações matemáticas em C++

Note que declaramos as variáveis todas na mesma linha. Fizemos isso pois elas são do mesmo tipo, do tipo inteiro, e separamos por vírgula.

Poderíamos também ter feito:
int var1=2;

E depois: var1 * var1

Afinal, são de valores iguais, concorda?

Divisão em C++: operador /

No dia-a-dia, o operador de divisão também é diferente, é o “÷”.
Já na programação, o símbolo é o : /

Vamos dividir 4 por 2, e depois 1 por 3.
O código fica:


#include <iostream>
using namespace std;

int main()
{
    float var1, var2;
    var1=1;
    var2=3;

    cout << "4 / 2 = " << 4/2 <<endl;
    cout << "1 / 3 = " << var1/var2;
    return 0;
}

A compilação resulta em:
Tutorial de C++ online grátis completo

Note que primeiro declaramos as variáveis:
float var1, var2;

E só depois inicializamos com os valores 1 e 3:
var1=1;
var2=3;

É uma outra forma de declarar e inicializar variáveis.

No primeiro cout, dividimos 4 por 2. Dois números inteiros, com resultados da divisão inteiro, e o C++ mostrou o inteiro resultante: 2.

Mas ao dividir 1 por 3, o resultado é decimal. Por isso declaramos as variáveis var1 e var2 como float, pois sabíamos que precisaríamos das casas decimais para representar a operação de divisão.

Altere a declaração de float para double, o que aconteceu? Diga nos comentários.
Altere a declaração de float para int, o que aconteceu? Diga nos comentários.


Resto da divisão em C++: operador %


Por fim, vamos usar o operador aritmético %, chamado de módulo ou resto da divisão.
Vamos voltar pra escolinha e relembrar como fazíamos continhas:

Resto da divisão em C++

Tá vendo aquele 'resto'? É o resto da divisão de 17 por 2.
Para obter esse resultado, faça:

  • 17 % 2 = 1
Esse operador é especial pois só se usa com números inteiros, ok?
No futuro, em nosso curso de C++, vamos usar o operador de módulo (ou resto da divisão), para alguns algoritmos específicos, como achar números primos e trabalhar com múltiplos.


Exercícios de Matemática em C++

01. Escreva um programa que some os número 10, 20 e 30
02. Escreva um programa que divida 21 por 12
03. Qual o módulo, ou resto da divisão, do número 21 por 12?
04. Qual o erro do código abaixo?

#include <iostream>
using namespace std;

int main()
{
    numero = 2112;
    int numero;

    cout << "Numero: "<< numero <<endl;
    return 0;
}

05. Armazene na variável 'soma' o resultado exercício 1. Em seguida, divida por 3 para achar a média, que valor encontrou?
06. Refaça o exercício anterior, mas sem usar nenhuma variável, ou seja, imprima o valor do resultado direto no cout.
07. Se fizer: 10 + 20 + 30/3, qual o resultado? É a média? Se não for, por quê deu errado?

Em breve, ainda em nossa seção de Introdução ao C++, vamos voltar a falar dos operadores, em relação a sua precedência.

Esses exercícios estão resolvidos e comentados em nossa Apostila C++ Progressivo.

Fontes de estudo

Ajude o C++ Progressivo

Que tal apoiar e fazer crescer o ensino da programação no Brasil ?

Ajudar nosso país a crescer e se desenvolver cada vez mais, tecnologicamente?

Clica abaixo pra saber mais!

Apoiar o Projeto Progressivo