📚 Capítulo do curso: 01 — Fundamentos, Arquitetura e Compilação da Especialização em Sistemas com C. Leia o capítulo antes de começar.

🔢 Miniprojeto C 01 — Conversor de Bases e Auditor de Arquitetura

Um relatório de terminal que audita fatos da arquitetura von Neumann e mostra como o número decimal 91 vira binário, octal e hexadecimal.

🔒 Regra de Ouro: até o Capítulo 01 você só conhece o Pilar da Sequência (Böhm-Jacopini) e a função printf. Este projeto é resolvido sem variáveis, sem if, sem laços e sem funções auxiliares. É de propósito: no Miniprojeto 07 você vai reescrever este conversor com laços, para qualquer número. Guarde a comparação.

⏱️ Tempo estimado 📦 Você vai entregar ✅ Pronto quando
40 min main.c compila sem avisos e a saída bate com a do Passo 4

Diagrama do 🔢 Miniprojeto C 01 — Conversor de Bases e Auditor de Arquitetura

🎯 Objetivos

📋 O problema

Você é estagiário de Engenharia de Sistemas. Sua primeira tarefa é uma ferramenta de diagnóstico que os calouros executam no primeiro dia de aula. Ela imprime dois blocos:

  1. Arquitetura: CPU (UC + ULA + registradores), memória RAM e as 4 etapas do pipeline de compilação.
  2. Conversão numérica: 91 em binário, octal e hexadecimal, calculado por você e explicado em comentários // acima de cada printf.
ID Requisito
RF01 Compila sem nenhum aviso com gcc -Wall -Wextra -Wpedantic -std=c17.
RF02 Inclui <stdio.h> e <stdlib.h>, usa int main(void) e termina com return EXIT_SUCCESS;.
RF03 Nenhuma variável, if, switch, while, for ou função além de main. Só printf em sequência.
RF04 O bloco de arquitetura cita CPU/UC/ULA, RAM e as 4 etapas: Pré-processador → Compilador → Assembler → Linker.
RF05 Mostra 91 = 1011011 (bin), 133 (oct) e 5B (hex), com as divisões sucessivas em comentários.
graph LR
    A["main() inicia"] --> B["Bloco 1:\nRelatório de Arquitetura\n(printf sequencial)"]
    B --> C["Bloco 2:\nConversão Manual de 91\n(printf sequencial)"]
    C --> D["return EXIT_SUCCESS"]

    style B fill:#0284c7,stroke:#38bdf8,color:#ffffff
    style C fill:#0d9488,stroke:#2dd4bf,color:#ffffff
    style D fill:#059669,stroke:#34d399,color:#ffffff

🧰 Ambiente

Você precisa do gcc (versão 8 ou mais nova, por causa do -std=c17).

Sistema Como obter
Linux / WSL sudo apt install build-essential
Windows MinGW-w64 (via MSYS2 ou o que vem com o Code::Blocks), com a pasta bin no PATH
macOS xcode-select --install (o gcc chama o clang; funciona igual aqui)

✅ Checkpoint: gcc --version mostra a versão.

🧯 Se der errado: no Windows, gcc não é reconhecido significa que a pasta bin do MinGW não está no PATH. Feche e reabra o terminal depois de ajustar.


Passo 1 — Compilar o esqueleto

🎯 Objetivo: ter o ponto de partida compilando e rodando antes de escrever qualquer linha.

⌨️ Faça: crie uma pasta c_mini_01, salve o código abaixo como main.c dentro dela e, nessa pasta, rode:

gcc -Wall -Wextra -Wpedantic -std=c17 main.c -o app
./app          # Linux/macOS
.\app.exe      # Windows (PowerShell)

📄 src/esqueleto.c

