# Laboratorio de la semana 4: punteros en `gdb` y filtros por puntero

Los comandos se corren desde `code/week-04`. Las ideas están en los apuntes, en la sección
"El laboratorio, paso a paso". Esta semana hay una sola sesión de laboratorio, porque la
otra es para la Práctica 1. Está pensada para unos 90 minutos.

| Archivo | Qué es | ¿Lo cambian? |
|---|---|---|
| `pointers_basic.c`, `pointers_params.c`, `pointers_array.c` | Los tres programas de la parte 1 | No |
| `image.h`, `image.c` | El módulo de imágenes, ya reescrito con punteros | No |
| `filters.h` | Lo que debe hacer cada función | No |
| `filters.c` | Los filtros: `brighten` hecho, los demás por escribir | **Sí** |
| `filter_tests.c` | Sus pruebas con `assert` | **Sí** |
| `filter_demo.c` | Aplica los filtros a `images/sun.pgm` y dibuja el resultado | No |
| `images/` | `tiny.pgm`, de 3 x 2, y `sun.pgm`, de 32 x 16 | No |

```sh
make gdb        # compila los programas de la parte 1 en build/gdb/, con -g -O0
make lab        # compila filter_tests y filter_demo en build/lab/
make test-lab   # comprueba sus filtros; falla hasta que terminen
```

## Parte 1: dibujar y comprobar punteros (unos 35 minutos)

Para cada programa: **primero dibujen en papel, sin ejecutar**. Cada puntero es una flecha
hacia la casilla a la que apunta. Después ábranlo en `gdb` y comparen con `print`, `whatis`,
`backtrace` y `up`. Si el dibujo y `gdb` no coinciden, averigüen por qué antes de seguir. Si a
los 35 minutos no llegaron a `pointers_array.c`, pasen a la parte 2 y déjenlo para antes de la
próxima semana.

**`pointers_basic.c`**: `gdb build/gdb/pointers_basic`.

1. Escriban lo que creen que imprime.
2. Dibujen `a`, `b`, `p` y `q` después de cada una de las líneas 10 a 14. Son cinco dibujos.
3. Con `break 10` y `next`, comprueben cada dibujo. Usen `print p`, `print &a` y `print *p`.
4. ¿Qué diferencia hay entre lo que hace la línea 11 y lo que hace la línea 12?

**`pointers_params.c`**: `gdb build/gdb/pointers_params`.

1. Escriban lo que creen que imprime.
2. Con `break swap`, dibujen los tres marcos en la parada. ¿Por qué `order` llama a
   `swap(low, high)` sin `&`?
3. Comprueben con `backtrace`, y con `up` y `print low`. ¿A qué variable de `main` apuntan
   `a` y `low`? Compárenlos con `print &x`.
4. Con `break 18`, dibujen el marco de `retarget` antes de `*p = 99`. Después de retornar,
   ¿a qué variable cambió `*p = 99`? ¿Por qué `x` no cambió, si `retarget` recibió `&x`?

**`pointers_array.c`**: `gdb build/gdb/pointers_array`.

1. Escriban lo que creen que imprime.
2. Con `break fill`, dibujen los marcos. `start` apunta a un elemento del arreglo: ¿a cuál?
   Compruébenlo con `print start`, `print *start@2`, y con `up` y `print &data[1]`.
3. Con `break 27`, ¿a qué elementos se refieren `*(p + 1)` y `p[-1]`? ¿Por qué es válido un
   índice negativo aquí?
4. Con `break record`, dibujen `c` en `main` y el puntero `c` en `record`. Después de la
   segunda llamada, ¿qué valen `c.count` y `c.last`? ¿Qué es `*data`?

## Parte 2: los filtros por puntero (unos 55 minutos)

Tomen el cuerpo de cada filtro de `code/week-03/lab/filters.c` y pónganlo dentro de la función
que corresponde en `lab/filters.c`, sin copiar el archivo completo, porque las firmas cambiaron.
Ya no devuelven una imagen: cambian la que reciben. `brighten` es el modelo.

1. `invert`, `threshold` y `flip_horizontal`. Agreguen sus pruebas en `filter_tests.c`, con el
   resultado esperado calculado a mano. `test_brighten` es el modelo.
2. `image_stats`, con sus pruebas. Devuelve tres resultados por sus parámetros de salida.
   Calculen a mano una imagen de 3 x 2.

```sh
make lab && build/lab/filter_tests
```

Cuando pasen sus pruebas, corran `make test-lab`. Luego miren el resultado:

```sh
build/lab/filter_demo
```

## Para antes de la siguiente semana

Si no alcanzó el tiempo, esto es lo primero que puede quedar para después de la sesión. Lean
`image.h` e `image.c`, compárenlos con los de la semana 3 y respondan por escrito:

1. ¿Por qué `image_load` lee en una imagen local, y solo al final escribe `*img`? ¿Qué vería
   quien llama si un archivo tuviera un error en el último píxel y no se hiciera así?
2. ¿Qué parámetros llevan `const` y cuáles no? ¿Qué dice eso de cada función?
3. La semana 3 usaba `width` igual a 0 para avisar de un error. ¿Qué lo reemplazó? ¿Por qué
   desapareció `image_is_valid`?
4. `filter_demo.c` hace `copy = img` antes de cada filtro. ¿Qué dibujaría si no lo hiciera?
   ¿Cuántos bytes se copian cada vez?
5. Con `read_number(FILE *file)`, ¿qué se copia al llamarla? ¿Dónde queda guardado por dónde
   va la lectura?
