Una introducción a los punteros para programadores

  • Brian Curtis
  • 0
  • 3068
  • 314
Anuncio

Ya sea que se dé cuenta o no, la gran mayoría de los programas que ha utilizado hacen uso de punteros de alguna manera. Tal vez has experimentado un Excepción de puntero nulo en algún momento. Como programador, es muy probable que el código que escriba use punteros, incluso si no los ha implementado usted mismo..

Hoy le mostraré cómo funcionan los punteros, por lo que es posible que desee ver cómo funcionan las matrices y las listas Cómo funcionan las matrices y las listas en Python Cómo funcionan las matrices y las listas en Python Las matrices y las listas son algunas de las estructuras de datos más útiles en la programación: - aunque pocas personas los usan en todo su potencial. para un manual de programación. Este artículo estará más basado en la teoría de lo habitual, pero sígalo, los punteros son muy complejos!

Compilando Código

Antes de profundizar en los punteros, debe comprender cómo se construye y ejecuta el código; tal vez ya lo sepa. Esta sección tendrá declaraciones bastante generales, cosas que se aplican a mayoria de idiomas, pero no necesariamente todos.

Volvamos las cosas al principio. Cada computadora usa binario ¿Qué es binario? [Explicación de la tecnología] ¿Qué es binario? [Explicación de la tecnología] Dado que el binario es tan fundamental para la existencia de las computadoras, parece extraño que nunca hayamos abordado el tema antes, así que hoy pensé que daría una breve descripción de qué binario ..., una serie de unos y ceros que componen la tecnología moderna tal como la conocemos. Es extremadamente difícil codificar cualquier cosa en binario (los archivos serían muy confusos), ya que estas son las instrucciones en bruto que necesita su unidad Central de procesamiento o CPU para funcionar ¿Qué es una CPU y qué hace? ¿Qué es una CPU y qué hace? Las siglas informáticas son confusas. ¿Qué es una CPU de todos modos? ¿Y necesito un procesador quad o dual-core? ¿Qué tal AMD o Intel? ¡Estamos aquí para ayudar a explicar la diferencia! . Esto se conoce como Codigo de maquina.

El siguiente paso del código de la máquina es Montaje. Este es un formato legible para humanos. Si bien aún es complejo programarlo, es posible. El ensamblaje se compone de una serie de comandos simples para ejecutar tareas, y se conoce como nivel bajo lenguaje de programación. Es posible escribir programas complejos, pero es difícil expresar conceptos abstractos y requiere mucha consideración.

Muchos videojuegos y aplicaciones de alto rendimiento tienen parte de la lógica escrita en el ensamblaje, ya que se pueden encontrar algunos aumentos de velocidad reales si sabes lo que estás haciendo. Sin embargo, para la gran mayoría de los proyectos de programación, no necesita saber nada de ensamblaje.

Entonces, si el código de la máquina es demasiado difícil de escribir y el ensamblaje es demasiado difícil de programar, ¿con qué escribe el código? Aquí es donde nivel alto entran los idiomas. Los idiomas de alto nivel hacen que los programas sean fáciles de escribir. Puede programar en algo que se parezca a su idioma nativo, y es fácil expresar algoritmos complejos. Es posible que haya oído hablar de muchos idiomas de alto nivel (y definitivamente habrá utilizado un programa escrito en ellos):

  • BASIC
  • do++
  • Ceceo

¡Estos lenguajes son muy antiguos ahora, y muchos se desarrollaron a principios de la década de 1950! Casi todos los lenguajes de programación modernos son de alto nivel, incluidos PHP y Python. Cada día se inventan más idiomas (aunque probablemente haya suficientes ahora), pero ¿cómo funciona exactamente su código si las computadoras requieren código de máquina??

Aquí es donde entra la compilación. Un compilador es un programa que convierte su código de alto nivel en un formulario que se puede ejecutar. Este podría ser otro lenguaje de alto nivel, pero generalmente es ensamblado. Algunos lenguajes (como Python o Java) convierten su código en una etapa intermedia llamada bytecode. Será necesario compilar nuevamente en una fecha posterior, que generalmente se realiza a pedido, como cuando se ejecuta el programa. Esto se conoce como justo a tiempo compilación, y es bastante popular.

Gestión de la memoria

