Memória e Modificadores
Teoria
Introdução
Fala aí, tudo beleza?
Nesse tópico a gente vai aprender sobre como o espaço na memória é criado para armazenar uma variável e como isso influencia nos valores que as variáveis podem assumir.
Depois, vamos ver que esse espaço pode ser alterado pelo que denominamos como modificadores.
Espaço na memória
Para cada tipo de variável, no momento em que a declaramos no nosso código, existe um espaço destinado para armazenar o seu valor. Além disso, cada tipo de variável tem uma faixa de valores que podem ser assumidos:
Mas onde esses bytes ficam armazenados?
No C++, existe o operador &, por onde podemos acessar o endereço na memória ram no qual uma variável está armazenada. Vamos ver como isso funciona:
Perceba que quando usamos o “cout” e chamamos apenas a variável, o programa vai printar o valor que está armazenado dentro dela, mas quando escrevemos antes do nome da variável, o programa vai printar o endereço de memória onde essa variável está armazenada. Isso ocorre pois o “” é um caractere especial para o C++, que o interpreta como um indicativo de endereço de memória.
Agora, imagine que você está trabalhando num projeto e precisa armazenar numa variável um valor que exceda o limite do int e que possa ser apenas positivo, como uma distância muito grande. Nesse caso, utilizaríamos a seguinte expressão:
Nesse código, o unsigned é um modificador de variáveis que nos ajudaria nessa exata questão. Mas como ele funciona?
Quando usamos o unsigned, estamos indicamos pro programa que a variável em questão é sempre positiva, com isso, ele “move” o intervalo de valores que ela pode assumir pra cobrir apenas valores positivos. Então, o limite máximo é aumentado.
Vamos ver mais sobre esse e outros tipos de modificadores!
Tipos de modificadores
Os principais modificadores usados em C++ são:
- Signed:
- Unsigned:
- Long
- Short
Utilizado para declarar que iremos trabalhar tanto com valores positivos quanto com valores negativos. O padrão em C++ é esse, então declarar uma variável com signed, pode ser redundante. Por exemplo, é o mesmo que .
Utilizado quando vamos trabalhar apenas com valores maiores ou iguais a 0. Uma variável declarada como , por exemplo, ocupa a mesma quantidade de memória que um (4 bytes), mas como não estamos trabalhando com valores negativos, o espaço na memória é totalmente reservado para valores positivos ou 0, o que torna o limite de valores positivos maior.
Aumenta a quantidade de memória destinada ao armazenamento de uma variável. Com isso, os limites de valores também aumentam.
O short é o oposto do long, ele diminui a memória destinada ao armazenamento de uma variável, diminuindo os limites de valores. Seu uso é importante para quando queremos reduzir a memória ocupada pelo nosso programa.
Com base nisso, podemos refazer a nossa tabela usando os modificadores para o tipo inteiro:
O uso desses modificadores é semelhante para os outros tipos de variáveis.
Função sizeof
Por meio do comando sizeof é possível saber o tamanho do espaço da memória dedicado a uma variável. Vamos usá-lo para confirmar alguns valores:
Esse programa vai printar na tela o quanto de memória cada tipo de variável ocupa. Pois a função sizeof nos retorna esse valor em bytes ao ser usada da forma acima.
Com isso, você já sabe sobre a memória que o seu programa usa para guardar as variáveis declaradas no código e como utilizar modificadores para manipular isso.
Agora vamos fazer alguns exercícios de fixação.
Espaço na memória
Tipos de modificadores
Função sizeof
Exercícios Resolvidos
Exercício Resolvido #1
Elaboração Própria
Cite uma vantagem e uma desvantagem de se utilizar os operadores short e long.
Passo 1
O modificador short é utilizado para diminuir a quantidade de memória ocupada por uma variável, consequentemente, reduzindo a capacidade armazenamento dessa variável, isso é importante pois, ao reduzir o espaço ocupado na memória ram, o programa pode rodar de forma mais rápida. É importante que ele seja utilizado para o armazenamento de pequenas quantias.
Passo 2
O modificador long é o caso oposto, pois é utilizado para aumentar a capacidade de armazenamento de uma variável, aumentando também o espaço de memória ram ocupado por ela. Quando esse operador é usado, um valor ou mais preciso pode ser adicionado, no entanto, o custo de memória ram é maior.
Resposta
- Short – Vantagem: menos espaço ocupado na memória. Desvantagem: reduz a capacidade de armazenamento da variável.
- Long – Vantagem: maior capacidade de armazenamento na variável. Desvantagem: maior espaço ocupado na memória ram.
Exercício Resolvido #2
Elaboração Própria
Tomando com base o seguinte programa em C++, coloque as variáveis em ordem crescente de memória ocupada.
Passo 1
Primeiramente, vamos analisar cada tipo de variável declarada.
- Double - número real com grande precisão. Ocupa 8 bytes.
- Short int - número inteiro com baixo limite. Ocupa 2 bytes.
- Float - número real. Ocupa 4 bytes.
- Char - caractere. Ocupa 1 byte.
Com isso, já possuímos o suficiente para colocarmos as variáveis em ordem crescente de memória.
Resposta
caracter, num2, num3 e num1.
Exercício Resolvido #3
Elaboração Própria
Explique para que serve a função do C++ e como usá-la.
Passo 1
A função é uma função do C++ que serve para sabermos o tamanho de um determinado dado ocupa (em Bytes) na memória ram do computador enquanto o programa está sendo executado.
A sintaxe dessa função é dada por
O valor retornado é um inteiro que representa a quantidade de bytes ocupados pelo dado que está entre parênteses.
Resposta
A função serve para sabermos a quantidade de bytes que um dado ocupa na memória ram. Ela recebe essa dado a quantidade de bytes na forma de um inteiro.
Exercício Resolvido #4
Elaboração Própria
Um engenheiro está fazendo um programa que precisa armazenar numa variável um valor inteiro, positivo e de no máximo 4 bilhões. Ao tentar armazenar esse valor numa variável do tipo , o seu programa estava dando erro. Explique porque isso está acontecendo e dê uma solução.
Passo 1
Uma variável do tipo int pode armazenar um número inteiro que esteja no intervalo de até . Como o valor que está sendo utilizado ultrapassa o máximo que pode ser armazenado, o programa está retornando um erro.
Passo 2
Como ele precisa armazenar uma variável inteira, positiva que é no máximo 4 bilhões. Uma boa alternativa seria declarar essa variável como um , que comporta valores de até . Dessa forma, o seu programa não dará erro ao tentar armazenar o valor trabalhado.
Resposta
O valor utilizado ultrapassa a capacidade de armazenamento de uma variável . Seria recomendado utilizar um .
Exercício Resolvido #5
Elaboração Própria
Com base nos dados do laboratório onde está trabalhando, um engenheiro precisa fazer um programa em C++ para calcular o valor de pi com 9 casas decimais de precisão. Com isso em mente, ele escreve o seguinte programa, que tem como intuito calcular esse valor e armazená-lo na variável pi.
Ao tentar rodar o seu script, o engenheiro nota que o programa não conseguiu imprimir o valor de pi com a quantidade de casas decimais esperadas. Por que ocorreu esse erro e qual seria uma medida para que isso não ocorra?
Passo 1
A variável declarada no código é do tipo float. Variáveis desse tipo podem ter até 6 casas decimais de precisão. No entanto, o objetivo do engenheiro é salvar um número de 9 casas decimais de precisão, fazendo o uso do float ser impraticável nesse caso.
Com isso, nós já sabemos qual o problema do programa.
Passo 2
Agora, vamos analisar uma possível solução.
Precisamos armazenar um número real com uma alta precisão. Para números reais, temos as seguintes opções principais:
float: Com até 6 casas de precisão.
double: Com até 10 casas de precisão.
Logo percebe-se que uma variável do tipo double seria mais eficiente nesse caso.
Resposta
O uso do tipo float, que apresenta 6 casas de precisão para armazenar um valor que necessita de 9 casas decimais de precisão. Uma possível solução seria usar o double.
Exercício Resolvido #6
Elaboração Própria
Descreva a saída do seguinte programa:
Passo 1
Eai, tudo beleza?
Primeiramente, vamos entender melhor esse código que nos foi fornecido. Nele, são declaradas variáveis distintas. A partir da linha , é utilizado o comando para que sejam impressas mensagens no seguinte padrão:
Logo em seguida, é chamada a função e, dentro dela, é passada uma variável do mesmo tipo indicado na mensagem anterior. Ou seja, será impresso a quantidade, em bytes, que essa variável ocupa na memória do computador.
Passo 2
Para sabermos exatamente qual mensagem será impressa na tela, temos que saber a quantidade de bytes ocupada por cada variável. Dessa forma, podemos montar a seguinte tabela:
Passo 3
Vamos unir as informações da tabela com a o padrão da mensagem que está sendo impressa. Dessa forma, na linha 14, por exemplo, nós teríamos:
Por fim, basta fazermos o mesmo para as outras mensagens impressas.
Resposta
O tamanho de um int: 4 byte(s)
O tamanho de um unsigned int: 4 byte(s)
O tamanho de um long long int: 8 byte(s)
O tamanho de um float: 4 byte(s)
O tamanho de um double: 8 byte(s)
O tamanho de um char: 1 byte(s)
O tamanho de um boolean: 1 byte(s)
Exercício Resolvido #7
Elaboração Própria
Para salvar uma data ao longo da execução de um programa, declare 3 variáveis inteiras: , e . De forma a minimizar a quantidade de memória ocupada no programa, utilize um modificador de tipo. Diga a quantidade de memória total ocupada por essas variáveis.
Passo 1
Eai, tudo beleza?
Nessa questão, precisamos declarar variáveis de forma a simularmos uma data, com o dia, o mês e o ano. Como esses valores não tendem a serem altos, não precisamos utilizar valores próximos do limite de para um inteiro.
Logo, vamos declarar essas variáveis como inteiros, mas vamos utilizar um modificado de tipo para reduzir a memória ocupada. Esse modificador é o . Com isso, vamos declarar essas variáveis como :
Passo 2
Enquanto um ocupa bytes, um ocupa somente bytes. Dessa forma, as 3 variáveis que declaramos ocupam um total de bytes na memória ram de um computador.
Resposta
bytes de memória ocupados.
Exercício Resolvido #8
Elaboração Própria
Um Arduino é um microcontrolador, programável em C++, que é muito utilizado mundialmente. Nele, existe uma função própria que diz quanto tempo ele está funcionando em microssegundos, a função . Ela retorna um valor que varia entre e , após o arduino ficar ligado por um tempo que exceda esse valor, a função reseta a contagem.
No código acima, a função é utilizada na linha , na qual é passada o valor do tempo no qual o Arduino ficou ligado para uma variável , declarada na primeira linha de código.
Tal código é utilizado no Arduino com a intenção de monitorar a quantidade de tempo no qual ele está ligado, fazendo com que seja impresso na tela o valor armazenado na variável . Um estudante percebe que, em certo momento, esse código começa a imprimir uns valores incoerentes para o tempo. Diga uma possível razão para isso.
Passo 1
Fala aí, tudo tranquilo?
Nessa questão, nós não precisamos ter conhecimento prévio em Arduino, devemos apenas compreender o que esse código está fazendo com base no que é dito no enunciado.
Basicamente, esse código imprime o valor do tempo em que o Arduino está ligado por meio do comando , que nos fornece um valor que varia entre e . Esse valor é armazenado variável tempo, declarada como um , e é impresso na tela do computador por meio dos comandos que estão depois da linha .
Passo 2
O problema aqui está na capacidade de armazenamento de uma variável do tipo . A variável pode receber valores que variam entre e , no entanto, ela está recebendo valores maiores que isso, o que vai levar aos valores incoerentes que são observados pelo estudante.
Para que isso fosse consertado, seria recomendado declarar a variável como um , ou simplesmente . Dessa forma, ela poderá receber os valores sem que o seu limite seja ultrapassado.
Resposta
A variável está declarada como , mas deveria ser uma .