Skip to content

Introdução ao C++

O foco é construir uma base computacional: entender o que é um programa, como ele é executado e como escrever os primeiros códigos. Não vamos nos preocupar com desempenho ou recursos avançados, apenas com o início da programação.

C++ é uma linguagem compilada, onde o código que você escreve (arquivo fonte) é transformado por um compilador em um programa executável que o sistema operacional roda. Esse processo de compilação acontece antes da execução; depois de compilar, você roda o executável.

Quando trabalhamos com uma linguagem compilada, temos algumas diferenças que devemos ter em mente. A primeira delas é que o código que escrevemos não pode ser executado diretamente pelo sistema operacional. As instruções do nosso programa não são interpretadas pelo computador diretamente. Precisamos de um elemento que traduza nossos códigos para uma linguagem que o computador consiga entender e executar. É aí que entra o compilador.

A função do compilador é transformar nosso programa em um conjunto de dados binários que o processador consiga interpretar e executar. Os compiladores surgiram nos anos 1950, quando se passou a escrever programas em linguagens de nível mais alto em vez de apenas em linguagem de máquina ou assembly. Um marco importante foi o compilador de Fortran (1957), desenvolvido na IBM sob a liderança de John Backus. Nessa mesma época, Grace Hopper e sua equipe trabalhavam em tradutores automáticos (como o A-0), que deram base às ideias de compilação.

O compilador lê o código fonte escrito em uma linguagem (como C++) e gera um programa equivalente em uma linguagem que o hardware consiga executar (geralmente código de máquina ou bytecode). Dessa forma, o compilador faz a ponte entre a linguagem que o programador usa e a linguagem que a máquina executa, permitindo que o mesmo código seja reutilizado em diferentes máquinas e que erros de sintaxe sejam detectados antes da execução.

Com isso em mente, vamos direto ao uso.

Para programar em C++, você precisa de:

  • Compilador: um programa que lê seu código e gera o executável. Exemplos: GCC (comando g++), Clang (clang++) ou, no Windows, Visual Studio (MSVC) ou MinGW.
  • Editor de texto ou IDE: onde você escreve o código. Qualquer editor serve; uma IDE facilita compilar e rodar com um clique.

Calma lá! Vocês não falaram para usar o Visual Studio?

Boa colocação, o Visual Studio é uma ótima e poderosa ferramenta. Contudo, ela tem um curva de aprendizado um pouco maior, quando comparada com o CodeBlocks e também possui um tamanho muito maior (alguns GB, no momento que escrevemos este texto, em 2026). Portanto, nossa recomendação para iniciar, ficar com algo mais simples. Se tamanho e complexidade não são um problema, recomendo testar a ferramenta.

Todo programa C++ executável precisa de uma função chamada main: é por ela que a execução começa. Um exemplo mínimo que só imprime uma mensagem é:

#include <iostream>
int main() {
std::cout << "Olá, mundo!" << std::endl;
return 0;
}

O que aparece aí:

  • #include <iostream> — inclui a parte da biblioteca padrão que permite entrada e saída (ler do teclado e imprimir na tela).
  • int main() — define a função principal; o programa começa aqui.
  • std::cout << ... — envia o que está à direita para a saída padrão (o terminal). std::endl pula uma linha.
  • return 0; — indica que o programa terminou sem erro (convenção para o sistema operacional).

Salve o código em um arquivo, por exemplo ola.cpp. Se você estiver no MacOS ou no Linux, no terminal, na pasta do arquivo:

Terminal window
g++ -o ola ola.cpp
./ola

(O primeiro comando gera o executável ola; o segundo roda. No Windows, use ola.exe ou apenas ola dependendo do ambiente.)

Em C++, a biblioteca padrão (entrada/saída, strings, containers, etc.) fica no namespace std. O prefixo std:: indica que o nome que vem em seguida pertence a esse namespace — por exemplo, std::cout é o cout da biblioteca padrão. Isso evita conflito com outros nomes: se você criar uma variável ou função chamada cout no seu código, ela não se mistura com o cout da biblioteca, que continua sendo std::cout. Usar std:: deixa explícito que você está usando recursos da biblioteca padrão e é uma prática comum em material didático e em projetos que preferem clareza à economia de digitação.

Para não precisar escrever std:: toda vez, podemos usar a diretiva using. Com using namespace std;, todos os nomes do namespace std passam a ser usados sem prefixo no arquivo (ou no bloco) em que a diretiva aparece. Outra opção é ser mais seletivo: using std::cout; e using std::cin; trazem só cout e cin para o escopo, reduzindo o risco de conflitos. Em códigos pequenos ou em material introdutório isso deixa o programa mais curto e legível; em projetos maiores costuma-se evitar using namespace std no topo do arquivo para não “poluir” o escopo com todos os nomes da biblioteca padrão.

