Resumo
Esta aula constitui a unidade inicial do curso e expõe o seu plano de estudos completo. Declara o propósito do curso, que é a própria programação e não uma linguagem; explica por que os seus fundamentos são ensinados em C++, uma linguagem que não oculta a máquina, e não em uma de curva mais amigável; indica os estudantes a quem se dirige, o pouco que pressupõe e os cursos aos quais conduz; enuncia os sete objetivos de aprendizagem globais e as unidades que contribuem para cada um; descreve as suas oito unidades de conteúdo e as aulas que as compõem; estima a dedicação total que o curso exige, a sua distribuição por unidades, um ritmo de estudo sugerido e os seus créditos; explica como as suas aulas são feitas, e, por último, aconselha sobre o modo de estudá-lo, sobre o uso de assistentes de inteligência artificial e sobre o controle de versão.
Objetivos de aprendizagem
- Descrever a sequência das oito unidades do curso e explicar o que cada uma traz às seguintes.
- Enunciar os sete objetivos de aprendizagem globais do curso e reconhecer que unidades contribuem para cada um.
- Explicar com um exemplo por que o curso ensina os fundamentos da programação em C++ e não em uma linguagem que oculte os tipos e a memória.
- Calcular, a partir das horas estimadas por unidade, a dedicação que o curso ou uma parte dele exige, e planejar com ela um ritmo de estudo pessoal.
Propósito
O curso ensina a escrever programas corretos a partir do zero: a converter um problema enunciado em palavras em uma sequência precisa de instruções, a escolher como representar os dados, a governar a ordem em que o escrito é executado e a organizar o código em funções com uma interface clara. Se isso é assim, o seu objeto não é uma linguagem, mas a própria programação: pensar um algoritmo, representar os dados, decompor um problema e raciocinar sobre a correção e o custo do que se escreve. Por isso se chama “Fundamentos da Programação”, e por isso cada construção de C++ é apresentada junto com o problema que resolve e com o modo de raciocinar sobre ela, e nunca como um catálogo de sintaxe.
C++ é, portanto, o instrumento do curso e não o seu fim. Ora, um instrumento não é indiferente ao que com ele se aprende, e a escolha deste, que à primeira vista parece a mais difícil, é deliberada; a seção seguinte a justifica. Convém adiantar, no entanto, a sua consequência mais visível: cada síntese de unidade contém uma seção fixa, “O que vale em qualquer linguagem”, que separa o aprendido da sua forma em C++ e diz como se expressa, ou o que muda, em outras linguagens. Disso se segue que o estudante que terminar o curso não saberá apenas escrever em C++, mas reconhecer em qualquer linguagem as mesmas ideias com outra roupagem.
Por que C++ e não uma linguagem mais amigável
Há linguagens de curva mais suave, como Python, nas quais um primeiro programa útil se escreve em poucas linhas, sem declarar tipos, sem compilar e sem perguntar onde vive um dado. Se o propósito fosse escrever logo programas que funcionam, esse seria o caminho. O propósito deste curso, ao contrário, é entender o que um programa faz, e para isso convém uma linguagem que não oculte a máquina. C++ obriga a ver seis coisas que as linguagens mais cômodas resolvem em silêncio:
- Os tipos. Cada dado é declarado com um tipo, que fixa que valores pode assumir, quanto ocupa e que operações admite; o compilador rejeita o que não concorda antes de executar qualquer coisa.
- A compilação. Escrever, compilar, ligar e executar são momentos distintos, e cada erro pertence a um deles; saber a qual é metade da sua correção.
- A memória. Uma variável é uma posição com nome, com um tempo de vida e um escopo; uma referência é outro nome para a mesma posição, e uma referência a uma posição que já não existe é um erro real.
- O custo de copiar. Passar um vetor a uma função pode copiá-lo inteiro; escolher entre valor e referência é uma decisão do programador, e não da máquina.
- Os limites dos números. Um inteiro de 32 bits não passa de , e um número de ponto flutuante não guarda com exatidão.
- O comportamento indefinido. O que o padrão não define (sair de um arranjo, estourar um inteiro com sinal, ler uma variável não inicializada) não produz um erro garantido, mas qualquer coisa; por isso o curso compila sempre com avisos e com detectores (sanitizers).
O exemplo seguinte o mostra em pequeno. O programa calcula os fatoriais de a em uma variável de tipo int. Em Python, cujos inteiros crescem sem limite, o mesmo cálculo imprimiria sem queixa ; em C++, o produto de por não cabe em um int, e o detector de comportamento indefinido, com o qual o curso compila todos os seus exemplos, detém o programa na linha exata:
#include <print>int main(){ int factorial{1}; for (int n{1}; n <= 15; ++n) { factorial = factorial * n; // o produto cabe em um int? std::println("{}! = {}", n, factorial); }}1! = 12! = 23! = 64! = 245! = 1206! = 7207! = 50408! = 403209! = 36288010! = 362880011! = 3991680012! = 479001600main.cpp:7:31: runtime error: signed integer overflow: 479001600 * 13 cannot be represented in type 'int'O programa terminou com o código 1.
Se isso é assim, a linguagem obrigou a fazer uma pergunta que a outra teria ocultado: quanto cabe no tipo escolhido e o que fazer quando não cabe. Nenhuma das duas respostas é melhor em abstrato; o que importa é saber que a pergunta existe. A aula sobre os inteiros e sua representação a responde, e a seção sobre o comportamento indefinido de cada síntese volta a ela.
Disso se segue uma assimetria, que é a razão de fundo da escolha. Quem aprende os fundamentos em C++ entende depois o que as linguagens mais cômodas fazem por ele: o coletor de lixo, os inteiros sem limite, a verificação dos índices, a conversão silenciosa dos tipos. Quem aprende primeiro em uma delas, ao contrário, deixa essas camadas sem ver, e tropeça nelas mais tarde, quando um programa real falha por uma das causas que a linguagem lhe havia escondido. Portanto, o caminho que o curso escolhe é mais exigente no começo, mas mais transferível: o que se aprende aqui vale em qualquer linguagem, e o que se aprende em uma linguagem que o oculta nem sempre vale aqui.
Ora, C++ é uma linguagem grande, e um curso de fundamentos deve resistir à tentação de ensiná-la inteira. Este primeiro curso se limita à programação estruturada (dados, expressões, controle de fluxo, sequências, texto e funções) no padrão C++23, com as suas formas modernas: a saída com std::println, as sequências com std::array e std::vector, o texto com std::string, os algoritmos da biblioteca na sua forma de ranges. Deixa para Programação em C++ II o que exige essa base: 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.
Público e conhecimentos prévios
O curso se dirige a quem nunca programou, de qualquer programa de estudo e desde o primeiro ano: estudantes de informática que precisam de um fundamento firme antes dos cursos de estruturas de dados e de sistemas, estudantes de engenharia e de ciências que precisam calcular com um computador sem confiar nele às cegas, e estudantes de matemática que querem ver os seus algoritmos convertidos em programas que se executam.
É um curso de nível 1, sem pré-requisitos e autocontido. Pressupõe apenas duas coisas: a aritmética escolar, com a divisão inteira e o seu resto, e o manejo elementar de um computador (criar uma pasta, salvar um arquivo, abrir um programa). O que usa da representação binária, do raciocínio por casos, da lógica das condições ou da indução, ensina no lugar em que precisa: o sistema binário, na aula sobre os inteiros; as leis de De Morgan, na aula sobre as relações e a lógica; a indução, na aula sobre a recursão. As remissões a outros cursos do site que aparecem nas aulas são, portanto, aprofundamentos, e não requisitos.
Aonde conduz
Do anterior se segue o lugar do curso no site. Não tem pré-requisitos e é meta de dois programas de estudo, Informática e Computação, e Engenharia, porque em ambos a programação é ao mesmo tempo ferramenta e objeto. Convém, por isso, que seja um dos primeiros cursos desses programas, junto com LaTeX para a Redação Acadêmica e Lógica Matemática I.
Tem um curso complementar, que pode ser seguido antes, em paralelo ou depois. Lógica Matemática I estuda como teoria o que aqui se usa como prática: as condições compostas, as tabelas de verdade e as leis de De Morgan da unidade 3, e a ideia de demonstrar que um procedimento é correto, que neste curso toma a forma do invariante de um laço e da indução sobre uma recursão. Álgebra e Geometria I, por sua vez, demonstra os resultados sobre os números que o curso programa: a divisão euclidiana, o algoritmo de Euclides, os sistemas de numeração e a regra de Horner. E LaTeX para a Redação Acadêmica ensina, na sua aula Escrever em equipe, o controle de versão com Git, que este curso recomenda usar desde o primeiro programa.
Ora, o curso deixa deliberadamente de fora o que exige a sua base. A sua continuação prevista é Programação em C++ II, que tratará dos ponteiros e da memória dinâmica, das classes e dos objetos, dos templates, das funções anônimas, das exceções e da biblioteca padrão em profundidade. Donde o curso não é um primeiro trecho de um manual de C++, mas um curso completo de fundamentos, que pode encerrar-se aqui; quem seguir, por outro lado, encontrará no curso II a mesma disciplina aplicada a programas cujo tamanho já não permite prescindir dela.
Objetivos de aprendizagem globais
Os objetivos seguintes descrevem o que um estudante que conclua o curso deve ser capaz de fazer. Cada um é formulado como um desempenho observável, de modo que possa ser verificado com uma tarefa concreta; cada aula de conteúdo declara, por sua vez, os seus próprios objetivos, que servem a um ou a vários dos globais, e a aula de encerramento mostra em que unidades e aulas se trabalha cada um. Os sete objetivos são numerados para que possam ser citados.
- Objetivo 1. Resolver problemas com programas: especificar o que entra e o que sai, projetar um algoritmo, rastreá-lo à mão, e escrevê-lo, compilá-lo, executá-lo e depurá-lo, interpretando as mensagens e os avisos do compilador.
- Objetivo 2. Escolher o tipo adequado para cada dado e raciocinar sobre os limites da sua representação: o intervalo dos inteiros, o estouro, o arredondamento do ponto flutuante e a codificação do texto.
- Objetivo 3. Construir expressões corretas, conhecendo a precedência, as conversões de tipo, os efeitos colaterais e o que o padrão deixa indefinido.
- Objetivo 4. Projetar o controle de fluxo com decisões e laços corretos, que terminam, e justificar a sua correção com um invariante.
- Objetivo 5. Decompor um problema em funções com interfaces claras, escolher como passar os parâmetros, e resolver problemas por recursão.
- Objetivo 6. Representar e processar dados compostos (sequências, tabelas, registros, texto e arquivos) com os algoritmos básicos e com a biblioteca padrão, estimando o seu custo.
- Objetivo 7. Organizar programas maiores em vários arquivos, especificá-los com uma pré-condição e uma pós-condição, testá-los de maneira sistemática e argumentar a sua correção.
Cinco objetivos têm a sua unidade: o 2, a dos dados e dos tipos; o 3, a das expressões; o 4, a do controle de fluxo; o 5, a das funções; e o 6, a dos dados compostos, que se prolonga na do texto e dos arquivos, onde o objetivo 2 reaparece com a codificação UTF-8. Os outros dois, ao contrário, percorrem o curso inteiro. O objetivo 1 tem como principal a primeira unidade, que ensina o ciclo de especificar, escrever, compilar e executar, e a aula sobre a depuração da última; mas exercita-se em todas, porque cada programa do curso é compilado, executado e corrigido. O objetivo 7 tem como principal a última unidade, a dos programas maiores; mas começa no guia de estilo da primeira, segue nas constantes da segunda, toma forma nos contratos da quinta, que desde então acompanham toda função, e nos invariantes da quarta e da sexta. Disso se segue que a sua consecução não pode ser atribuída a uma só unidade, e que convém cultivá-los ao longo do curso inteiro.
Conteúdos
O curso se organiza em dez unidades: esta apresentação, oito unidades de conteúdo e um encerramento. Cada unidade de conteúdo se abre com uma aula de introdução, que apresenta as suas aulas, o que dá por sabido e o problema que resolve, e começa com uma avaliação de entrada; fecha-se com uma aula de síntese, que reconstrói a cadeia de conceitos da unidade, separa o que vale em qualquer linguagem da sua forma em C++, reúne o comportamento indefinido da unidade, repete em uma avaliação de saída as destrezas da de entrada e propõe desafios de dificuldade superior à dos problemas das aulas.
Unidade 0. Apresentação do curso
Consta desta aula, que fixa o propósito, a escolha da linguagem, os objetivos globais, os conteúdos, a dedicação e o desenho do curso.
Unidade 1. Primeiros passos
O seu objetivo é levar o estudante de um problema enunciado em palavras até um programa que compila, é executado, lê dados e escreve resultados, sabendo o que cada ferramenta fez no caminho. Começa sem código, porque o algoritmo precede o programa; ao final, o estudante ainda sabe pouco de C++, mas sabe como se trabalha com ele.
- Introdução: primeiros passos.
- Do problema ao algoritmo: a especificação de entradas e saídas, os passos numerados, o rastreamento à mão, a sequência, a decisão e a repetição.
- Programas, compiladores e C++: o pré-processamento, a compilação e a ligação; o compilado frente ao interpretado; os padrões da linguagem.
- Instalar o ambiente em Windows, macOS e Linux: os três guias completos, o compilador, o Visual Studio Code e a sua extensão de C++, a verificação e as falhas frequentes.
- Compilar, executar e configurar: as opções do curso, os erros e os avisos, os detectores, a tarefa de compilação do editor e a codificação do console.
- Anatomia de um programa: a inclusão,
main, as instruções, os blocos, os comentários e o guia de estilo do curso. - Entrada, saída e erros:
std::cin,std::printlne as especificações de formato, a entrada malformada e a classificação dos erros. - Síntese e desafios: primeiros passos.
Unidade 2. Dados e tipos
O seu objetivo é ensinar que todo dado vive na memória com um tipo que fixa que valores pode assumir, quanto ocupa e que operações admite, e que um número do programa não é um número da matemática, mas uma representação com limites.
- Introdução: dados e tipos.
- Variáveis e memória: a declaração e a inicialização com chaves, a atribuição, o rastreamento do estado, os nomes e a variável não inicializada.
- Os inteiros e sua representação: as bases 2 e 16, o intervalo de cada tipo, o complemento de dois e o estouro com sinal e sem sinal.
- Os números de ponto flutuante: por que não é exato, o arredondamento acumulado, a comparação com tolerância, o infinito e o valor não numérico.
- Caracteres, booleanos, conversões e constantes: o código de um caractere, as conversões implícitas e explícitas, a rejeição das conversões que perdem informação,
const,constexpreauto. - Síntese e desafios: dados e tipos.
Unidade 3. Expressões e operadores
O seu objetivo é ensinar a construir expressões cujo valor se possa prever com certeza: que operação se faz primeiro, de que tipo é o resultado, que efeitos colaterais tem e que expressões carecem de significado. A unidade ainda não tem decisões nem laços: as condições são avaliadas e impressas.
- Introdução: expressões e operadores.
- Aritmética: o quociente e o resto com negativos, a árvore de uma expressão, a precedência, a associatividade e o tipo do resultado.
- Relações e lógica: as condições compostas, a sua negação por De Morgan, o curto-circuito e o erro de
1 < x < 5. - Atribuição, efeitos colaterais e comportamento indefinido: o valor e o efeito de uma expressão, os incrementos, a ordem de avaliação e o catálogo do que o padrão não define.
- Bits e biblioteca matemática: os operadores bit a bit, os deslocamentos, as máscaras,
<cmath>e as constantes de<numbers>. - Síntese e desafios: expressões e operadores.
Unidade 4. Controle de fluxo
O seu objetivo é ensinar a governar a ordem de execução com decisões e laços, e a raciocinar sobre a sua correção: que cada caso seja atendido, que cada laço faça o que deve e que termine. Realiza o que a primeira aula do curso anunciou: a decisão e a repetição, agora escritas e verificadas.
- Introdução: controle de fluxo.
- Decisões:
ifeelseencadeados e aninhados, os casos disjuntos e exaustivos,switchcomenum classe as suas armadilhas. - Laços:
while,doefor, o rastreamento de um laço, a conversão entre as suas formas e os laços aninhados. - Projetar laços corretos: os padrões de contador, acumulador, máximo e sentinela, o invariante, a terminação e um primeiro contato com o depurador.
- Algoritmos numéricos: a primalidade, o algoritmo de Euclides, a mudança de base, a regra de Horner e a bissecção, cada um com a sua justificativa.
- Síntese e desafios: controle de fluxo.
Unidade 5. Funções
O seu objetivo é ensinar a decompor um problema em partes com nome, cada uma com uma interface e um contrato, e a resolver problemas por recursão. Converte os programas longos da unidade 4 em programas compostos de partes que se verificam uma a uma.
- Introdução: funções.
- Funções: a declaração, a definição e a chamada, a pilha de chamadas, a pré-condição e a pós-condição, e a função que não retorna valor.
- Parâmetros e escopo: a passagem por valor, por referência e por referência constante, os resultados múltiplos com vinculações estruturadas, o escopo e a duração das variáveis.
- Projetar com funções: o refinamento sucessivo, a interface antes do corpo, a regra “uma função, uma tarefa” e a sobrecarga.
- Recursão: o caso base e o recursivo, a correção e a terminação por indução, a pilha e o custo da recursão.
- Síntese e desafios: funções.
Unidade 6. Dados compostos
O seu objetivo é ensinar a representar coleções de dados e a processá-las com os algoritmos básicos, escritos à mão e tomados da biblioteca, estimando quanto custam. Leva do dado isolado à coleção, e da pergunta “está correto?” à pergunta “quanto custa?”.
- Introdução: dados compostos.
- Arranjos:
std::array, o percurso com índices e por intervalo, o índice dentro dos limites e os arranjos de C como contraste. - Vetores:
std::vector, a leitura de uma série de comprimento desconhecido, a acumulação, a filtragem e a transformação, o tamanho e a capacidade. - O custo de um algoritmo: a contagem das operações dominantes, as ordens de crescimento e a medição do tempo.
- Buscar e ordenar: a busca linear e a binária, a ordenação por seleção e por inserção com os seus invariantes, e os algoritmos da biblioteca.
- Tabelas: as tabelas bidimensionais, os seus percursos por linhas e por colunas, a transposta, o produto e a tabela em um vetor plano.
- Registros:
struct, os inicializadores designados, os registros como parâmetros e a ordenação por um campo. - Síntese e desafios: dados compostos.
Unidade 7. Texto e arquivos
O seu objetivo é ensinar a manejar o texto como dado e a fazer com que um programa leia e escreva arquivos sem quebrar diante de uma entrada malformada. Ao final, o estudante pode escrever programas que processam dados reais, com acentos e erros incluídos.
- Introdução: texto e arquivos.
- Cadeias de caracteres:
std::stringe as suas operações,npos, as visõesstd::string_viewe as strings de C como contraste. - O texto não é ASCII: a codificação UTF-8, os bytes e os caracteres, e as operações que quebram o texto.
- Ler bem:
std::getline, o estado do fluxo, a recuperação após um dado inválido e a validação comstd::from_chars. - Arquivos de texto: abrir, ler linha por linha, escrever, acrescentar, e processar um arquivo de valores separados por vírgulas.
- Síntese e desafios: texto e arquivos.
Unidade 8. Programas maiores
O seu objetivo é ensinar a organizar, verificar e depurar programas que já não cabem em um arquivo nem na cabeça. Fecha o círculo que a primeira aula abriu: especificar, construir, verificar; a sua síntese termina com um projeto final que reúne o curso inteiro.
- Introdução: programas maiores.
- Vários arquivos e bibliotecas próprias: o cabeçalho e a implementação, as guardas de inclusão, a regra de uma definição e a compilação separada.
- Testar: os casos de teste a partir da especificação, os testes automáticos,
assertestatic_assert. - Depurar: o depurador do Visual Studio Code, os pontos de interrupção, a pilha de chamadas e uma estratégia sistemática para localizar um erro.
- Síntese e desafios: programas maiores.
Unidade 9. Encerramento do curso
Consta da aula Balanço final de Programação em C++ I, que recorda os sete objetivos globais, mostra em uma figura em que unidades e aulas se trabalha cada um, reúne por objetivo a primeira tentativa das avaliações de saída e indica para onde continua o estudo.
Dedicação e créditos
A dedicação de um curso não se mede pelas horas de exposição, que num curso assíncrono não existem, mas pelo trabalho total do estudante: ler, escrever e compilar os exemplos, resolver problemas e revisar. A estimativa segue o mesmo método em todos os cursos do site: conta o tempo de leitura do texto de cada aula, incluído o código dos seus exemplos, a cem palavras por minuto, vinte minutos por problema resolvido, trinta e cinco por problema proposto, quarenta e cinco por desafio e doze por avaliação de entrada ou de saída, e acrescenta uma margem de um décimo para a revisão.
Resultados
As aulas do curso contêm no conjunto problemas resolvidos, problemas propostos e desafios, além de dezesseis avaliações de unidade e setenta exercícios breves que o site revisa no mesmo instante. A dedicação estimada por unidade, arredondada à hora, é a seguinte:
- Unidade 0, apresentação do curso: hora.
- Unidade 1, primeiros passos: horas.
- Unidade 2, dados e tipos: horas.
- Unidade 3, expressões e operadores: horas.
- Unidade 4, controle de fluxo: horas.
- Unidade 5, funções: horas.
- Unidade 6, dados compostos: horas.
- Unidade 7, texto e arquivos: horas.
- Unidade 8, programas maiores: horas.
- Unidade 9, encerramento do curso: menos de hora.
O total é de cerca de horas de trabalho do estudante. Convém ler esse número como o que é: uma estimativa para um estudante que escreve e compila todos os exemplos e resolve todos os problemas e desafios. Quem já tiver programado em outra linguagem empregará bastante menos nas primeiras unidades; quem nunca tiver instalado um programa nem lido uma mensagem de erro pode precisar de mais, sobretudo na unidade 1, que é também, com a dos dados compostos, a mais extensa.
Ora, o número é nominal: é o que fixa os créditos do curso, e supõe uma leitura em ritmo constante e três quartos de hora por desafio. Enquanto não for medido com estudantes reais, convém acompanhá-lo de uma faixa realista. Se a leitura avançasse à metade do ritmo suposto, como acontece quando cada exemplo é escrito à mão, compilado e alterado para ver o que muda, e cada desafio exigisse setenta e cinco minutos em vez de quarenta e cinco, o mesmo método daria cerca de horas. Portanto, a dedicação esperável situa-se entre cerca de e cerca de horas. O extremo superior é uma cota prudente, não uma medição; a faixa será corrigida quando se conhecer o tempo que empregam os que estudam o curso, e até então os créditos são calculados com o número nominal.
Ritmo sugerido
Para nomear os ritmos, este plano usa o mesmo critério que os demais planos do site: a dedicação integral é a de um ano acadêmico de créditos, cerca de horas repartidas em cerca de quarenta semanas, isto é, cerca de horas semanais, e a dedicação parcial é a metade, cerca de horas semanais. Disso se segue um ritmo recomendado de um semestre de dezesseis semanas, com cerca de horas semanais de estudo, algo menos da terça parte da dedicação integral; com a faixa realista, de a horas semanais. Esse semestre pode ser compartilhado com Lógica Matemática I, cujas tabelas de verdade e cuja ideia de demonstração se reconhecem nas condições e nos invariantes deste curso.
Um ritmo intensivo, de cerca de horas semanais, isto é, dedicação parcial, completa o curso em nove ou dez semanas. Um ritmo mais folgado, de cerca de horas semanais, o leva a dois semestres, que se repartem quase pela metade: as unidades 0 a 4, do algoritmo ao controle de fluxo, ocupam cerca de horas, e as unidades 5 a 9, das funções ao projeto final, cerca de . O corte é natural: ao terminar a unidade 4, o estudante já escreve programas completos em um só main, e a segunda metade lhe ensina a organizá-los.
Créditos
Os créditos deste site medem a dedicação total que um curso exige de quem o estuda (a leitura, os problemas, os desafios e a revisão), e não as horas de aula. Um crédito equivale a cerca de horas de trabalho, e um ano de dedicação integral, a créditos, isto é, a cerca de horas; é o mesmo critério com que a subseção anterior nomeia os ritmos de estudo.
Ora, dividindo as horas estimadas por , obtém-se 6,8, que se arredonda para . Admitindo-se para o crédito uma faixa de a horas de trabalho, o número de créditos do curso fica compreendido entre 6,3 e 7,5:
Portanto, o curso tem créditos, algo mais da nona parte de um ano de dedicação integral. O número não é um descuido: o curso dura o que deve durar para ensinar os fundamentos, e não foi recortado para se ajustar a um número redondo de créditos.
A sua utilidade é prática: permitem comparar entre si a carga dos cursos do site e decidir quantos convém estudar ao mesmo tempo sem ultrapassar o tempo disponível. Quem dispuser, por exemplo, de dedicação parcial durante um semestre de dezesseis semanas, isto é, de cerca de horas, pode abordar cursos que somem cerca de créditos; com a dedicação integral do mesmo semestre, cerca de .
Estes créditos são uma medida própria do site para planejar o estudo: não correspondem a nenhum sistema oficial de créditos nem implicam o reconhecimento acadêmico de nenhuma instituição.
Desenho do curso
Modalidade
O curso é assíncrono, on-line e de ritmo autônomo: não tem datas, sessões ao vivo nem prazos, e cada estudante avança na velocidade que a sua preparação e o seu tempo lhe permitem. Será oferecido nos catorze idiomas do site. Os identificadores dos programas estão em inglês e são iguais em todas as versões; os comentários e as mensagens que os programas mostram, ao contrário, estão no idioma da página, de modo que cada versão é compilada e executada com a sua própria saída. As aulas declaram que outras aulas convém ter estudado antes, de modo que a ordem recomendada é explícita.
A estrutura de uma aula
Todas as aulas de conteúdo seguem a mesma estrutura. Começam com um resumo e com uma lista de objetivos de aprendizagem próprios, formulados como desempenhos observáveis. Segue-se a exposição, cujo núcleo são os programas. Cada programa completo do curso foi compilado, antes de construir o site, com o padrão C++23, com todos os avisos ativados e com os detectores de erros de memória e de comportamento indefinido, e foi executado; o que se publica sob o código é a sua saída real, ou as mensagens reais do compilador quando o que se ensina é um erro ou um aviso, ou o relatório real do detector quando o programa incorre em um comportamento indefinido. Se isso é assim, nenhuma saída do curso está escrita à mão: o site verifica, ao ser construído, que cada programa tenha guardada a saída da sua versão atual, e não seria publicado se faltasse a algum. Outras figuras animam passo a passo o que o texto raciocina: as posições da memória com o seu nome e o seu valor, a pilha de chamadas, o percurso de um laço, os bits de um número.
Fecham cada aula três problemas resolvidos, com a sua solução passo a passo, e três problemas propostos, cada um com uma dica recolhida e, depois, a resposta, às vezes acompanhada de uma solução desenvolvida que convém abrir só depois de ter escrito a própria. Os problemas exigem uma ideia, nunca a repetição mecânica de um exemplo, e usam apenas o que foi ensinado até essa aula. Cada aula inclui, além disso, dois exercícios breves que o site revisa no mesmo instante: em um se prevê a saída exata de um programa, e no outro se completa ou se corrige um fragmento. Convém saber o que faz e o que não faz essa revisão: o site não compila o código do estudante, mas verifica com padrões que o essencial esteja presente e que o erro procurado tenha desaparecido. Portanto, um exercício aprovado no site ainda deve ser compilado e executado no computador próprio, que é o único juiz definitivo.
As aulas de introdução e de síntese têm uma estrutura própria. A introdução apresenta a unidade, as suas aulas e o fio que as une, o que dá por sabido e o problema que resolve, e contém a avaliação de entrada. A síntese reconstrói a cadeia de conceitos da unidade, com a aula em que se estabelece cada elo e o que cada um usa; contém duas seções fixas, “O que vale em qualquer linguagem” e “O comportamento indefinido da unidade”, a avaliação de saída e seis desafios (dez na última unidade, cujo projeto final se decompõe em etapas), cada um com dica, resposta e, quando o raciocínio o merece, uma solução desenvolvida recolhida.
O leitor de voz
Cada aula pode ser ouvida em voz alta com o leitor do site, que usa as vozes do próprio dispositivo: o texto é lido tal como está escrito, o código citado nele é pronunciado com sentido e os blocos de código são anunciados, sem ser lidos caractere por caractere. Isso permite revisar a exposição longe da tela; os programas, ao contrário, sempre pedem o editor.
Avaliação
O curso não atribui nota: a sua avaliação é formativa e se apoia na autoavaliação. Os problemas propostos permitem verificar a consecução dos objetivos de cada aula, e os desafios, o dos objetivos de cada unidade; em todos eles, o juiz último é o compilador, com os seus avisos e os seus detectores, porque um programa que compila sem avisos, passa nos seus casos de teste e não desperta nenhum detector é uma prova que não admite discussão, embora, como ensina a aula sobre os testes, não uma demonstração.
A isso acrescentam-se as avaliações de unidade. A de entrada, na introdução, é uma autoavaliação breve que mede o ponto de partida; a de saída, na síntese e antes dos desafios, mede o alcançado e é comparada com a de entrada. Ambas são corrigidas no próprio navegador: cada resposta recebe uma explicação, cada erro típico, uma observação que o identifica, e cada pergunta remete à aula que convém revisar. Nenhuma delas atribui nota nem certifica, e os seus resultados são guardados apenas no navegador do estudante; a validação das habilidades adquiridas será feita mais adiante noutra plataforma. O balanço final reúne a primeira tentativa de cada avaliação de saída num perfil por objetivo global.
Os assistentes de inteligência artificial
Existem hoje assistentes de inteligência artificial capazes de escrever em segundos a solução de quase qualquer problema deste curso. Convém dizer com clareza que lugar lhes corresponde, e a razão é a mesma que justifica todo o resto: o curso não treina a produção de programas, mas uma capacidade, a de pensar um problema até convertê-lo em um programa correto. Se isso é assim, delegar o exercício a um assistente anula o exercício, do mesmo modo que olhar a resposta de um problema antes de tentá-lo o converte em leitura. O programa resultante pode estar correto; quem o entrega, ao contrário, não aprendeu a escrevê-lo, e não saberá fazê-lo quando o assistente errar, que é precisamente quando mais falta faz.
Disso se segue uma regra de uso, e não uma proibição. Um assistente serve para explicar uma mensagem de erro que não se entende, para propor casos de teste em que não se havia pensado, para comparar uma solução própria já terminada com outra, ou para esclarecer uma ideia da exposição de outro ângulo. Não serve para escrever os exercícios, os problemas nem os desafios. E em todos os casos rege um princípio que vale para qualquer código alheio, venha de um assistente, de um fórum ou de um colega: lê-se, testa-se e entende-se antes de ser aceito. Um assistente pode produzir código que compila e parece correto, mas que incorre em comportamento indefinido ou usa uma forma antiga da linguagem; o estudante que tiver feito o curso saberá reconhecê-lo, e o que tiver delegado o curso, não.
Como estudar este curso
O curso foi pensado para ser estudado em ordem. Cada unidade pressupõe as anteriores: as expressões se escrevem com os tipos da segunda unidade, os laços com as expressões da terceira, as funções encapsulam os laços da quarta, e os dados compostos se processam com funções; pular uma aula obriga, cedo ou tarde, a voltar a ela.
A regra principal é uma só: escrever e compilar cada exemplo. A programação não se aprende lendo, mas escrevendo, compilando e lendo o que o compilador responde. Por isso, o estudante instala o seu próprio ambiente seguindo a aula Instalar o ambiente em Windows, macOS e Linux, e reproduz cada programa no seu Visual Studio Code, com as opções que a aula Compilar, executar e configurar ensina a fixar; quem usar um computador em que não possa instalar programas dispõe, de maneira provisória, de um compilador on-line, que a aula de instalação descreve. Convém escrever os exemplos à mão em vez de copiá-los, porque a mão retém o que o olho deixa passar; convém prever a saída de cada programa antes de executá-lo, porque a diferença entre o previsto e o obtido é exatamente o que falta aprender; e convém ler cada aviso do compilador como uma pergunta que merece resposta, e não como um ruído que se tolera. Depois que um programa funcionar, convém além disso alterá-lo de propósito (apagar um ponto e vírgula, mudar um tipo, sair de um vetor) e ler o que dizem o compilador ou o detector, porque cada erro provocado é um erro que depois se reconhecerá.
Cada unidade tem dois pontos de controle. A avaliação de entrada, na introdução, é o ponto de partida: convém respondê-la antes de estudar a unidade, sem consultar nada, e anotar as aulas às quais remetem os erros. A avaliação de saída, na síntese e antes dos desafios, é o contraste: responde-se ao terminar as aulas, também sem consultar, e compara-se com a de entrada. Em ambas conta a primeira tentativa, que é a que se compara e a que o perfil do balanço final reúne. Nos problemas propostos e nos desafios, convém abrir a dica só quando a tentativa se tiver esgotado, e a resposta só no final, para conferir. Um problema cuja resposta foi consultada antes de compilar a própria não foi resolvido, mas lido.
Controle de versão
Por último, convém guardar o trabalho do curso com um sistema de controle de versão desde o primeiro programa. Git registra cada estado de uma pasta de trabalho, permite voltar a qualquer um deles e mostra o que mudou entre dois; para quem programa, isso significa poder experimentar sem medo de perder o que funcionava, e localizar, comparando versões, a mudança que introduziu um erro, o que leva à história do programa a bissecção que a aula sobre a depuração ensina. O curso não ensina Git, porque outro curso do site já o faz: a aula Escrever em equipe, do curso LaTeX para a Redação Acadêmica, explica o fluxo mínimo, que arquivos se guardam e quais se excluem, e como se resolve um conflito. O que lá vale para as fontes de um documento vale igualmente para as de um programa; basta excluir, em lugar dos arquivos auxiliares de LaTeX, os executáveis e os arquivos-objeto que a compilação regenera.