Memória e Modificadores

Ver Todos os Exercícios

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:
  • 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, i n t   a é o mesmo que s i g n e d   i n t   a .

  • Unsigned:
  • Utilizado quando vamos trabalhar apenas com valores maiores ou iguais a 0. Uma variável declarada como u n s i g n e d   i n t , por exemplo, ocupa a mesma quantidade de memória que um i n t (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.

  • Long
  • Aumenta a quantidade de memória destinada ao armazenamento de uma variável. Com isso, os limites de valores também aumentam.

  • Short

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

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

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

Explique para que serve a função s i z e o f do C++ e como usá-la.

Passo 1

A função s i z e o f é 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

s i z e o f   d a d o

O valor retornado é um inteiro que representa a quantidade de bytes ocupados pelo dado que está entre parênteses.

Resposta

A função s i z e o f 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

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 i n t , 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 - 2,147,483,648 até 2,147,483,64 7 . 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 u n s i g n e d   i n t , que comporta valores de 0 até 4,294,967,295 . 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 i n t . Seria recomendado utilizar um u n s i g n e d   i n t .

Exercício Resolvido #5

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

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 7 variáveis distintas. A partir da linha 14 , é utilizado o comando c o u t para que sejam impressas mensagens no seguinte padrão:

O   t a m a n h o   d e   u m         _ _ T i p o D e V a r i á v e l _ _ :

Logo em seguida, é chamada a função s i z e o f 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 r a m 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:

O   t a m a n h o   d e   u m   i n t :   4   b y t e ( s )

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

Para salvar uma data ao longo da execução de um programa, declare 3 variáveis inteiras: d i a , m e s e a n o . 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 s h o r t . Com isso, vamos declarar essas variáveis como s h o r t   i n t :

Passo 2

Enquanto um i n t ocupa 4 bytes, um s h o r t   i n t ocupa somente 2 bytes. Dessa forma, as 3 variáveis que declaramos ocupam um total de 6 bytes na memória ram de um computador.

Resposta

6 bytes de memória ocupados.

Exercício Resolvido #8

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 m i c r o s ( ) . Ela retorna um valor que varia entre 0 e 4,294,967,279 , 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 m i c r o s ( ) é utilizada na linha 7 , na qual é passada o valor do tempo no qual o Arduino ficou ligado para uma variável t e m p o , 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 t e m p o . 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 m i c r o s ( ) , que nos fornece um valor que varia entre 0 e 4,294,967,279 . Esse valor é armazenado variável tempo, declarada como um i n t , e é impresso na tela do computador por meio dos comandos que estão depois da linha 7 .

Passo 2

O problema aqui está na capacidade de armazenamento de uma variável do tipo i n t . A variável t e m p o pode receber valores que variam entre - 2,147,483,648 e 2,147,483,64 7 , 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 t e m p o como um u n s i g n e d   l o n g   i n t , ou simplesmente u n s i g n e d   i n t . Dessa forma, ela poderá receber os valores sem que o seu limite seja ultrapassado.

Resposta

A variável t e m p o está declarada como i n t , mas deveria ser uma u n s i g n e d   l o n g   i n t .