initial commit

This commit is contained in:
2026-09-30 10:22:42 +02:00
commit 3b0f5e365f
32 changed files with 4498 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
# Punteros y cadenas
## En C no hay tipo `string`
En Go, `string` es un tipo propio: por dentro guarda un puntero y una
longitud, y lo manejas como un valor.
En C, una cadena es solo una secuencia de bytes en memoria terminada en `'\0'`.
La longitud **no se guarda en ningún sitio**: para saberla hay que recorrer la
cadena hasta encontrar el `'\0'`.
```
"1.0.0" → '1' '.' '0' '.' '0' '\0' (6 bytes, no 5)
```
Los literales como `"1.0.0"` viven en **memoria de solo lectura**. Si
intentas escribir en ellos, el comportamiento es indefinido; en la práctica,
el programa se cierra.
## `const char *`
Una función que "devuelve una cadena" en realidad devuelve **la dirección de
su primer byte**:
```c
const char *version = escpos_version();
```
- `char`: en esa dirección hay caracteres.
- `*`: `version` es un puntero; guarda una dirección, no un carácter.
- `const`: a través de este puntero no se pueden modificar los caracteres.
`char` es un **entero de 1 byte**. Si guardas un puntero en un `char`, pierdes
la dirección. Por eso el error dice `makes pointer from integer`.
## Los dos significados de `*`
| Dónde aparece | Qué significa |
|---|---|
| En una **declaración**: `const char *p` | "`p` es un puntero" |
| En una **expresión**: `*p` | "el valor que hay en la dirección de `p`" (desreferenciar) |
Si `p` apunta a `"1.0.0"`, `*p` es solo el `'1'`.
**En Go**: es lo mismo que `var p *T` frente a `*p`.
## `printf` y el formato
El primer argumento de `printf` es el **formato**. Nunca pases ahí una cadena
variable:
```c
printf(s); /* mal */
printf("%s\n", s); /* bien */
```
Si `s` contuviera un `%`, `printf` iría a leer argumentos que no existen, lo
que es comportamiento indefinido y un agujero de seguridad clásico
(*format string*). `%s` significa "imprime los bytes desde esta dirección hasta
el `'\0'`".