Resumo
Esta aula encerra a terceira unidade do curso, dedicada às expressões e seus operadores. Reconstrói a cadeia de conceitos que vai do operador aritmético à função de biblioteca, passando pela árvore da expressão e o tipo de cada nó, as condições e sua álgebra, o curto-circuito, o efeito colateral e a ordem de avaliação, e os bits; separa o que disso vale em qualquer linguagem do que é próprio de C++; reúne o comportamento indefinido da unidade, com o que o compilador detecta, o que o detector detecta e o que ninguém detecta; repete na sua avaliação de saída as habilidades da avaliação de entrada; e termina com seis desafios que combinam a unidade inteira.
Objetivos de aprendizagem
- Prever o valor, o tipo e o efeito de qualquer expressão do curso, a partir da sua árvore e das conversões em cada nó.
- Escrever e negar condições compostas, e usar o curto-circuito para proteger uma operação que de outro modo careceria de significado.
- Reconhecer as expressões que carecem de significado (o catálogo do comportamento indefinido da unidade), dizer que ferramenta detecta cada uma e reescrevê-las sem ele.
- Escolher entre a aritmética, os operadores bit a bit e a biblioteca matemática para um cálculo dado, e justificar a escolha.
- Separar, no que foi aprendido na unidade, o que vale em qualquer linguagem do que é próprio de C++.
O que a unidade alcançou
A unidade propôs-se 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 não têm significado. O propósito cumpriu-se apoiando-se só no que a introdução declarou como sabido: os tipos da unidade 2, seus intervalos e suas conversões. O programa das seis perguntas com que a introdução colocou o problema pode agora ser lido como o compilador o lê, e corrigido expressão por expressão.
Aritmética
A aula Aritmética estabeleceu o comportamento exato dos cinco operadores aritméticos. A divisão inteira trunca em direção a zero e cumpre a identidade (a / b) * b + a % b == a sempre que o quociente tenha significado, de modo que o resto, quando não é zero, tem o sinal do dividendo; daí que -7 / 2 valha e -7 % 2 valha , e que a imparidade se pergunte com n % 2 != 0. Relacionou-o com o resto euclidiano, ((a % b) + b) % b para , e usou ambos para decompor quantidades. Ensinou a desenhar a árvore de uma expressão segundo a precedência e a associatividade, e a decidir o tipo em cada nó pelas conversões aritméticas usuais. Fechou com os quocientes sem significado (a divisão inteira por zero e o menor inteiro dividido por ) e com o estouro de um resultado intermediário, que basta para o comportamento indefinido ainda que o resultado final caiba.
Relações e lógica
A aula Relações e lógica ensinou que uma condição é uma expressão de tipo bool, com seu lugar na árvore: as relações ligam menos que a aritmética, && mais que ||, e ! mais que todas. Ensinou a traduzir enunciados em condições e a reconhecer as que compilam com outro significado, como 1 < x < 5 e day == 6 || 7. Mostrou que && e || avaliam seu segundo operando só se o primeiro não decide, e que esse curto-circuito permite proteger uma operação com uma guarda à sua esquerda. Terminou com as leis de De Morgan, que negam uma condição composta, e com seu limite: com um valor não numérico, !(a < b) não equivale a a >= b.
Atribuição, efeitos colaterais e comportamento indefinido
A aula Atribuição, efeitos colaterais e comportamento indefinido distinguiu o valor de uma expressão do seu efeito: a atribuição é uma expressão que vale o que foi atribuído e muda uma variável, e x++ vale o valor anterior enquanto ++x vale o novo. Mostrou que a árvore de uma expressão não fixa a ordem em que se calculam seus ramos, de modo que dois efeitos sobre uma mesma variável, ou um efeito e uma leitura, sem ordem entre eles, deixam a expressão sem significado, e precisou o que C++17 ordenou e o que deixou sem especificar. Reuniu o catálogo dos quatro graus (definido, definido pela implementação, não especificado e indefinido), explicou que o compilador raciocina supondo que o programa não tem comportamento indefinido, e disse, para cada caso do catálogo, que ferramenta o detecta.
Bits e biblioteca matemática
A aula Bits e biblioteca matemática ensinou que um inteiro é também uma sequência de bits: &, | e ^ aplicam um conectivo a cada coluna, ~ inverte todos os bits, e os deslocamentos multiplicam e dividem por potências de 2, com a condição de que a quantidade do deslocamento não seja negativa nem alcance a largura do tipo. Com eles construiu as máscaras que consultam, ligam, desligam e alternam um bit. Advertiu que esses operadores ligam menos que as relações, de modo que x & 1 == 0 não pergunta o que parece, e que ^ não é a potência. Fechou com a biblioteca: <cmath>, <numbers>, <numeric> e <bit> dão cálculos corretos e testados, com suas próprias precondições, como a do valor absoluto, que não existe para o menor inteiro.
Carregando o conteúdo…