Saltar para o conteúdo
Topos Uranos

Resumo

Esta aula abre a primeira unidade do curso, dedicada aos primeiros passos na programação com C++. Explica para que serve a unidade: levar quem nunca programou de um problema enunciado em linguagem corrente até um programa que compila, executa, lê dados e escreve resultados, sabendo o que cada ferramenta fez no caminho; apresenta suas seis aulas e o fio que as une, desde o algoritmo escrito em português até a classificação dos erros; precisa o pouco que se dá por sabido, que é a aritmética escolar, o hábito de seguir instruções escritas e o manejo de arquivos e pastas; formula o problema que a unidade resolve, o de converter um cálculo que se sabe fazer à mão num procedimento que uma máquina executa sem se enganar e sem se cansar; e mostra aonde conduz, nas unidades seguintes e no curso Programação em C++ II.

Objetivos de aprendizagem

  1. Descrever a sequência de conteúdos da unidade e explicar o que cada aula traz à seguinte.
  2. Reconhecer os conhecimentos prévios que o curso supõe (operar com inteiros e decimais, calcular um quociente e um resto, seguir instruções escritas, salvar um arquivo numa pasta determinada) e revisá-los se for preciso.
  3. Explicar, com um exemplo, o caminho que a unidade ensina a percorrer: do enunciado à especificação, da especificação ao algoritmo e do algoritmo ao programa que se compila e se executa.
  4. Reconhecer o que se espera saber fazer ao terminar a unidade, e distingui-lo do que se aprenderá nas unidades seguintes.

Avaliação de entrada

Antes de percorrer a unidade, convém medir o ponto de partida. Esta avaliação é uma autoavaliação: não se pontua, e seu único propósito é orientar o estudo. Como esta é a primeira unidade do curso, não há perguntas sobre unidades anteriores; em seu lugar, as três primeiras verificam o que o curso dá por sabido: o quociente e o resto de uma divisão inteira, a ordem dos passos de um procedimento e o nome, a extensão e a pasta de um arquivo. As sete seguintes tocam, em ordem, as ideias centrais das seis aulas da unidade. Quem nunca programou não deve esperar acertá-las, e não importa: cada resposta, certa ou não, explica o ponto e nomeia a aula que o trata. As mesmas habilidades voltam a ser medidas no final, na aula de síntese.

Avaliação de entrada

Antes de começar a unidade, meça seu ponto de partida. É uma autoavaliação breve: não recebe nota e seu resultado fica guardado apenas no seu navegador.

  1. Pergunta 1De unidades anterioresRepartem-se 47 folhas entre 6 pessoas, em partes inteiras iguais, e as que não bastam para uma volta completa são guardadas. Quantas recebe cada pessoa e quantas são guardadas?

  2. Pergunta 2De unidades anterioresPara enviar um arquivo anexo por correio eletrônico há quatro passos: A, escrever o endereço do destinatário; B, clicar em “Enviar”; C, abrir uma mensagem nova; D, anexar o arquivo. Qual é a ordem adequada?

  3. Pergunta 3De unidades anterioresUm arquivo está salvo em C:\Users\ana\programas\suma.cpp. Qual é o seu nome, qual a sua extensão e em que pasta está?

  4. Pergunta 4Uma receita diz: “Se a massa estiver seca, acrescentar uma colher de água e sovar; repetir até que não esteja”. A massa precisa de exatamente três colheres para deixar de estar seca. Quantas vezes se pergunta se a massa está seca?

  5. Pergunta 5Qual destas instruções qualquer pessoa, ou uma máquina, pode seguir exatamente da mesma maneira?

  6. Pergunta 6Um programa compila sem erros nem avisos, executa bem com muitos dados, e com um em particular para com a mensagem “division by zero”. Em que momento se produziu o erro?

  7. Pergunta 7Instalou-se o Visual Studio Code com sua extensão de C++, e ao pedir g++ --version no terminal, este responde que não reconhece g++. O que é mais provável?

  8. Pergunta 8O compilador escreve uma mensagem que começa com warning: e, apesar dela, produz o executável. O que significa?

  9. Pergunta 9Onde começa a execução de um programa de C++?

  10. Pergunta 10Um programa declara int age{};, executa std::cin >> age; para ler uma idade, e o usuário digita abc. O que acontece?

