61 lines
1.8 KiB
Markdown
61 lines
1.8 KiB
Markdown
# 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'`".
|