Programar em C/Variáveis: diferenças entre revisões

[edição verificada][edição verificada]
Conteúdo apagado Conteúdo adicionado
Abacaxi (discussão | contribs)
Sem resumo de edição
Abacaxi (discussão | contribs)
Linha 60:
 
== Tipos de variáveis ==
Até agora você só viu as variáveis do tipo <code>int</code>, que servem para guardar números inteiros. A linguagem C tem 4outros tipos fundamentais. São eles:
* <code>int</code>, para números inteiros entre -2147483647 e 2147483647, utiliza 4 bytes;
* <code>char</code>, para caracteres individuais do padrão ASCII, utiliza 1 byte;
Linha 67:
* <code>bool</code>, para indicar true (verdadeiro) ou false (falso), utiliza 1 byte; Presente apenas no padrão C99 em diante.
 
=== Explicando bits e bytes ===
Os tipos <code>float</code> e <code>double</code> servem para guardar números de ponto flutuante, ou seja, números reais, como 3,1415 (pi), -2,3333, 0,00015, 6,02 &times; 10<sup>23</sup>. A diferença entre os dois é, além do intervalo de dados, a precisão. Geralmente, o tipo <code>float</code> guarda dados (com sinal positivo ou negativo) de 3,4E-38 a 3,4E+38 (além do zero). Já <code>double</code> suporta números tão pequenos quanto 1,7E-308 e no máximo 1,7E+308.
Podemos pensar na memória do computador como uma fita, uma grande fita feita de frames sequenciais.
 
Em cada um desses frames, podemos colocar uma certa voltagem: tem voltagem ou não tem voltagem: se tem voltagem associamos o valor 1, se não tem voltagem associamos o valor 0. Daí termos a linguagem binária de zeros e uns.
 
Agora podemos fazer combinações se tivermos posição de zeros e uns, da direita para a esquerda.
*00000000 1ª Combinação
*00000001 2ª Combinação
*00000010 3ª Combinação
*00000011 4ª Combinação
*00000100 5ª Combinação
*00000101 6ª Combinação
*00000110 7ª Combinação
*00000111 8ª Combinação
*…
 
E na verdade podemos estender este conceito para um número infinito de combinações.
 
Ora o que aconteceu é que nos bastavam pouco menos de 256 combinações (8 bits ordenados) para termos uma combinação para cada letra, maiúscula e minúscula, número, pontos de exclamação, interrogação, etc. …e isso era o suficiente para a nossa comunicação. Mas para haver um certo consenso para que uma dada combinação desse um dado símbolo surgiu a tabela ASCII (surgiram outras tabelas quando se quis colocar os símbolos de outras línguas, como o japonês ou o chinês – ver tabela ISO)
Portanto com 8 bits ou 8 casas conseguíamos ter qualquer símbolo que utilizamos. A esse conjunto de 8 bits chamamos de byte, mais convenientemente. Portanto, um byte tem 8 casas de zeros /uns , ou seja 2 elevado a 8 dá as 256 combinações. E o byte é a unidade básica que o C++ consegue operar e é representado pelo tipo char.
 
=== Números inteiros ===
Se dissermos que 2 bytes representam inteiros, poderemos utilizar as 65 536 combinações, pois 2 bytes -16bits- temos 2 elevado a 16 = 65 536 e isso dar-nos-ia esses números todos. Assim se quisermos apenas os positivos com o zero temos de [0, 65535].
 
Se quisermos ter números negativos e positivos podemos dividir esse valor a meio e dá 32768 para cada lado positivo e negativo, mas como temos de ter o zero vamos roubar um valor ao lado positivo e então ficamos com o intervalo [-32768, 32767]. E ficamos com as mesmas 65 536 combinações.
 
Apresentamos inteiro com 2 bytes, mas eles podem ter 4 bytes, isso vai depender do processador do computador, ie, com quantos bytes consegue ele lidar ao mesmo tempo.
 
Também existem outros tipos, como short (ou short int), que serve para inteiros menores, long (ou long int) para inteiros maiores. Qualquer tipo inteiro pode ser precedido por unsigned (o signed para COM negativos), para cortar os números negativos, permitindo maior capacidade de armazenamento de números positivos. Alguns compiladores aceitam o long long, para aumentar ainda mais o tamanho da variável, alguns desses só aceitam para o tipo int, outros também para o tipo double.
 
Podemos alterar a maneira como os dados são guardados com os '''modificadores de tipo'''. Você pode modificar os tipos de duas maneiras.
Convém ver a tabela de tipos.
 
==== Tamanho: <code>short</code> e <code>long</code> ====
Você pode modificar o tamanho de uma variável usando os '''modificadores de tipo''', que são dois: <code>short</code> e <code>long</code>. Note que <code>float</code> e <code>char</code> não podem ser modificados em tamanho.
 