Os conteúdos da unidade

A unidade tem seis aulas, que percorrem em ordem o caminho de um problema a um programa em funcionamento. Cada uma supõe a anterior, e a primeira não supõe nada da linguagem.

  • Do problema ao algoritmo. O curso começa sem código, porque o algoritmo precede o programa. A aula ensina a especificar um problema pela sua entrada, pela sua saída e pela relação entre ambas (a pré-condição e a pós-condição); a descrever um algoritmo em passos numerados, sem ambiguidade; a rastreá-lo à mão com uma tabela de rastreamento; a reconhecer nele a sequência, a decisão e a repetição; e a justificar que uma repetição termina, com uma quantidade que decresce a cada volta.
  • Programas, compiladores e C++. Um algoritmo escrito para uma máquina é um programa, e um programa de C++ não se executa tal como se escreve: o pré-processador, o compilador e o ligador o convertem num executável. A aula percorre essas três etapas, distingue o que se descobre ao compilar do que só se manifesta ao executar, compara o modelo compilado com o interpretado e situa no tempo os padrões da linguagem, até C++23, o que o curso usa, e C++26, cuja implementação nos compiladores está em curso.
  • Instalar o ambiente em Windows, macOS e Linux. Três guias completos, um por sistema, para instalar um compilador capaz de C++23 e o editor Visual Studio Code com sua extensão de C++, verificar que tudo funciona com um programa de teste e resolver as falhas frequentes: o compilador que o terminal não encontra, a versão antiga e o padrão que não foi pedido.
  • Compilar, executar e configurar. O ciclo de editar, salvar, compilar, executar e ler, a partir do terminal e a partir do editor, com o comando de compilação do curso. A aula distingue os erros, que impedem o executável, dos avisos, que assinalam código suspeito; ativa os detectores (o de erros de memória, AddressSanitizer, e o de comportamento indefinido, UndefinedBehaviorSanitizer), que vigiam o programa enquanto ele roda; e explica por que uma saída mostra símbolos estranhos no lugar de acentos e do ñ.
  • Anatomia de um programa. O programa mínimo, peça por peça: a diretiva de inclusão e os cabeçalhos, a função main e o código de saída, o namespace std, as instruções, os blocos e os comentários. A aula ensina a corrigir os erros de estrutura lendo as mensagens do compilador a partir da primeira, e fixa o guia de estilo do curso.
  • Entrada, saída e erros. O programa se comunica com o exterior: escreve com std::print e std::println, com especificações de formato para a largura e as casas decimais, e lê com std::cin. A aula mostra o que acontece quando a entrada não tem a forma esperada e como se verifica a leitura, e fecha a unidade com a classificação dos erros pelo seu momento: de compilação, de ligação, de execução e de lógica.

O fio que as une é o do próprio programa. A primeira aula o concebe, a segunda explica em que ele se converte, a terceira instala as ferramentas que o convertem, a quarta ensina a usá-las e a escutar o que dizem, a quinta o disseca e a sexta o põe a conversar com quem o usa. Se isto é assim, no final da unidade o estudante ainda sabe muito pouco de C++, mas sabe como se trabalha com ele, e isso é o que o resto do curso supõe.

O que se dá por sabido

O curso não supõe nenhuma experiência prévia em programação. Supõe, em compensação, três habilidades que convém revisar agora, se a avaliação de entrada mostrou alguma dúvida.