Ahora que sabe cómo funcionan los lenguajes de programación, veamos la administración de memoria en lenguajes de alto nivel. Para estos ejemplos, usaré pseudocódigo: código escrito no en un lenguaje específico, sino que se usa para mostrar conceptos en lugar de sintaxis exacta. Hoy, esto se parecerá principalmente a C ++, ya que es el mejor lenguaje de alto nivel (en mi opinión).

Para esta sección, será útil que comprenda cómo funciona la RAM Una guía rápida y sucia de RAM: lo que necesita saber Una guía rápida y sucia de la RAM: lo que necesita saber La RAM es un componente crucial de cada computadora , pero puede ser confuso. Lo desglosamos en términos fáciles de entender que comprenderá. .

La mayoría de los idiomas tienen variables: contenedores que almacenan algunos datos. Debe definir explícitamente el tipo de datos. Algunos lenguajes de tipo dinámico como Python o PHP manejan esto por usted, pero aún tienen que hacerlo..

Digamos que tienes una variable:

int myNumber;

Este código declara una variable llamada mi número, y le da un tipo de datos de entero. Una vez compilado, la computadora interpreta este comando como:

“Encuentre un poco de memoria vacía y reserve un espacio lo suficientemente grande como para almacenar un número entero”

Una vez que este comando se ha ejecutado, ese bit de memoria no puede ser utilizado por otro programa. Todavía no contiene ningún dato, pero está reservado para su variable myNumber.

Ahora asigne un valor a su variable:

myNumber = 10;

Para completar esta tarea, su computadora accede a su ubicación de memoria reservada y cambia cualquier valor almacenado allí, a este nuevo valor.

Ahora, todo esto está muy bien, pero ¿cómo se reservan las ubicaciones de memoria? Si los programas reservaran toda la memoria que quisieran, la RAM se llenaría inmediatamente, lo que generaría una muy sistema lento.

Para evitar este problema potencial, muchos idiomas implementan un recolector de basura, usado para destruir variables (y por lo tanto liberar las ubicaciones de memoria reservadas) que se han ido fuera del ámbito.

Quizás se pregunte qué alcance tiene y por qué es tan importante. El alcance define los límites y la vida útil de las variables o cualquier memoria utilizada por un programa. Una variable es “fuera del ámbito” cuando ya no se puede acceder por ningún código (es cuando el recolector de basura interviene). Aquí hay un ejemplo:

function maths () int firstNumber = 1;  int secondNumber = 2; print (primerNúmero + segundoNúmero); // no trabajará

Este ejemplo no se compilará. La variable primer número está dentro de matemáticas función, por lo que es su alcance. No se puede acceder desde fuera de la función en la que se ha declarado. Este es un concepto de programación importante., y entender que es crucial trabajar con punteros.

Esta forma de manejar la memoria se llama apilar. Es la forma en que funciona la gran mayoría de los programas. No tiene que entender los punteros para usarlo, y está bastante bien estructurado. La desventaja de la pila es la velocidad. Como la computadora tiene que asignar memoria, hacer un seguimiento de las variables y ejecutar la recolección de basura, hay una pequeña sobrecarga. Esto está bien para programas más pequeños, pero ¿qué pasa con las tareas de alto rendimiento o las aplicaciones pesadas de datos??

Entrar: punteros.

Punteros

En la superficie, los punteros suenan simples. Ellos hacen referencia (apunta a) una ubicación en la memoria. Esto puede no parecer diferente a “regular” variables en la pila, pero confía en mí, hay una gran diferencia. Los punteros se almacenan en el montón. Esto es lo opuesto a la pila: está menos organizado, pero es mucho más rápido.

Veamos cómo se asignan las variables en la pila:

int numberOne = 1; int numberTwo = numberOne;

Esta es una sintaxis simple; La variable número dos Contiene el número uno. Su valor se copia durante la asignación desde el número uno variable.

Si quisieras obtener el dirección de memoria de una variable, en lugar de su valor, debe usar el signo de y comercial (&). Esto se llama el Dirección de operador, y es una parte esencial de su kit de herramientas de puntero.

int numberOne = 1; int numberTwo = & numberOne;

