progress
This commit is contained in:
@@ -196,6 +196,70 @@ uint8_t init[] = { 0x1B, 0x40 }; /* ESC @ */
|
||||
**En Go** `[2]byte{0x1B, 0x40}` es un array con su longitud dentro del tipo.
|
||||
Se pasa por copia, y para pasarlo sin copiar se usa un slice: `init[:]`.
|
||||
|
||||
## Aritmética de punteros: `[]` también lleva un `*` escondido
|
||||
|
||||
Con dibujos interactivos y preguntas: [02-pointers-visual.html](02-pointers-visual.html).
|
||||
|
||||
Sumar un entero a un puntero da **otra dirección**: `p + i` avanza `i`
|
||||
**elementos**, es decir, `i * sizeof *p` bytes. No va a la casa. Solo calcula
|
||||
qué casa es.
|
||||
|
||||
`p[i]` es una abreviatura de `*(p + i)`: calcula la dirección y va a ella.
|
||||
Igual que `->`, los corchetes llevan el `*` dentro.
|
||||
|
||||
La cadena completa con el buffer:
|
||||
|
||||
| Escribes | Equivale a | Tipo | Qué es |
|
||||
|---|---|---|---|
|
||||
| `buffer` | | `escpos_buffer *` | El papel (8 bytes) |
|
||||
| `*buffer` | | `struct escpos_buffer` | La casa (24 bytes) |
|
||||
| `buffer->data` | `(*buffer).data` | `uint8_t *` | Un papel guardado dentro de la casa, con la dirección del bloque de bytes |
|
||||
| `buffer->data + i` | `&buffer->data[i]` | `uint8_t *` | La dirección de la casilla `i` |
|
||||
| `buffer->data[i]` | `*(buffer->data + i)` | `uint8_t` | El byte de la casilla `i` |
|
||||
|
||||
Para saber si una expresión lleva `*`, cuenta: `*`, `->` y `[]` desreferencian
|
||||
una vez cada uno, y `&` quita una desreferencia.
|
||||
|
||||
### Qué viaja cuando llamas a una función
|
||||
|
||||
En C, a una función le llega siempre **una copia** del valor que le pasas.
|
||||
|
||||
- `f(buffer)`: viaja una copia del papel, 8 bytes. La función llega a la misma
|
||||
casa, así que lo que cambie en ella lo ves tú.
|
||||
- `f(*buffer)`: viaja una copia de la casa, 24 bytes. Lo que cambie la función
|
||||
se queda en su copia.
|
||||
- `f(data)`, con `data` un array de 300 bytes: el array decae a la dirección
|
||||
de su primera casilla. Viaja un papel de 8 bytes, no los 300 bytes. Dentro de
|
||||
la función, `sizeof *data` es 1, el tamaño de una casilla.
|
||||
|
||||
### Restar direcciones
|
||||
|
||||
Las direcciones se escriben en hexadecimal, en base 16: cada posición vale 16
|
||||
veces la de su derecha, y `a`–`f` valen 10–15.
|
||||
|
||||
| Hex | Decimal |
|
||||
|---|---|
|
||||
| `0x08` | 8 |
|
||||
| `0x10` | 16 |
|
||||
| `0x18` | 24 |
|
||||
| `0x20` | 32 |
|
||||
| `0x40` | 64 |
|
||||
| `0x80` | 128 |
|
||||
| `0x100` | 256 |
|
||||
|
||||
`0x20` es 2 × 16 + 0 = 32. Para no hacer la cuenta a mano:
|
||||
|
||||
- En gdb: `p 0xd210 - 0xd1f0` da `32`, y `p/x 32` da `0x20`.
|
||||
- En bash: `echo $((0xd210 - 0xd1f0))`.
|
||||
|
||||
Si restas dos **punteros** del mismo tipo (`p &b - &a`), el resultado no son
|
||||
bytes: son **elementos**, igual que en la suma. Dos `escpos_buffer *` separados
|
||||
32 bytes dan `4`, porque cada uno ocupa 8.
|
||||
|
||||
**En Go** pasa lo mismo, todo se copia: un `*Buffer` copia el puntero y un
|
||||
slice copia la cabecera (puntero, len y cap). La diferencia es que en el slice
|
||||
viaja la longitud, y en C tienes que pasarla tú.
|
||||
|
||||
## `printf` y el formato
|
||||
|
||||
El primer argumento de `printf` es el **formato**. Nunca pases ahí una cadena
|
||||
|
||||
Reference in New Issue
Block a user