A primeira é a aritmética escolar: operar com inteiros e com decimais, respeitar a ordem das operações (a multiplicação e a divisão antes da adição e da subtração, salvo parênteses) e, sobretudo, calcular o quociente e o resto de uma divisão inteira. Esta última é mais importante do que parece. Dividir 47 folhas entre 6 pessoas dá 7 a cada uma e sobram 5, o que se escreve 47=6⋅7+547 = 6 \cdot 7 + 5, com o resto 55 menor que o divisor 66. C++ tem um operador para o quociente e outro para o resto, e grande parte dos cálculos com inteiros (converter segundos em horas, separar os algarismos de um número, decidir se um número é par) se reduz a eles. Quem quiser estudá-la com detenção a encontra, com a sua demonstração, no curso Álgebra e Geometria I: Números, Funções e Geometria do Plano; aqui basta saber calculá-la.

A segunda é o hábito de seguir instruções escritas ao pé da letra e de reconhecer quando uma instrução não basta para saber o que fazer. Não se trata de um conhecimento, mas de uma atitude: ler “acrescentar sal a gosto” e perceber que essa instrução depende de quem a executa. A primeira aula da unidade converte essa atitude em método.

A terceira é o manejo básico de um computador: criar uma pasta, salvar nela um arquivo com um nome escolhido, reconhecer a extensão do nome (.cpp, .txt, .exe) e saber em que pasta está cada arquivo. Convém configurar desde já o sistema para que mostre as extensões, que alguns sistemas, como o Windows, ocultam por omissão: o código-fonte suma.cpp e o executável suma.exe são arquivos muito diferentes, e confundi-los é uma fonte de erros absurdos. A unidade ensina também a usar o terminal, de modo que não é preciso sabê-lo de antemão; basta estar disposto a digitar comandos em vez de clicar em botões. Instalar programas exige, por último, poder fazê-lo no próprio computador; a aula de instalação indica uma alternativa on-line para quem não puder.

Não se supõe o inglês. As mensagens do compilador estão em inglês, e o curso ensina a lê-las campo por campo, de modo que o que importa nelas (o arquivo, a linha, o tipo de defeito) se entende sem dominar a língua. Tampouco se supõe nenhuma matemática além da escolar: os exemplos usam a divisão, as médias, a tabuada, as datas e as horas.

O problema que a unidade resolve

Um cálculo que se sabe fazer à mão não é ainda um programa. A distância entre ambos é o que a unidade ensina a percorrer, e um problema simples permite medi-la.

ExemploUma duração em horas, minutos e segundos

Um cronômetro registra a duração de cada atividade como um número de segundos, por exemplo 7384, e quer-se escrevê-la na forma habitual de horas, minutos e segundos, com os minutos e os segundos sempre com dois algarismos: 2:03:04. À mão, o cálculo é uma cadeia de divisões: 7384=3600⋅2+1847384 = 3600 \cdot 2 + 184, donde resultam 2 horas e 184 segundos; 184=60⋅3+4184 = 60 \cdot 3 + 4, donde resultam 3 minutos e 4 segundos. Para uma duração, faz-se em um minuto. Para as mil durações de um registro, em compensação, o cálculo à mão é longo e propenso a erros, e a tarefa se presta a que uma máquina a execute.

Ora, uma máquina não pode receber a explicação anterior. Recebe um texto numa linguagem de programação, e para escrever esse texto é preciso ter resolvido antes três questões que o cálculo à mão deixava implícitas. A primeira é a especificação: o que entra (um número inteiro de segundos, não negativo), o que sai (três inteiros, as horas, os minutos e os segundos) e que relação os une: se tt é o total, t=3600h+60m+st = 3600 h + 60 m + s, com 0≤m<600 \leq m < 60 e 0≤s<600 \leq s < 60. A segunda é o algoritmo: os passos precisos que, para qualquer entrada admissível, produzem essa saída.

  1. hh recebe o valor do quociente de tt por 36003600.
  2. mm recebe o valor do quociente por 6060 do resto de tt por 36003600.
  3. ss recebe o valor do resto de tt por 6060.
  4. Escrever hh, dois-pontos, mm com dois algarismos, dois-pontos e ss com dois algarismos.

