📚 Introdução às Structs

Structs (estruturas) permitem agrupar variáveis relacionadas sob um único nome. São ideais para representar entidades complexas como jogadores, produtos, ou dados relacionados.


🧩 1. O que são Structs?

Definição:

Uma struct é um tipo de dados personalizado que agrupa variáveis de tipos diferentes.

Analogia:

Pense em uma ficha de aluno:

  • Nome (string)
  • Idade (int)
  • Nota (float)
  • Matriculado (bool)

⚙️ 2. Sintaxe Básica das Structs

2.1 Declarando uma Struct

#include <stdio.h>
#include <string.h>

// Definindo uma struct
struct Aluno {
    char nome[50];
    int idade;
    float nota;
    int matriculado;
};

int main() {
    // Criando variáveis do tipo struct Aluno
    struct Aluno aluno1;
    struct Aluno aluno2;

    return 0;
}

2.2 Inicialização e Acesso

#include <stdio.h>

struct Pessoa {
    char nome[50];
    int idade;
    float altura;
};

int main() {
    // Inicialização direta
    struct Pessoa pessoa1 = {"Maria", 25, 1.65};

    // Atribuição individual
    struct Pessoa pessoa2;
    strcpy(pessoa2.nome, "João");
    pessoa2.idade = 30;
    pessoa2.altura = 1.80;

    // Acesso aos membros
    printf("Nome: %s\\n", pessoa1.nome);
    printf("Idade: %d\\n", pessoa1.idade);
    printf("Altura: %.2f\\n", pessoa1.altura);

    return 0;
}


🔧 3. Structs com Funções

3.1 Passando Structs para Funções

#include <stdio.h>

struct Ponto {
    int x;
    int y;
};

// Função que recebe struct por valor
void imprimir_ponto(struct Ponto p) {
    printf("Ponto: (%d, %d)\\n", p.x, p.y);
}

// Função que recebe struct por referência
void mover_ponto(struct Ponto *p, int dx, int dy) {
    p->x += dx;
    p->y += dy;
}

int main() {
    struct Ponto ponto = {10, 20};

    imprimir_ponto(ponto);
    mover_ponto(&ponto, 5, -3);
    imprimir_ponto(ponto);

    return 0;
}

3.2 Typedef para Simplificar

#include <stdio.h>

// Usando typedef para criar um alias
typedef struct {
    char titulo[100];
    char autor[50];
    int ano;
    float preco;
} Livro;

void imprimir_livro(Livro l) {
    printf("Título: %s\\n", l.titulo);
    printf("Autor: %s\\n", l.autor);
    printf("Ano: %d\\n", l.ano);
    printf("Preço: R$ %.2f\\n", l.preco);
}

int main() {
    // Agora não precisa usar "struct"
    Livro livro1 = {"Dom Casmurro", "Machado de Assis", 1899, 29.90};
    Livro livro2;

    strcpy(livro2.titulo, "O Cortiço");
    strcpy(livro2.autor, "Aluísio Azevedo");
    livro2.ano = 1890;
    livro2.preco = 34.50;

    imprimir_livro(livro1);
    printf("\\n");
    imprimir_livro(livro2);

    return 0;
}


🎮 4. PROJETO: Jogo da Forca com Structs

4.1 Estruturas do Jogo

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>

#define MAX_TENTATIVAS 6
#define TAM_PALAVRA 20

// Struct para representar o jogo
typedef struct {
    char palavra_secreta[TAM_PALAVRA];
    char palavra_atual[TAM_PALAVRA];
    char letras_tentadas[26];
    int tentativas_restantes;
    int letras_encontradas;
    int jogando;
} JogoForca;

4.2 Funções do Jogo

// Inicializa o jogo
void inicializar_jogo(JogoForca *jogo) {
    // Lista de palavras possíveis
    char palavras[][TAM_PALAVRA] = {
        "PROGRAMACAO", "COMPUTADOR", "ALGORITMO",
        "LINGUAGEM", "DESENVOLVIMENTO", "ESTRUTURA"
    };

    // Escolher palavra aleatória
    srand(time(NULL));
    int indice = rand() % 6;
    strcpy(jogo->palavra_secreta, palavras[indice]);

    // Inicializar palavra atual com underscores
    int tamanho = strlen(jogo->palavra_secreta);
    for(int i = 0; i < tamanho; i++) {
        jogo->palavra_atual[i] = '_';
    }
    jogo->palavra_atual[tamanho] = '\\0';

    jogo->tentativas_restantes = MAX_TENTATIVAS;
    jogo->letras_encontradas = 0;
    jogo->jogando = 1;
    memset(jogo->letras_tentadas, 0, 26);
}

