Variáveis e tipos básicos: int, char, float, double

1. Introdução às Variáveis em C

Em linguagem C, uma variável é um espaço reservado na memória do computador para armazenar dados que podem ser modificados durante a execução do programa. Cada variável possui um tipo, que define o formato e o tamanho dos dados que ela pode armazenar, além das operações permitidas.

A declaração de uma variável segue a sintaxe básica:

tipo nome;

Por exemplo:

int idade;
char letra;
float salario;
double precisao;

As regras para nomes de identificadores em C incluem:
- O nome deve começar com letra (maiúscula ou minúscula) ou underscore (_)
- Os caracteres subsequentes podem ser letras, dígitos ou underscore
- C é case-sensitive: idade e Idade são variáveis diferentes
- Palavras reservadas da linguagem (como int, if, return) não podem ser usadas como nomes

2. Tipo int: Números Inteiros

O tipo int é utilizado para armazenar números inteiros (sem parte fracionária). Em arquiteturas modernas de 32 ou 64 bits, um int ocupa 4 bytes (32 bits), com faixa de -2.147.483.648 a 2.147.483.647.

Declaração e inicialização:

int idade = 25;
int quantidade = -10;
int alunos = 0;

Modificadores permitem ajustar a faixa de valores:
- short int: normalmente 2 bytes, faixa menor (-32.768 a 32.767)
- long int: normalmente 4 ou 8 bytes, faixa maior
- unsigned int: apenas valores positivos (0 a 4.294.967.295)

Exemplo prático:

#include <stdio.h>

int main() {
    short int pequeno = 100;
    long int grande = 100000L;
    unsigned int positivo = 3000000000U;

    printf("short: %d\n", pequeno);
    printf("long: %ld\n", grande);
    printf("unsigned: %u\n", positivo);

    return 0;
}

3. Tipo char: Caracteres e Números Pequenos

O tipo char ocupa 1 byte (8 bits) e pode armazenar um caractere da tabela ASCII ou um número inteiro pequeno (-128 a 127 para signed char, ou 0 a 255 para unsigned char).

Declaração de caracteres com aspas simples:

char letra = 'A';
char digito = '7';
char simbolo = '#';

Como char é tecnicamente um tipo inteiro, podemos usá-lo para aritmética:

char valor = 65;  // Equivale a 'A' na tabela ASCII
char proximo = valor + 1;  // Agora vale 66, que é 'B'

printf("Caractere: %c\n", valor);    // Imprime 'A'
printf("Código ASCII: %d\n", valor); // Imprime 65

Exemplo completo:

#include <stdio.h>

int main() {
    char letra = 'M';
    char codigo = 77;  // 'M' em ASCII

    printf("Letra: %c, Código: %d\n", letra, letra);
    printf("Código: %d, Letra: %c\n", codigo, codigo);

    // Convertendo maiúscula para minúscula
    char minuscula = letra + 32;  // Diferença entre 'A' e 'a' é 32
    printf("Minúscula de %c é %c\n", letra, minuscula);

    return 0;
}

4. Tipo float: Números de Ponto Flutuante (Precisão Simples)

O tipo float representa números reais com precisão simples, ocupando 32 bits. Ele oferece aproximadamente 7 dígitos decimais de precisão e faixa aproximada de ±3.4 × 10⁻³⁸ a ±3.4 × 10³⁸.

Declaração com sufixo f obrigatório:

float pi = 3.14159f;
float temperatura = -5.5f;
float velocidade = 120.75f;

Limitações importantes:

#include <stdio.h>

int main() {
    float a = 0.1f;
    float b = 0.2f;
    float soma = a + b;

    printf("0.1 + 0.2 = %.20f\n", soma);  // Erro de arredondamento!
    // Resultado: 0.30000001192092895508

    // Precisão limitada
    float grande = 1234567.89f;
    printf("Valor: %.2f\n", grande);  // Pode perder precisão

    return 0;
}

5. Tipo double: Números de Ponto Flutuante (Precisão Dupla)

O tipo double oferece precisão dupla, ocupando 64 bits. Ele fornece aproximadamente 15 dígitos decimais de precisão, sendo o padrão para literais de ponto flutuante em C.

Declaração (sem sufixo, o padrão é double):

double preco = 19.99;
double precisao = 3.141592653589793;
double cientifico = 1.5e-10;  // Notação científica

Comparação entre float e double:

#include <stdio.h>

int main() {
    float f_pi = 3.141592653589793f;
    double d_pi = 3.141592653589793;

    printf("float:   %.15f\n", f_pi);   // Perde precisão após 7 dígitos
    printf("double:  %.15f\n", d_pi);   // Mantém precisão por 15 dígitos

    // Quando usar cada um
    float f1 = 0.1f;
    double d1 = 0.1;

    printf("float:   %.20f\n", f1);
    printf("double:  %.20f\n", d1);     // Mais preciso

    return 0;
}

Use float quando a memória for crítica (como em gráficos 3D) e double para cálculos científicos que exigem alta precisão.

6. Operações com Variáveis e Conversão de Tipos

Operações aritméticas básicas:

int a = 10, b = 3;
int soma = a + b;       // 13
int diferenca = a - b;  // 7
int produto = a * b;    // 30
int quociente = a / b;  // 3 (divisão inteira!)
int resto = a % b;      // 1 (módulo)

Conversão implícita (promoção de tipos):

int inteiro = 5;
float flutuante = inteiro;  // 5.0 (promoção automática)
double resultado = inteiro + flutuante;  // 10.0

Conversão explícita (cast):

int x = 10, y = 3;
float divisao = (float) x / y;  // 3.333333, não 3
printf("Divisão: %.2f\n", divisao);

// Armadilha comum
int a = 5, b = 2;
float errado = a / b;    // 2.0 (divisão inteira primeiro!)
float certo = (float) a / b;  // 2.5

7. Escopo e Tempo de Vida das Variáveis

Variáveis locais existem apenas dentro do bloco {} onde foram declaradas:

#include <stdio.h>

void funcao() {
    int local = 10;  // Variável local
    printf("Local: %d\n", local);
}  // 'local' é destruída aqui

int global = 100;  // Variável global, visível em todo o arquivo

int main() {
    printf("Global: %d\n", global);

    {
        int bloco = 20;  // Variável de bloco
        printf("Bloco: %d\n", bloco);
    }  // 'bloco' é destruída aqui

    // printf("%d", bloco);  // ERRO: bloco não existe mais

    static int persistente = 0;  // Mantém valor entre chamadas
    persistente++;
    printf("Persistente: %d\n", persistente);

    return 0;
}

8. Boas Práticas e Erros Comuns

Sempre inicialize variáveis para evitar lixo de memória:

int contador = 0;  // Correto
int total;         // Perigoso: contém valor indefinido
printf("%d", total);  // Comportamento imprevisível!

Escolha o tipo adequado para cada contexto:

// Para contagens, use int
int alunos = 30;

// Para dinheiro, use double (evite float pela baixa precisão)
double salario = 2500.50;

// Para caracteres, use char
char inicial = 'J';

// Para flags binárias, use unsigned char
unsigned char ativo = 1;

Cuidado com overflow e divisão inteira:

int max = 2147483647;
int overflow = max + 1;  // Resultado negativo! (-2147483648)

int a = 7, b = 2;
int resultado = a / b;  // 3, não 3.5!

Referências