🔍 Adreces i punters en C amb "Hola món"

Aquesta pàgina explica, pas a pas i amb exemples reals en C, els conceptes fonamentals de memòria, adreces i punters utilitzant la cadena de text "Hola món".

Tot el codi que veuràs es pot compilar i executar. Les adreces que apareixen són adreces virtuals (les que veu el teu programa), no les físiques de la RAM.

1. Declarar la cadena de caràcters

En C, una cadena de text és un array de char acabat amb un caràcter nul '\0'.

// Declarem la cadena "Hola món" (9 caràcters visibles + '\0') char salutacio[] = "Hola món";

Internament, la memòria reserva 10 bytes consecutius (un per a cada lletra, espai, accent i el zero final).

📦 Memòria (adreces d'exemple)

⬆️ Cada byte té la seva pròpia adreça. La cadena ocupa 10 bytes seguits.

2. Obtenir l'adreça de la cadena

El nom de l'array salutacio ja és un punter constant al primer element. Per tant, salutacio equival a &salutacio[0].

char *p = salutacio; // 'p' guarda l'adreça del primer caràcter char *q = &salutacio[0]; // Exactament el mateix
💡 Recorda: p conté un número d'adreça, no la lletra 'H'. Per veure la lletra cal desreferenciar el punter amb *p.

3. Programa complet: imprimir adreces i valors

Afegim printf per veure què hi ha realment dins de p, dins de &p i el valor apuntat.

#include <stdio.h> int main() { char salutacio[] = "Hola món"; char *p = salutacio; printf("Cadena: %s\n", salutacio); printf("Adreça de salutacio: %p\n", salutacio); printf("Contingut de p: %p\n", p); printf("Adreça de p: %p\n", &p); printf("Primer caràcter: %c\n", *p); return 0; }

Una possible sortida (les adreces canvien cada execució):

Cadena: Hola món Adreça de salutacio: 0x7fffb45c8a30 Contingut de p: 0x7fffb45c8a30 Adreça de p: 0x7fffb45c8a18 Primer caràcter: H
🔎 Observa: p i salutacio donen la mateixa adreça. Però l'adreça on es guarda p (&p) és completament diferent!

📋 Resum d'expressions

ExpressióSignificatExemple de valor
salutacioAdreça del primer caràcter (punter constant)0x7fffb45c8a30
&salutacio[0]Mateixa adreça que salutacio0x7fffb45c8a30
pVariable punter que conté l'adreça de salutacio[0]0x7fffb45c8a30
&pAdreça on s'emmagatzema el punter p0x7fffb45c8a18
*pValor del primer caràcter ('H')H
*(p+3)Quart caràcter ('a')a
p[3]Equivalent a *(p+3)a

4. Recórrer la cadena amb aritmètica de punters

Un punter no sols apunta al primer element. Sumant-li enters avancem byte a byte per la cadena.

printf("Segon caràcter: %c\n", *(p+1)); // 'o' printf("Cinquè caràcter: %c\n", *(p+4)); // ' ' printf("Últim caràcter: %c\n", *(p+8)); // 'n' (sense accent, perquè 'ó' són 2 bytes en UTF-8? Depèn del sistema)
⚠️ Compte amb els caràcters multibyte! En C, char és un byte. L'accent de la 'ó' pot ocupar 2 bytes en codificació UTF-8. Aquí simplifiquem amb un sol byte per lletra (Latin-1).

5. Modificar la cadena a través del punter

Com que salutacio és un array (modificable), podem canviar un caràcter usant el punter.

*(p + 5) = 'M'; // Canvia la 'm' minúscula per una 'M' majúscula printf("Modificada: %s\n", salutacio); // "Hola Món"
Modificada: Hola Món

Això demostra que el punter dóna accés directe a la memòria original.

6. Recordatori: totes aquestes adreces són virtuals

Com ja hem dit, un programa normal d'usuari mai veu adreces físiques. %p imprimeix l'adreça virtual assignada pel sistema operatiu. Cada execució pot donar valors diferents gràcies a l'ASLR (randomització del layout de l'espai d'adreces).

Si intentessis saber l'adreça física des d'un programa normal, el sistema t'ho impediria per seguretat i aïllament entre processos.

7. Prova-ho tu mateix! (simulació)

Prem el botó per generar una representació visual de la memòria amb adreces aleatòries (simulades) i veure com el punter p hi apunta.

🧠 Memòria simulada

Les adreces són fictícies però il·lustren la diferència entre el valor i la seva ubicació.

📌 Conclusió

.