// Exibe o estado atual do jogo
void exibir_jogo(JogoForca jogo) {
    printf("\\n=== JOGO DA FORCA ===\\n\\n");

    // Desenho da forca
    printf("Tentativas restantes: %d\\n", jogo.tentativas_restantes);
    printf("Palavra: %s\\n\\n", jogo.palavra_atual);

    // Letras tentadas
    printf("Letras tentadas: ");
    for(int i = 0; i < 26; i++) {
        if(jogo.letras_tentadas[i]) {
            printf("%c ", 'A' + i);
        }
    }
    printf("\\n\\n");
}

// Processa uma tentativa
void processar_tentativa(JogoForca *jogo, char letra) {
    letra = toupper(letra);

    // Verificar se letra já foi tentada
    if(jogo->letras_tentadas[letra - 'A']) {
        printf("Você já tentou a letra %c!\\n", letra);
        return;
    }

    jogo->letras_tentadas[letra - 'A'] = 1;

    // Verificar se a letra está na palavra
    int encontrou = 0;
    int tamanho = strlen(jogo->palavra_secreta);

    for(int i = 0; i < tamanho; i++) {
        if(jogo->palavra_secreta[i] == letra) {
            jogo->palavra_atual[i] = letra;
            jogo->letras_encontradas++;
            encontrou = 1;
        }
    }

    if(!encontrou) {
        jogo->tentativas_restantes--;
        printf("Letra %c não encontrada!\\n", letra);
    } else {
        printf("Boa! Letra %c encontrada!\\n", letra);
    }
}

// Verifica condições de vitória/derrota
void verificar_fim_jogo(JogoForca *jogo) {
    int tamanho = strlen(jogo->palavra_secreta);

    if(jogo->letras_encontradas == tamanho) {
        printf("\\n🎉 PARABÉNS! Você venceu!\\n");
        printf("A palavra era: %s\\n", jogo->palavra_secreta);
        jogo->jogando = 0;
    } else if(jogo->tentativas_restantes <= 0) {
        printf("\\n💀 Fim de jogo! Você perdeu!\\n");
        printf("A palavra era: %s\\n", jogo->palavra_secreta);
        jogo->jogando = 0;
    }
}

4.3 Função Principal do Jogo

int main() {
    JogoForca jogo;
    char letra;

    printf("Bem-vindo ao Jogo da Forca!\\n");
    printf("Tema: Tecnologia e Programação\\n\\n");

    inicializar_jogo(&jogo);

    while(jogo.jogando) {
        exibir_jogo(jogo);

        printf("Digite uma letra: ");
        scanf(" %c", &letra);

        // Validar entrada
        if(!isalpha(letra)) {
            printf("Por favor, digite uma letra válida!\\n");
            continue;
        }

        processar_tentativa(&jogo, letra);
        verificar_fim_jogo(&jogo);
    }

    printf("\\nDeseja jogar novamente? (S/N): ");
    scanf(" %c", &letra);

    if(toupper(letra) == 'S') {
        main(); // Reiniciar o jogo
    }

    return 0;
}


🎯 5. Como Compilar e Executar

5.1 Compilação

gcc -g forca.c -o forca

5.2 Execução

./forca

5.3 Depuração no VS Code

  1. Coloque breakpoints nas funções principais
  2. Pressione F5 para debug
  3. Use Step Into (F11) para acompanhar a lógica

💡 6. Desafios para Melhorar o Jogo

Exercícios de Aprimoramento:

  1. Adicionar mais palavras: Crie um arquivo de palavras
  2. Interface gráfica: Use bibliotecas como ncurses
  3. Sistema de pontuação: Pontue baseado no número de tentativas
  4. Multiplayer: Dois jogadores competindo
  5. Dicas: Adicione sistema de dicas

Exemplo: Carregar palavras de arquivo

void carregar_palavras(char palavras[][TAM_PALAVRA], int *quantidade) {
    FILE *arquivo = fopen("palavras.txt", "r");
    if(arquivo == NULL) {
        // Usar palavras padrão
        strcpy(palavras[0], "PROGRAMACAO");
        // ... outras palavras
        *quantidade = 6;
        return;
    }

    *quantidade = 0;
    while(fscanf(arquivo, "%s", palavras[*quantidade]) != EOF) {
        (*quantidade)++;
    }
    fclose(arquivo);
}


📌 Resumo do que Aprendemos:

O que são structs e quando usá-las

Declaração e uso de structs

Structs com funções (passagem por valor/referência)

Typedef para simplificar

Projeto completo: Jogo da Forca

Boas práticas de organização


🚀 PRÓXIMOS PASSOS:

Agora você está pronto para criar programas mais complexos! Pratique criando:

  • Sistema de cadastro de alunos
  • Agenda de contatos
  • Sistema de gerenciamento de biblioteca
  • Jogos mais complexos

😊

Compartilhe seu jogo da forca melhorado!


💻 Dica: Use o debugger do VS Code para entender melhor o fluxo do jogo e encontrar possíveis bugs!


Descubra mais sobre Apprendendo

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continue lendo