Los punteros en C son una tormenta perfecta. La energía de la complejidad derivada de muchos orígenes se encuentra en un solo punto. Después de que apenas logras escapar del estrecho estrecho de sintaxis, esta energía te estrella en las rocas de la corrupción de la memoria o se ahoga en tu nave con fugas.
Estas son las energías que amenazan al marinero de las altas C:
[1] Navegando por los punteros
Toda la noción de punteros es confusa. De hecho, tuve un compañero de trabajo que había programado en C ++ antes, se confundió con los punteros de Python. “Pero Python no tiene punteros “. Le han mentido, ya que Python tiene punteros , y también Java.
def byRef (arr):
arr [:] = [1]
arr = [2]
print (‘en byRef = {}’. formato (arr))
a = [1,2,3]
por Ref (a)
print (‘after byRef = {}’. format (a))
Ejecutar esto confundirá a muchos programadores de Python con la salida:
en byRef = [2]
después de byRef = [1]
¿De dónde, en nombre del poderoso Kraken, viene esto? ¿Por qué ‘ a’ cambió en absoluto? ¿Y por qué obtuvo [1]
, que fue asignado primero, pero no obtuvo [2]
, que fue segundo?
El faro de la asamblea. saber hardware y ensamblaje ayuda aquí, ya que comienzas a entender que los punteros son direcciones. Usted comprende que arr es solo un puntero al objeto de matriz, y [math] arr [:] = [1] [/ math] no cambia el puntero, sino que va directamente al objeto. Entonces verá que arr = [2]
reemplaza el puntero que ‘ arr ‘ contiene y no toca el objeto original.
[2] El laberinto de la recursividad
Cuando era joven, vi el faro desde lejos; Tenía mis flechas de montaje en mi carcaj. Pero el Minotauro logró atraparme en su reino de datos recursivos. Me tomó algo de tiempo escapar de este pequeño pedazo de Laberinto:
struct tree_node {
datos int;
struct tree_node * left, * right;
struct tree_node * parent;
};
¿Dónde está el principio y el final de esto? Para entender qué tree_node es, lee sus campos, pero luego gira a la izquierda y vuelve al principio. Gira a la derecha , pero eso no te lleva a ninguna parte. Este laberinto no tiene fin, y ni siquiera puedo encontrar el comienzo. Tuve que encontrar un hilo de pensamiento en este desastre: algunas habilidades básicas para navegar por la recursión.
Esto no es específico de este C, y también afectará a cualquiera que navegue a Java. Pero las sirenas del C confunden tu mente más de lo que tienen que enfrentar los marineros de Java. ¿Cómo se produce un conocimiento de embarque, para tree_node, cuando tree_node se contiene a sí mismo?
Serás como un ciervo atrapado en los faros hasta que veas el faro de la asamblea. Los punteros son solo bits en la memoria, y el compilador no necesita saber a qué apuntan exactamente izquierda y derecha , solo que son flechas en su mapa de memoria. E incluso después de comprender eso, aún debe comprender la recursividad.
[3] El estrecho de sintaxis
La C de la sintaxis es muy confusa, y una simple mirada en sus ojos te petrificará:
int * ptr; // * significa definición
int a = * ptr; // * significa leer datos
* ptr = a; // * significa escribir datos!
ptr = & a; // & significa tomar un puntero!?
La sintaxis no es muy consistente. Además, esta es la única forma de pasar valores por referencia a funciones. Estos pequeños dardos de punteros lo atraparán si desea obtener más de un bit de información del oráculo de funciones. El oráculo te hablará solo si traes el sacrificio de int*
y double const*const*
, o (horrores) int**(*)(int *)
.
[4] Poseidón te estrellará contra las rocas
Además de todo, si mallocas () el tamaño incorrecto, a veces chocas, y otras no, por los caprichos de Moira y el señor del mar. Si olvida inicializar el puntero, Hades se alegrará de obtener su alma. Si señala dónde no debería, Hermes le robará su oro. En el mejor de los casos, un centinela pensará que estás tratando de violar los derechos de su monarca OS y disparará una flecha para matar.
[5] Un barco con fugas se hunde
Habiendo visto tantas aventuras, aún no estás seguro. Su bote está goteando como un tamiz. Debes tirar toda el agua que hayas bombeado, de lo contrario tu pesado barco se hundirá. A diferencia de C, C ++ no le permite hundirse tan rápido y las aguas de Java son más ligeras, pero las naves aún se escapan a través de sus grietas de devolución de llamada.
Los punteros son difíciles porque se los aborda como una nuez monolítica grande para romper. Es muy difícil separar todos los aspectos de la dificultad en pequeños fragmentos. Si, en lugar de C, comienza a aprender el ensamblaje Python o Java, puede escapar del estrecho de la sintaxis, pero no los otros problemas.
En mi opinión, las estructuras recursivas son tanto el pináculo del uso del puntero como la parte más difícil de comprender. Sin estructuras recursivas, realmente no puedes entender los punteros. Afortunadamente, puede sumergirse en el laberinto de estructuras recursivas en las aguas de Java o en las tierras de la gran Python, sin navegar por los traicioneros estrechos de la sintaxis de puntero y la gestión de la memoria de la C.
Cómo simplificar los punteros de aprendizaje:
- Aprenda el ensamblaje o, al menos, cómo se organiza la memoria. Aprenda bits y bytes, y las direcciones de estos bytes.
- Aprenda estructuras de datos recursivas en lenguajes administrados como Python o Java.
Después de hacer 1 y 2, comprender los punteros debería ser relativamente fácil, ya que todo lo que le queda por aprender es la sintaxis [3], la validez de los punteros [4] y las pérdidas de memoria [5]. Estas partes son mucho más fáciles de entender cuando no se entremezclan con la noción de punteros [1] y el concepto de datos recursivos estructurados [2].