/*
 * Miniprojeto 01: Conversor de Bases Numericas e Auditor de Arquitetura
 * Regra: somente sequencia de printf. Sem variaveis, sem if, sem lacos.
 */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    printf("====================================================\n");
    printf(" ⚡ AUDITOR DE ARQUITETURA - BLOCO 1: VON NEUMANN\n");
    printf("====================================================\n");
    // TODO 1: imprima uma linha para CPU (Unidade de Controle + ULA + Registradores)
    // TODO 2: imprima uma linha para Memoria RAM (array de bytes enderecavel)
    // TODO 3: imprima as 4 etapas do pipeline: Pre-processador, Compilador, Assembler, Linker

    printf("----------------------------------------------------\n");
    printf(" 🔢 BLOCO 2: CONVERSAO MANUAL DE 91 (DECIMAL)\n");
    printf("----------------------------------------------------\n");

    // TODO 4: Conversao para BINARIO por divisoes sucessivas por 2.
    // Calcule no papel: 91/2=45 resto 1; 45/2=22 resto 1; 22/2=11 resto 0;
    // 11/2=5 resto 1; 5/2=2 resto 1; 2/2=1 resto 0; 1/2=0 resto 1.
    // Lendo os restos de baixo para cima: 1011011
    printf("Decimal 91 em Binario  = 1011011\n");

    // TODO 5: Conversao para OCTAL por divisoes sucessivas por 8.
    // 91/8=11 resto 3; 11/8=1 resto 3; 1/8=0 resto 1 -> lendo de baixo para cima: 133
    printf("Decimal 91 em Octal    = %s\n", "COMPLETE_AQUI");

    // TODO 6: Conversao para HEXADECIMAL por divisoes sucessivas por 16.
    // 91/16=5 resto 11(B); 5/16=0 resto 5 -> lendo de baixo para cima: 5B
    printf("Decimal 91 em Hexa     = %s\n", "COMPLETE_AQUI");

    printf("====================================================\n");

    return EXIT_SUCCESS;
}

✅ Checkpoint: o gcc não imprime nada (zero avisos) e o programa mostra:

🖥️ Saída esperada:

====================================================
 ⚡ AUDITOR DE ARQUITETURA - BLOCO 1: VON NEUMANN
====================================================
----------------------------------------------------
 🔢 BLOCO 2: CONVERSAO MANUAL DE 91 (DECIMAL)
----------------------------------------------------
Decimal 91 em Binario  = 1011011
Decimal 91 em Octal    = COMPLETE_AQUI
Decimal 91 em Hexa     = COMPLETE_AQUI
====================================================

🧯 Se der errado:


Passo 2 — Bloco de arquitetura (TODO 1 a 3)

🎯 Objetivo: descrever a máquina de von Neumann e o pipeline de compilação do Capítulo 01, só com printf.

⌨️ Faça: troque os comentários TODO 1, TODO 2 e TODO 3 por printfs:

💡 Para imprimir o caractere % dentro de um printf (como em %rax), escreva %%.

✅ Checkpoint: recompile e rode. Entre a primeira linha de = e a linha de -, aparecem pelo menos 6 linhas novas, e as 4 etapas estão na ordem Pré-processador → Compilador → Assembler → Linker.

🧯 Se der errado: warning: unknown conversion type character → você escreveu %r em vez de %%r.


Passo 3 — Conversão de 91 (TODO 4 a 6)

🎯 Objetivo: fazer à mão o algoritmo de divisões sucessivas, que é o que um laço vai automatizar mais tarde.

⌨️ Faça:

  1. No papel, divida 91 por 8 até o quociente chegar a 0 e leia os restos de baixo para cima. Repita dividindo por 16 (resto 11 = B).
  2. Escreva as divisões como comentários // acima de cada printf, como já está feito no binário.
  3. Troque "%s\n", "COMPLETE_AQUI" pelo resultado escrito direto no texto do printf.

✅ Checkpoint: as três linhas da conversão mostram 1011011, 133 e 5B. Confira: a calculadora do sistema, no modo Programador, converte 91 para essas bases.

🧯 Se der errado: resultado ao contrário (331 ou B5) → os restos foram lidos de cima para baixo. O último resto é o dígito mais significativo.


Passo 4 — Conferir com o gabarito

🎯 Objetivo: validar o resultado completo e o código de retorno.

⌨️ Faça: acrescente ao fim um rodapé de conclusão (✅ Auditoria concluida...) entre duas linhas de =, recompile e rode. Depois confira o código de retorno:

echo $?              # Linux/macOS → 0
echo $LASTEXITCODE   # Windows (PowerShell) → 0

✅ Checkpoint: a saída tem a mesma estrutura desta (os textos das linhas de arquitetura podem ser seus) e o código de retorno é 0:

🖥️ Saída esperada:

====================================================
 ⚡ AUDITOR DE ARQUITETURA - BLOCO 1: VON NEUMANN