Ahora el número dos variable puntos a una ubicación de memoria, en lugar de copiar el número uno en su propia ubicación de memoria nueva. Si tuviera que generar esta variable, no sería la número uno (aunque esté almacenada en la ubicación de la memoria). Daría salida a su ubicación de memoria (probablemente algo así como 2167, aunque varía según el sistema y la RAM disponible). Para acceder al valor almacenado en un puntero, en lugar de la ubicación de la memoria, debe desreferencia el puntero Esto accede al valor directamente, que sería el número uno en este caso. Así es como desreferencia un puntero:

int numberTwo = * numberOne;

los operador de desreferencia es un asterisco (*).

Este puede ser un concepto difícil de entender, así que repasemos nuevamente:

  • los Dirección de El operador (&) almacena la dirección de memoria.
  • los operador de desreferencia (*) accede al valor.

La sintaxis cambia ligeramente al declarar punteros:

int * myPointer;

El tipo de datos de En t aquí se refiere al tipo de datos del puntero puntos a, y no el tipo de puntero en sí.

Ahora que sabes lo que son los punteros, ¡puedes hacer algunos trucos realmente geniales con ellos! Cuando se usa memoria, se inicia su sistema operativo secuencialmente. Puedes pensar en la RAM como huecos de palomas. Muchos agujeros para almacenar algo, solo se puede usar uno a la vez. La diferencia aquí es que estas palomas están numeradas. Al asignar memoria, su sistema operativo comienza en el número más bajo y funciona. Nunca saltará entre números aleatorios.

Al trabajar con punteros, si ha asignado una matriz, puede navegar fácilmente al siguiente elemento simplemente incrementando su puntero.

Aquí es donde se pone interesante. Cuando pasa valores a una función (usando variables almacenadas en la pila), estos valores se copian en su función. Si estas son variables grandes, su programa ahora las almacena dos veces. Cuando finalice su función, es posible que necesite una forma de devolver estos valores. En general, las funciones solo pueden devolver una cosa, así que, ¿qué pasaría si quisiera devolver dos, tres o cuatro cosas??

Si pasa un puntero a su función, solo se copia la dirección de memoria (que es pequeña). ¡Esto le ahorra mucho trabajo a tu CPU! Tal vez su puntero apunta a una gran variedad de imágenes: su función no solo puede funcionar exactamente con los mismos datos almacenados en la misma ubicación de memoria, sino que una vez que está hecha, no hay necesidad de devolver nada. ordenado!

Sin embargo, debes tener mucho cuidado. Los punteros aún pueden salir del alcance y ser recolectados por el recolector de basura. Sin embargo, los valores almacenados en la memoria no se recopilan. Esto se llama pérdida de memoria. Ya no puede acceder a los datos (ya que se han destruido los punteros), pero todavía está usando memoria. Esta es una razón común para que muchos programas se bloqueen, y puede fallar espectacularmente si hay una gran cantidad de datos. La mayoría de las veces, su sistema operativo matará su programa si tiene una fuga grande (usando más RAM que el sistema), pero eso no es deseable.

La depuración de punteros puede ser una pesadilla, especialmente si está trabajando con grandes cantidades de datos o trabajando en bucles. Sus desventajas y dificultades para comprender realmente valen la pena las compensaciones que obtienes en rendimiento. Aunque recuerde, puede que no siempre sean necesarios.

Es todo por hoy. Espero que hayas aprendido algo útil sobre un tema complejo. Por supuesto, no hemos cubierto todo lo que hay que saber: es un tema muy complejo. Si está interesado en aprender más, le recomiendo C ++ en 24 horas.

Si esto fue un poco complejo, eche un vistazo a nuestra guía de los lenguajes de programación más fáciles. 6 Lenguajes de programación más fáciles de aprender para principiantes. proceso de edificación Aquí están los seis lenguajes de programación más fáciles para principiantes.. .

¿Aprendiste cómo funcionan los punteros hoy? ¿Tienes algún consejo o truco que quieras compartir con otros programadores? Entra en los comentarios y comparte tus pensamientos a continuación!




Nadie ha comentado sobre este artículo todavía.

Sobre tecnología moderna, simple y asequible.
Tu guía en el mundo de la tecnología moderna. Aprenda a usar las tecnologías y los dispositivos que nos rodean todos los días y aprenda a descubrir cosas interesantes en Internet.