> Paso por Valor
y Referencia
En C, todo se pasa por valor. Los punteros hacen que parezca magia, pero siguen siendo copias de direcciones.
↓ scroll para continuar
Stack vs Heap
Primero entendé cómo C organiza la memoria. Sin esto, nada de lo que viene tiene sentido.
Variables locales y referencias. LIFO.
Primitivos: el valor vive acá.
Objetos: solo la dirección (referencia).
Objetos reales. Gestionado por el GC.
Los objetos reales viven acá.
El Stack guarda la dirección para llegar.
LA REGLA FUNDAMENTAL
Cuando C pasa algo a una función, lo que viaja es el contenido de la variable en el Stack. Para primitivos eso es el valor directo. Para objetos eso es la dirección de memoria (la referencia). En AMBOS casos: se copia.
Paso por Valor
Con primitivos (int, double, boolean, char...)
x = 99;
// x es una COPIA local
}
int a = 5;
cambiar(a);
printf("%d\n", a); // 5 ← no cambió
POR QUÉ
C copia el valor 5 en una nueva variable x.
Cualquier cambio a x es local al método. a nunca se toca.
VISUALIZACIÓN
x cambia a 99...
...pero a sigue siendo 5 ✓
Objetos: La Referencia se Copia
Ambas variables apuntan al MISMO objeto en el heap
arr[0] = 99;
// arr apunta al MISMO objeto
}
int[] nums = {1,2,3};
modificar(nums);
printf("%d\n", nums[0]); // 99!
POR QUÉ
arr recibe una COPIA de la referencia (la dirección 0x4A2F).
Ambas apuntan al mismo array en el heap. Modificar arr[0] modifica el objeto real, y nums lo ve.
DIAGRAMA DE MEMORIA
Reasignar la Referencia
Esto prueba QUE C copia los punteros por valor
arr = new int[]{99,99,99};
// arr ahora apunta a OTRO objeto
// nums NO se entera
}
int[] nums = {1,2,3};
reasignar(nums);
printf("%d\n", nums[0]); // 1 ← no cambió
LA CLAVE
arr = new int[]... solo cambia a dónde apunta la COPIA local. La referencia original nums en el Stack del llamador no se modifica. Sigue apuntando al objeto original. Esta es la prueba de que en C los punteros también se pasan POR VALOR.
DIAGRAMA
Clase Persona
Modificar campos vs reasignar el objeto
✓ Modifica el campo
char nombre[20];
}
void cambiarNombre(Persona p) {
p.nombre = "Nuevo";
}
Persona ana = new Persona();
ana.nombre = "Ana";
cambiarNombre(ana);
// ana.nombre == "Nuevo" ✓
RESULTADO
p apunta al mismo objeto que ana. Modificar p.nombre cambia el objeto compartido.
✗ Reasigna la referencia
p = new Persona();
p.nombre = "Otro";
// p apunta a un objeto nuevo
}
Persona ana = new Persona();
ana.nombre = "Ana";
reemplazar(ana);
// ana.nombre == "Ana" (sin cambios)
RESULTADO
La copia local p apunta a otro objeto. ana sigue apuntando al original.
Strings en C: arreglos mutables
En C, un arreglo de char se puede modificar carácter por carácter si tenés memoria escribible.
s[0] = 'Z';
// modifica el arreglo original
}
char nombre[] = "Ana";
cambiar(nombre);
printf("%s\n", nombre); // "Zna"
INMUTABILIDAD
char[] en C es mutable si la memoria es escribible. s[0] = 'Z' modifica el mismo arreglo recibido. La función escribe directamente sobre la misma memoria compartida.
ARREGLO DE CHARS
Los literales suelen ser de solo lectura; si querés mutarlos, usá un arreglo de chars propio. Usá strcmp() para comparar contenido, no compares direcciones si querés saber si dicen lo mismo.
QUÉ PASA EN MEMORIA
Diagrama de Memoria Completo
Todo junto. Primitivos y referencias en acción.
Los objetos no viven en el Stack.
Solo la dirección para encontrarlos.
NOTA SOBRE PRIMITIVOS
Los primitivos (int, double, boolean, char, long, float, short, byte)
son los ÚNICOS que viven directamente en el Stack. Todo lo demás — incluyendo buffers dinámicos, arrays reservados en heap y structs gestionados con punteros — vive en el Heap.
Reglas de Oro
Grabátelas. Son inamovibles.
C SIEMPRE pasa por valor
Sin excepciones. Los punteros no cambian esta regla: solo copian direcciones.
Para primitivos: se copia el VALOR
El método recibe una copia. Cambiarla no afecta al original.
Para objetos: se copia la REFERENCIA
La copia contiene la misma dirección de memoria. Ambas apuntan al mismo objeto.
Modificar el objeto a través de la copia: SÍ afecta al original
arr[0] = 99, p.nombre = "X" — ambas referencias ven el cambio.
Reasignar la referencia copiada: NO afecta al original
arr = new int[]..., p = new Persona() — solo mueve la copia local.
SESION FINALIZADA
Ahora sabés la diferencia entre paso por valor y uso de punteros en C.
No la vayas a confundir con "paso por referencia" de otros lenguajes.
PRIMITIVOS
int, double, boolean, char, long, float, short, byte
→ copia del valor
OBJETOS
punteros, arrays, structs
→ copia de la referencia
FIN DE SESION // DATOS PROCESADOS CORRECTAMENTE
← VOLVER A PRESENTACIONES