A terceira é a escrita do algoritmo em C++, com a forma exata que a linguagem exige, e a sua tradução a um executável com as ferramentas adequadas. O programa seguinte o faz. Contém muitas coisas que ainda não foram explicadas: as variáveis (aula 2.1), os operadores / e %, que dão o quociente e o resto da divisão inteira (aula 3.1), a leitura com std::cin e as especificações de formato (aula 1.6); a especificação {:02} deste programa, que escreve um número em duas posições completando com zeros à esquerda, é uma variante da largura que essa aula ensina e que a aula 3.1 usará. Por ora basta reconhecer nele os quatro passos do algoritmo.

Programa em C++
#include <iostream>#include <print>​int main(){    int total{};  // as variáveis serão explicadas na aula 2.1    std::print("Duração em segundos: ");    std::cin >> total;    const int hours{total / 3600};    const int minutes{total % 3600 / 60};    const int seconds{total % 60};    std::println("{} s = {}:{:02}:{:02}", total, hours, minutes, seconds);}
Entrada do programa
7384
Saída
Duração em segundos: 7384 s = 2:03:04

As linhas 9 a 11 são os passos 1 a 3, e a linha 12 é o passo 4. Que o resultado coincida com o calculado à mão não é uma casualidade, mas a verificação que todo programa merece: testá-lo primeiro com um dado cuja resposta se conhece.

O programa resolve o problema, mas a unidade ensina também a desconfiar dele. Se o usuário digita abc em lugar de um número, a leitura fracassa, total fica em zero e o programa escreve, sem nenhum sinal de alarme, que a duração é 0:00:00: uma conclusão falsa com aparência de verdadeira. Se digita uma duração negativa, a especificação não diz o que deve acontecer, e o resultado carece de sentido. Se se escreve total / 360 em lugar de total / 3600, o programa compila, executa e dá um resultado errado, e nenhuma ferramenta o adverte. Cada um desses defeitos pertence a um tipo diferente de erro, que se descobre num momento diferente e se procura de um modo diferente; a última aula da unidade os classifica. Daí se segue que o problema que a unidade resolve não é só o de escrever este programa, mas o de saber por que funciona, com que dados deixa de funcionar e que ferramenta avisará, ou não, de cada defeito.

Portanto, ao terminar a unidade o estudante poderá escrever, compilar e executar programas deste tipo: uns poucos dados de entrada, umas contas em sequência e uns resultados escritos com formato. Não poderá ainda tomar decisões nem repetir instruções em C++ (embora sim num algoritmo escrito em português), nem escolher com critério o tipo de cada dado; isso é o que trazem as unidades seguintes.

Aonde conduz

A unidade é o limiar do curso. O que nela se usa sem explicar se explica depois, nesta ordem. A unidade 2, “Dados e tipos”, explica as variáveis e como se guardam na memória, os limites dos inteiros (e por que um cálculo correto pode estourar), o arredondamento dos números com decimais e as conversões entre tipos. A unidade 3, “Expressões e operadores”, explica a aritmética de C++, com o quociente e o resto dos negativos, a lógica das condições e o que o padrão deixa sem definir numa expressão. A unidade 4, “Controle de fluxo”, leva a C++ as decisões e as repetições que a primeira aula escreve em português, e ensina a justificar que um laço é correto e termina. A unidade 5 decompõe os programas em funções; a 6 introduz os dados compostos (arranjos, vetores, tabelas e registros), com os algoritmos de busca e ordenação e o seu custo; a 7 trata do texto, da entrada robusta e dos arquivos; e a 8, dos programas de vários arquivos, dos testes sistemáticos e do depurador.

Depois do curso, Programação em C++ II continua com o que este deixa de fora de propósito: os ponteiros e a memória dinâmica, as classes com métodos, os templates próprios, as funções anônimas e as exceções. Nenhum desses temas é necessário para resolver os problemas deste curso, e adiá-los permite concentrar-se no que vale em qualquer linguagem: especificar, projetar o algoritmo, escrevê-lo com clareza e verificar que é correto. A aula de síntese desta unidade recolherá precisamente essa distinção, entre o que é próprio de C++ e o que se levará a qualquer outra linguagem.