* '''<code>short</code>''' diminui o espaço necessário para guardar a variável (diminuindo também a gama de valores que esta pode assumir). Só pode ser usado com <code>int</code>.
* '''<code>long</code>''' aumenta o espaço tomado pela variável, e portanto aumenta seu valor máximo e/ou sua precisão. Pode ser usado com <code>int</code> e <code>double</code>.
* O padrão C de 1999 adicionou um terceiro modificador, suportado pelos compiladores mais recentes, inclusive o gcc: <code>long long</code>, que aumentaria ainda mais a capacidade da variável. Alguns deles suportam esse modificador apenas para o tipo <code>int</code>, e outros suportam também para <code>double</code>.
 
Uma observação é necessária: segundo o padrão, não existe nenhuma garantia de que uma variável <code>short int</code> é menor que uma variável <code>int</code>, nem que <code>long int</code> é maior que <code>int</code>. Apenas é garantido que <code>int</code> não é maior que <code>long</code> nem menor que <code>short</code>. De fato, nos sistemas x86 de 32 bits (ou seja, a maioria dos computadores pessoais atualmente), o tamanho de <code>int</code> é igual ao de <code>long</code>. Geralmente, <code>int</code> será o tamanho nativo do processador &mdash; ou seja, 32 bits num processador de 32 bits, 16 bits num processador de 16 bits etc.
 
==== Sinal: <code>signed</code> e <code>unsigned</code> ====
Existe outro tipo de modificador, que define se o número vai ser guardado com '''sinal''' ou não. São os modificadores <code>signed</code> e <code>unsigned</code>, suportados pelos tipos inteiros apenas.
 
* '''<code>signed</code>''' diz que o número deve ser guardado com sinal, ou seja, serão permitidos valores positivos e negativos. Esse é o padrão, portanto esse modificador não é muito usado.
* '''<code>unsigned</code>''' diz que o número deve ser guar
 
==== Tabela de tipos inteiros ====
Convém ver a tabela de tipos inteiros.
 
Tipo Num de bits Formato para leitura com scanf Intervalo
Linha 87 ⟶ 131:
signed long int 32 %li -2.147.483.648 2.147.483.647
unsigned long int 32 %lu 0 4.294.967.295
float 32 %f 3,4E-38 3.4E+38
double 64 %lf 1,7E-308 1,7E+308
long double 80 %Lf 3,4E-4932 3,4E+4932
 
=== Modificadores de tipo ===
Podemos alterar a maneira como os dados são guardados com os '''modificadores de tipo'''. Você pode modificar os tipos de duas maneiras.
 
'''Nota''': O tipo '''long''' é 32 bits como int em computadores de arquitetura 32 bits e 64 bits em computadores de arquitetura 64 bits.
==== Tamanho: <code>short</code> e <code>long</code> ====
Você pode modificar o tamanho de uma variável usando os '''modificadores de tipo''', que são dois: <code>short</code> e <code>long</code>. Note que <code>float</code> e <code>char</code> não podem ser modificados em tamanho.
 
=== Números de ponto flutuante ===
* '''<code>short</code>''' diminui o espaço necessário para guardar a variável (diminuindo também a gama de valores que esta pode assumir). Só pode ser usado com <code>int</code>.
Os números de ponto flutuante são uma tentativa para guardar números reais, como 3,1415 (pi), -2,3333, 0,00015, 6,02 &times; 10<sup>23</sup>. Ao contrário dos números reais, os números representáveis pelo hardware são finitos. A maneira como os tipos de ponto flutuante são armazenados é abstrata para o programador, entretanto, o hardware segue o padrão IEEE 754 (Standard for Floating-Point Arithmetic).
* '''<code>long</code>''' aumenta o espaço tomado pela variável, e portanto aumenta seu valor máximo e/ou sua precisão. Pode ser usado com <code>int</code> e <code>double</code>.
* O padrão C de 1999 adicionou um terceiro modificador, suportado pelos compiladores mais recentes, inclusive o gcc: <code>long long</code>, que aumentaria ainda mais a capacidade da variável. Alguns deles suportam esse modificador apenas para o tipo <code>int</code>, e outros suportam também para <code>double</code>.
 