====================================================
CPU:     Unidade de Controle (busca/decodifica) + ULA (calcula)
                + Registradores (%rax, %rsp, %rip)
MEMORIA: Array contiguo de bytes enderecaveis (0x0000 a 0xFFFF...)
PIPELINE DE COMPILACAO (4 etapas):
  1. Pre-processador (gcc -E) -> expande #include e #define
  2. Compilador      (gcc -S) -> gera Assembly (x86_64/ARM)
  3. Assembler       (gcc -c) -> gera codigo objeto binario (.o)
  4. Linker          (ld)     -> resolve simbolos e gera o executavel
----------------------------------------------------
 🔢 BLOCO 2: CONVERSAO MANUAL DE 91 (DECIMAL)
----------------------------------------------------
Decimal 91 em Binario  = 1011011
Decimal 91 em Octal    = 133
Decimal 91 em Hexa     = 5B
====================================================
 ✅ Auditoria concluida. Status: 100% Operacional.
====================================================

Só abra o gabarito depois de chegar até aqui:

🔑 Ver gabarito: src/main.c

📄 src/main.c

/*
 * Miniprojeto 01: Conversor de Bases Numericas e Auditor de Arquitetura
 * Especializacao em Engenharia de Sistemas em C
 * Regra: somente sequencia de printf (Pilar da Sequencia, Bohm-Jacopini).
 */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    printf("====================================================\n");
    printf(" ⚡ AUDITOR DE ARQUITETURA - BLOCO 1: VON NEUMANN\n");
    printf("====================================================\n");
    printf("CPU:     Unidade de Controle (busca/decodifica) + ULA (calcula)\n");
    printf("                + Registradores (%%rax, %%rsp, %%rip)\n");
    printf("MEMORIA: Array contiguo de bytes enderecaveis (0x0000 a 0xFFFF...)\n");
    printf("PIPELINE DE COMPILACAO (4 etapas):\n");
    printf("  1. Pre-processador (gcc -E) -> expande #include e #define\n");
    printf("  2. Compilador      (gcc -S) -> gera Assembly (x86_64/ARM)\n");
    printf("  3. Assembler       (gcc -c) -> gera codigo objeto binario (.o)\n");
    printf("  4. Linker          (ld)     -> resolve simbolos e gera o executavel\n");

    printf("----------------------------------------------------\n");
    printf(" 🔢 BLOCO 2: CONVERSAO MANUAL DE 91 (DECIMAL)\n");
    printf("----------------------------------------------------\n");

    // BINARIO (divisoes sucessivas por 2, le-se os restos de baixo para cima):
    // 91/2=45 r1 | 45/2=22 r1 | 22/2=11 r0 | 11/2=5 r1 | 5/2=2 r1 | 2/2=1 r0 | 1/2=0 r1
    // Restos de baixo para cima: 1 0 1 1 0 1 1 -> 1011011
    printf("Decimal 91 em Binario  = 1011011\n");

    // OCTAL (divisoes sucessivas por 8):
    // 91/8=11 r3 | 11/8=1 r3 | 1/8=0 r1  -> de baixo para cima: 1 3 3 -> 133
    printf("Decimal 91 em Octal    = 133\n");

    // HEXADECIMAL (divisoes sucessivas por 16):
    // 91/16=5 r11(B) | 5/16=0 r5 -> de baixo para cima: 5 B -> 5B
    printf("Decimal 91 em Hexa     = 5B\n");

    printf("====================================================\n");
    printf(" ✅ Auditoria concluida. Status: 100%% Operacional.\n");
    printf("====================================================\n");

    return EXIT_SUCCESS;
}

Por que isso importa: os comentários acima de cada printf fazem todo o cálculo. O programa só exibe um resultado que você já calculou. É essa repetição tediosa (a mesma divisão, várias vezes) que justifica os laços, a partir do Capítulo 06.


🏆 Desafio

Repita o Bloco 2 para mais dois números (por exemplo, 200 e 47), sempre com as divisões comentadas antes do printf.

✅ Checkpoint: 200 = 11001000 / 310 / C8 e 47 = 101111 / 57 / 2F.

Repare que o código cresce uma linha por número e por base. No Miniprojeto 07 você vai automatizar exatamente essa repetição com laços for.


🧭 Navegação

📋 Projetos do curso de C | 📚 Teoria do Capítulo 01 | 🗂️ Hub de projetos