Resumen
Esta clase abre la tercera unidad del curso, dedicada a las expresiones y sus operadores. Explica para qué sirve la unidad: enseñar a construir expresiones cuyo valor se pueda predecir con certeza, sabiendo qué operación se hace primero, de qué tipo es el resultado, qué efectos secundarios tiene y qué expresiones no tienen significado; presenta sus cuatro clases y el hilo que las une, desde la aritmética entera y real hasta los bits y la biblioteca matemática, pasando por las condiciones y por el catálogo del comportamiento indefinido; recuerda lo que la unidad da por sabido de la segunda, que es el tipo de cada dato, sus límites y sus conversiones; formula el problema que la unidad resuelve, el de un programa que compila sin un solo aviso y cuyas seis respuestas a seis preguntas escolares son todas equivocadas; y muestra adónde conduce, en las unidades siguientes y en el curso Programación en C++ II.
Objetivos de aprendizaje
- Describir la secuencia de contenidos de la unidad y explicar qué aporta cada clase a la siguiente.
- Recordar lo necesario de la unidad 2 (los tipos enteros y reales, sus rangos, el desbordamiento y las conversiones) y repasarlo si hace falta.
- Anticipar, con un ejemplo, que el valor de una expresión depende de reglas de evaluación (la precedencia, el tipo de los operandos, el orden de los efectos) que no siempre coinciden con las de la matemática escolar.
- Reconocer qué se espera saber hacer al terminar la unidad, y distinguirlo de lo que se aprenderá en las unidades siguientes.
Evaluación de entrada
Antes de recorrer la unidad conviene medir el punto de partida. Esta evaluación es una autoevaluación: no se califica, y su único propósito es orientar el estudio. Las cuatro primeras preguntas comprueban lo que la unidad da por sabido de la segunda: la división entre enteros, la escritura en base 2, la resta sin signo y el desbordamiento con signo. Las seis siguientes tocan, en el orden de las clases, las ideas centrales de la unidad, y varias de ellas parten de la matemática escolar o de la lógica elemental. Nadie está obligado a acertarlas todavía, y en dos de ellas «todavía no lo sé» es una respuesta honesta: cada respuesta, acertada o no, explica el punto y nombra la clase que lo trata. Las mismas destrezas se vuelven a medir al final, en la clase de síntesis.
Antes de comenzar la unidad, mide tu punto de partida. Es una autoevaluación breve: no se califica y su resultado se guarda solo en tu navegador.
Pregunta 1De unidades anterioresUn programa declara
const double r{7 / 2};y escriber. ¿Qué aparece?Cree que el tipo de la variable decide cómo se divide; lo decide el tipo de los operandos.Cree que la división entera redondea; descarta la parte decimal.El valor 3 es constante y se representa exactamente en undouble: no hay estrechamiento que rechazar.La división7 / 2es entre enteros y da el cociente entero, 3; solo después ese 3 se convierte endouble. El tipo de los operandos decide la operación, no el tipo de la variable que recibe el resultado. La clase 3.1 convierte esta observación en una regla general: el tipo se decide en cada nodo de la expresión.Pregunta 2De unidades anteriores¿Cómo se escribe el número 13 en base 2, con ocho bits?
Suma mal los pesos: .Escribe los restos de las divisiones sucesivas en el orden en que salen; se leen del último al primero.Ese patrón es 26, el doble de 13: los bits están desplazados una posición.Cada posición pesa el doble que la de su derecha: los unos ocupan las posiciones de peso 8, 4 y 1. La clase 3.4 opera directamente sobre estos bits, de modo que conviene leerlos con soltura.Repasar: Los enteros y su representación
Pregunta 3De unidades anteriores¿Qué escribe
std::println("{}", 0u - 1);con ununsigned intde 32 bits?No tiene en cuenta el sufijou: un tipo sin signo no tiene negativos.Confunde la aritmética sin signo, definida módulo , con el desbordamiento con signo.Cree que la resta se detiene en el menor valor del tipo; da la vuelta.La aritmética sin signo es módulo : . El resultado está definido, y por eso ningún detector lo señala. La unidad lo reencuentra en las conversiones de una expresión mixta y en los operadores de bits, que se escriben con tipos sin signo.Repasar: Los enteros y su representación
Pregunta 4De unidades anterioresUn programa ejecuta
int count{std::numeric_limits<int>::max()};y despuéscount = count + 1;. ¿Qué garantiza la norma sobre el valor decount?Confunde lo que se observa a veces con lo que la norma garantiza; la vuelta al mínimo es lo que hacen los sin signo, no los con signo.Ignora el límite del tipo: ese número no cabe en unintde 32 bits.El compilador no conoce los valores que el programa tendrá al ejecutarse; casi siempre compila sin decir nada.La suma tiene una precondición, que el resultado quepa en el tipo, y fuera de ella la norma no promete nada. El detector del curso detiene el programa; sin él, puede escribirse cualquier cosa. La clase 3.3 reúne este caso con los demás de su especie en un catálogo.Repasar: Los enteros y su representación
Pregunta 5¿Cuánto valen y ?
Opera de izquierda a derecha sin atender a la precedencia del producto.Ignora los paréntesis de la segunda expresión.Atribuye a cada expresión el valor de la otra: invierte el efecto de los paréntesis.El producto liga más que la suma: en se multiplica primero, y los paréntesis alteran ese orden. C++ sigue la misma convención, y la clase 3.1 la extiende a la división, al resto y a la asociatividad, con el árbol de la expresión como instrumento.Repasar: Aritmética
Pregunta 6Según el teorema de la división de la matemática, con el resto sujeto a , ¿cuáles son el cociente y el resto de entre ?
Es lo que calcula C++, pero no cumple : el resto de la matemática no es negativo.No comprueba la identidad: , no .Tampoco cumple la identidad: .El teorema exige con , y esos dos números son los únicos que lo cumplen. C++, en cambio, trunca el cociente hacia el cero:-7 / 2vale y-7 % 2vale . La clase 3.1 explica la diferencia y enseña a obtener el resto de la matemática a partir del de C++.Repasar: Aritmética
Pregunta 7¿Cuál es la negación de «llueve y hace frío»?
Niega cada parte sin cambiar la conectiva: eso afirma mucho más que la negación, porque excluye también el día seco y frío.Niega solo una de las partes.Dice lo mismo que la segunda opción, con el mismo error.La negación de una conjunción es la disyunción de las negaciones: es una de las leyes de De Morgan. Basta que falte una de las dos cosas para que la afirmación sea falsa. La clase 3.2 aplica la misma ley a las condiciones de un programa.Repasar: Relaciones y lógica
Pregunta 8¿Qué escribe
std::println("{}", 3 < 5);?Cree que el valor lógico se escribe como número; con el marcador{},std::printlnescribe la palabra.Cree que la expresión se escribe como texto; lo que se escribe es su valor.Lo es: una comparación es una expresión de tipobool.Una comparación es una expresión como cualquier otra: tiene un valor, de tipobool, ystd::printlnlo escribe comotrueofalse. La clase 3.2 parte de esta observación: una condición se calcula, y por eso tiene precedencia, árbol y álgebra.Repasar: Relaciones y lógica
Pregunta 9Tras
int a{5};yint b{a++ * 2};, ¿cuánto valenayb?Es una respuesta honesta: la clase 3.3 enseña la diferencia entre el valor de una expresión y su efecto, y la evaluación de salida volverá a preguntarlo.Olvida el efecto:a++incrementaa.Usa el valor nuevo dea; el incremento sufijo da el valor anterior.La expresióna++tiene un valor, el queatenía (5), y un efecto, que dejaaen 6. El producto usa el valor, no el efecto. La clase 3.3 enseña a separar ambas cosas, y a reconocer cuándo dos efectos en una misma expresión la dejan sin significado.Repasar: Asignación, efectos secundarios y comportamiento indefinido
Pregunta 10¿Qué escribe
std::println("{}", 2 ^ 3);?Es una respuesta honesta: la clase 3.4 lo explica, y la evaluación de salida volverá a preguntarlo.Lee el circunflejo como potencia, como en la notación de muchas calculadoras; en C++ no lo es.Lo lee como producto.En C++ el circunflejo no es la potencia, sino el o exclusivo bit a bit: y difieren solo en el bit de peso 1, de modo que el resultado es 1. C++ no tiene operador de potencia; la clase 3.4 enseña cuándo usarstd::powy cuándo un desplazamiento.Repasar: Bits y biblioteca matemática
Cargando el contenido…