C++ é uma linguagem fortemente tipada. As variáveis devem ser declaradas com um tipo específico.

#include <iostream>
int main() {
int idade = 25; // Inteiro
double altura = 1.75; // Ponto flutuante (precisão dupla)
char letra = 'A'; // Caractere único
bool programador = true; // Booleano (true/false)
// std::string requer #include <string>, mas é fundamental conhecer
// (Veremos mais em STL)
std::cout << "Idade: " << idade << std::endl;
std::cout << "Altura: " << altura << std::endl;
return 0;
}

A partir do C++11, a palavra-chave auto permite que o compilador deduza o tipo da variável com base no valor de inicialização. Isso é útil para reduzir a verbosidade, especialmente com tipos complexos.

auto x = 10; // Deduzido como int
auto y = 3.14; // Deduzido como double
auto z = "Texto"; // Deduzido como const char*
// O tipo é fixo após a dedução. Não é tipagem dinâmica!
// x = "Erro"; // Isso causaria erro de compilação

A biblioteca <iostream> fornece std::cin para entrada e std::cout para saída.

#include <iostream>
int main() {
int numero;
std::cout << "Digite um número: ";
std::cin >> numero; // Lê o input do usuário e armazena em 'numero'
std::cout << "Você digitou: " << numero << std::endl;
return 0;
}

As estruturas de controle em C++ são muito semelhantes às de C, Java e C#. Elas permitem que o nosso programa execute ou não trechos de código e determine como será a sua execução dado um conjunto de valores ou estados que nosso programa pode assumir. Além das estruturas de controle condicional, temos as estruturas de repetição. Elas permitem que um trecho do nosso programa possa ser repetido enquanto uma determinada condição for verdadeira.

int x = 10;
if (x > 0) {
std::cout << "Positivo";
} else if (x < 0) {
std::cout << "Negativo";
} else {
std::cout << "Zero";
}
// Loop For
for (int i = 0; i < 5; i++) {
std::cout << i << " ";
}
// Saída: 0 1 2 3 4
// Loop While
int contador = 0;
while (contador < 3) {
std::cout << "Contando: " << contador << "\n";
contador++;
}

Funções são agrupamentos de código que podem ser reutilizados em diversos pontos do nosso programa. Além da reutilização, quando utilizamos funções, torna-se mais direto o processo de modularização do código, deixando trechos mais bem definidos e simples de trabalhar e modificar.

Vamos analisar o exemplo abaixo. Este exemplo ainda não utiliza funções.

#include <iostream>
using namespace std;
int main() {
int a, b;
cout << "Digite dois números: ";
cin >> a >> b;
int soma = a + b;
cout << "Soma: " << soma << endl;
return 0;
}
  • cin >> a >> b — lê dois valores do teclado e armazena em a e b (separados por espaço ou Enter).
  • int soma = a + b — calcula a soma e guarda em uma nova variável.

Esse é o padrão básico: declarar variáveis, ler com cin, fazer cálculos e mostrar resultados com cout.

Resumo do fluxo: escrever, compilar, executar:

  1. Escrever o código em um arquivo (por exemplo .cpp).
  2. Compilar com o compilador (ex.: g++ -o meu_programa meu_programa.cpp).
  3. Executar o programa gerado (ex.: ./meu_programa no Linux/macOS ou meu_programa.exe no Windows).

Se houver erro de sintaxe, o compilador mostra mensagens na linha em que detectou o problema. Corrija o código e compile de novo.

Você também pode criar suas próprias funções. Em C++, é comum separar a declaração (protótipo) da definição:

// Declaração da função (protótipo)
int somar(int a, int b);
int main() {
int resultado = somar(5, 3);
std::cout << "A soma é: " << resultado << std::endl;
return 0;
}
// Definição da função
int somar(int a, int b) {
return a + b;
}

O que aconteceu aqui, retiramos o comportamento de somar os dois números do programa principal e deixamos ele separado do nosso programa principal. Desta forma, ele pode ser utilizado em diversos pontos, além de ficar mais direto e simples alterar e corrigir esse comportamento se for necessário.

Calma lá, vocês estão dizendo que mudar esse código simples vai ser um problema?

Aqui tem um ponto importante para analisarmos: muitos exemplos que vamos passar aqui tem uma característica de demonstrar algum comportamento. Para tornar mais simples o processo de compreender o que estamos apresentando, estes exemplos serão mais simples. Contudo, com o passar do tempo e do material, a sua complexidade será elevada. Neste momento, eles são simples de forma proposital, para demonstrar o conceito em sua forma mais básica beleza?