O armazenamento é feito usando notação científica binária.
Uma observação é necessária: segundo o padrão, não existe nenhuma garantia de que uma variável <code>short int</code> é menor que uma variável <code>int</code>, nem que <code>long int</code> é maior que <code>int</code>. Apenas é garantido que <code>int</code> não é maior que <code>long</code> nem menor que <code>short</code>. De fato, nos sistemas x86 de 32 bits (ou seja, a maioria dos computadores pessoais atualmente), o tamanho de <code>int</code> é igual ao de <code>long</code>. Geralmente, <code>int</code> será o tamanho nativo do processador &mdash; ou seja, 32 bits num processador de 32 bits, 16 bits num processador de 16 bits etc.
{| class=wikitable
| Decimal Notation || Scientific Notation || E Notation
|-
| 123.45 || 1.2345 x 102 || 1.2345E2
|-
| 0.0051 || 5.1 x 10-3 || 5.1E-3
|-
| 1,200,000,000 || 1.2 x 109 || 1.2E9
|}
 
Os tipos <code>float</code> e <code>double</code> servem para guardar números de ponto flutuante. A diferença entre os dois é, além do intervalo de dados, a precisão. Geralmente, o tipo <code>float</code> guarda dados (com sinal positivo ou negativo) de 3,4E-38 a 3,4E+38 (além do zero). Já <code>double</code> suporta números tão pequenos quanto 1,7E-308 e no máximo 1,7E+308.
==== Sinal: <code>signed</code> e <code>unsigned</code> ====
Existe outro tipo de modificador, que define se o número vai ser guardado com '''sinal''' ou não. São os modificadores <code>signed</code> e <code>unsigned</code>, suportados pelos tipos inteiros apenas.
 
float 32 %f 3,4E-38 3.4E+38
* '''<code>signed</code>''' diz que o número deve ser guardado com sinal, ou seja, serão permitidos valores positivos e negativos. Esse é o padrão, portanto esse modificador não é muito usado.
double 64 %lf 1,7E-308 1,7E+308
* '''<code>unsigned</code>''' diz que o número deve ser guardado '''sem sinal'''. Com isso, o valor máximo da variável aumenta, já que não teremos mais valores negativos. Por exemplo, com uma variável <code>char</code> podemos guardar valores de -128 a 127, mas com uma variável <code>unsigned char</code> pode guardar valores de 0 a 255.
long double 80 %Lf 3,4E-4932 3,4E+4932
 
'''Nota''': O tipo '''long double''' é específico de máquinas X86.
 
dado '''sem sinal'''. Com isso, o valor máximo da variável aumenta, já que não teremos mais valores negativos. Por exemplo, com uma variável <code>char</code> podemos guardar valores de -128 a 127, mas com uma variável <code>unsigned char</code> pode guardar valores de 0 a 255.
 
Para usar esses modificadores, devemos colocá-los '''antes''' do nome do tipo da variável, sendo que o modificador de sinal deve vir antes do modificador de tamanho caso ambos sejam usados. Por exemplo:
Linha 116 ⟶ 166:
 
<div style="background-color: #ddffdd; padding: 10px; margin: 20px;">'''Nota:''' Você pode abreviar <code>short int</code> e <code>long int</code> para simplesmente <code>short</code> e <code>long</code>, respectivamente.</div>
 
=== Bool ===
Este tipo surgiu porque muitas vezes apenas se quer ter 2 valores: sim/não ; verdadeiro/falso.
Tem o tamanho de um byte e tem apenas dois valores 0 e 1 que corresponde a true e false.
 
Por que guardar um bool num byte quando se pode utilizar apenas um bit? A razão é que o computador usa no mínimo o byte, não o bit.
 
=== Endereços ===
Os vários locais na memória são identificados por um address, que tem uma lógica sequencial numerada. São necessários 16 bits para guardar o endereço de um byte. dito de outra forma são necessários 2 bytes para guardar a morada de um byte.
será isto verdade?!! isso quer dizer que se guardarmos os endereços de todos os bytes, só temos 1/3 da memória disponível para guardar valores. Bem isto é um pouco estanho, mas repare-se que apenas vamos guardar os addresses das variáveis reservadas. Depois as variáveis nem sempre são de 1 byte, por isso apenas iremos guardar o endereço do primeiro byte e não de todos. por fim faz sentido guardar o endereço de outro endereço?
Os endereços de memória (addresses) são normalmente expressos em linguagem hexadecimal (base 16, utilizam os 10 algarismos mais as 6 primeiras letras – de a a f - do alfabeto para fazerem as 16).
 
'''Pergunta''': Quando tivermos mais do que 256 bytes acrescenta-se um outro byte?
*Sim. Com dois bytes o número de combinações é 256*256.
 
'''Pergunta''': Qual a razão do computador usar apenas bytes como medida mínima? Será que não seria possível utilizar 7 bits ou 5 bits?
*Não é possível pelo fato do computador só entender 0 e 1 então no caso é impossível se ter um número ímpar de bits porque tudo tem que ter o 0 e o 1 por isso que tudo na informática evolui multiplicando-se por 2 (32, 64, 256, 512)
 
== Compatibilidade de dados na atribuição de valor ==