¿Cuál es la diferencia real entre punteros y referencias?

9 minutos de lectura

avatar de usuario
Ian

AKA – ¿Qué es esta obsesión con los punteros?

Habiendo usado solo lenguajes modernos orientados a objetos como ActionScript, Java y C#, realmente no entiendo la importancia de los punteros y para qué los usa. ¿Qué me estoy perdiendo aquí?

  • No estoy seguro de que alguien esté “obsesionado” con los punteros. ¿No se podría volver a redactar el título de la pregunta ya que la pregunta en sí es valiosa pero el título es simplemente tonto? Tal vez “¿Cuál es la diferencia entre las ‘Referencias’ modernas y los ‘Puntos’ tradicionales?”

    –Shaun Austin

    18 de septiembre de 2008 a las 13:20

  • sí, pero mi título es más divertido. De hecho, he aprendido mucho de estas respuestas, por lo que probablemente formularía la pregunta de manera diferente con mi nuevo conocimiento. ¿Debería cambiarlo?

    – Ian

    18 de septiembre de 2008 a las 16:12

  • Sí, era un título entretenido. Sin embargo, si fuera yo, lo reformularía por dos razones relacionadas 1) Es más probable que una búsqueda encuentre esto en Google si la pregunta refleja el texto real de la pregunta 2) Alguien que haga una pregunta similar no vería la suya debido a la forma en que lo expresaste. EN MI HUMILDE OPINIÓN.

    –Shaun Austin

    18 de septiembre de 2008 a las 17:01

  • Si haces que “pointer” sea tu amigo, “referencias” ¡acompáñalo!

    – Jay D.

    6 de junio de 2012 a las 18:36

avatar de usuario
adam wright

Todo es solo indirección: la capacidad de no tratar con datos, pero decir “Te dirigiré a algunos datos, allí”. Tiene el mismo concepto en Java y C#, pero solo en formato de referencia.

Las diferencias clave son que las referencias son efectivamente señales inmutables: siempre apuntan a algo. Esto es útil y fácil de entender, pero menos flexible que el modelo de puntero C. Los punteros C son señales que puede reescribir felizmente. ¿Sabe que la cuerda que está buscando está al lado de la cuerda a la que apunta? Bueno, solo modifica ligeramente el poste indicador.

Esto combina bien con el enfoque de C “cercano al hueso, se requiere conocimiento de bajo nivel”. Nosotros saber que una char* foo consta de un conjunto de caracteres que comienzan en la ubicación señalada por el poste indicador foo. Si también sabemos que la cadena tiene al menos 10 caracteres, podemos cambiar la señal a (foo + 5) para apuntar a la misma cuerda, pero comienza la mitad de la longitud.

Esta flexibilidad es útil cuando sabes lo que estás haciendo, y la muerte si no lo sabes (donde “saber” es más que “saber el idioma”, es “saber el estado exacto del programa”). Hazlo mal, y tu señal te está dirigiendo al borde de un precipicio. Las referencias no le permiten jugar, por lo que está mucho más seguro de que puede seguirlas sin riesgo (especialmente cuando se combinan con reglas como “Un objeto al que se hace referencia nunca desaparecerá”, como en la mayoría de los lenguajes recopilados de basura).

  • Las referencias en Java y C# no son tan inmutables como en C++… se pueden cambiar para hacer referencia a otros objetos y también pueden tomar valores nulos, los cuales no se pueden hacer en C++… algo así como una mezcla de Referencias y punteros de C++ (que se recolectan como basura)

    – trabajomad3

    18 de septiembre de 2008 a las 14:19

  • ¡Explicación brillantemente redactada!

    –Robert Jeppesen

    18 de septiembre de 2008 a las 19:54

  • Me encanta el ejemplo del poste indicador del acantilado 🙂

    – Novato de SharePoint

    23 de diciembre de 2008 a las 8:07

  • Yo diría que los punteros se refieren directamente a la memoria de la computadora, mientras que las referencias son alias para otras variables. Si tiene un int y le da dos nombres, eso es esencialmente una referencia. Si tiene un int y registra su ubicación en la RAM, eso es un puntero.

    – Máx.

    1 de enero de 2009 a las 1:11

  • “por el precipicio se va” – ¡bien dicho!

    – Jay D.

    6 de junio de 2012 a las 18:41

¡Te estás perdiendo de mucho! Comprender cómo funciona la computadora en los niveles inferiores es muy útil en varias situaciones. C y el ensamblador lo harán por ti.

Básicamente, un puntero te permite escribir cosas en cualquier punto de la memoria de la computadora. En hardware/SO más primitivo o en sistemas integrados, esto podría ser útil. Digamos que encienda y apague los Blinkenlichts nuevamente.

Por supuesto, esto no funciona en los sistemas modernos. El sistema operativo es el amo y señor de la memoria principal. Si intenta acceder a una ubicación de memoria incorrecta, su proceso pagará su arrogancia con su vida.

En C, los punteros son la forma de pasar referencias a los datos. Cuando llamas a una función, no quieres copiar un millón de bits en una pila. En su lugar, solo indica dónde residen los datos en la memoria principal. En otras palabras, le das un puntero a los datos

Hasta cierto punto eso es lo que sucede incluso con Java. Pasas referencias a objetos, no a los objetos en sí. Recuerde, en última instancia, cada objeto es un conjunto de bits en la memoria principal de la computadora.

  • Estoy totalmente de acuerdo con tu comentario: “te estás perdiendo de mucho”.

    – Jay D.

    6 de junio de 2012 a las 18:41

avatar de usuario
steve jesop

Los punteros son para manipular directamente el contenido de la memoria.

Depende de usted si cree que esto es algo bueno, pero es la base de cómo se hace cualquier cosa en C o en ensamblador.

Los lenguajes de alto nivel ocultan punteros detrás de escena: por ejemplo, una referencia en Java se implementa como un puntero en casi cualquier JVM que encuentre, por lo que se llama NullPointerException en lugar de NullReferenceException. Pero no permite que el programador acceda directamente a la dirección de memoria a la que apunta, y no se puede modificar para que tome un valor que no sea la dirección de un objeto del tipo correcto. Por lo tanto, no ofrece el mismo poder (y responsabilidad) que los punteros en lenguajes de bajo nivel.

[Edit: this is an answer to the question ‘what’s this obsession with pointers?’. All I’ve compared is assembler/C-style pointers with Java references. The question title has since changed: had I set out to answer the new question I might have mentioned references in languages other than Java]

  • gran respuesta: respeta por igual los lenguajes de bajo nivel como C y los lenguajes de alto nivel..!

    – Jay D.

    6 de junio de 2012 a las 18:40

Esto es como preguntar, “¿qué es esta obsesión con las instrucciones de la CPU? ¿Me pierdo algo al no esparcir instrucciones MOV x86 por todas partes?”

tu solo necesitar punteros al programar en un nivel bajo. En la mayoría de las implementaciones de lenguajes de programación de alto nivel, los punteros se usan tan extensamente como en C, pero el compilador los oculta al usuario.

Así que… No te preocupes. Ya está usando punteros, y sin los peligros de hacerlo incorrectamente. 🙂

avatar de usuario
Fóstah

Veo punteros como una transmisión manual en un automóvil. Si aprende a conducir con un automóvil que tiene transmisión automática, no será un mal conductor. Y aún puede hacer casi todo lo que pueden hacer los conductores que aprendieron en una transmisión manual. Sólo habrá un agujero en su conocimiento de la conducción. Si tuviera que conducir un manual, probablemente estaría en problemas. Claro, es fácil entender el concepto básico, pero una vez que tienes que empezar en una colina, estás jodido. Pero, todavía hay un lugar para las transmisiones manuales. Por ejemplo, los pilotos de autos de carrera deben poder cambiar de marcha para que el auto responda de la manera más óptima a las condiciones de carrera actuales. Tener una transmisión manual es muy importante para su éxito.

Esto es muy similar a la programación en este momento. Hay una necesidad de desarrollo C/C++ en algún software. Algunos ejemplos son juegos 3D de gama alta, software integrado de bajo nivel, cosas en las que la velocidad es una parte crítica del propósito del software y un lenguaje de nivel inferior que le permite un acceso más cercano a los datos reales que deben procesarse es clave para ese rendimiento. . Sin embargo, para la mayoría de los programadores este no es el caso y no conocer los punteros no es paralizante. Sin embargo, creo que todos pueden beneficiarse al aprender sobre C y punteros, y también transmisiones manuales.

  • -1, no explica nada más que afirmar que el puntero es útil.

    – Johan

    5 oct 2013 a las 16:17

Ya que has estado programando en lenguajes orientados a objetos, déjame ponerlo de esta manera.

Obtiene el Objeto A, crea una instancia del Objeto B y lo pasa como un parámetro de método al Objeto C. El Objeto C modifica algunos valores en el Objeto B. Cuando regresa al código del Objeto A, puede ver el valor modificado en el Objeto B. ¿Por qué esto es tan?

Porque pasaste en un referencia del Objeto B al Objeto C, no hizo otra copia del Objeto B. Entonces, el Objeto A y el Objeto C tienen referencias al mismo Objeto B en la memoria. Cambia de un lugar y se ve en otro. Esto se llama Por referencia.

Ahora, si usa tipos primitivos en su lugar, como int o float, y los pasa como parámetros de método, el Objeto A no puede ver los cambios en el Objeto C, porque el Objeto A simplemente pasó un Copiar en lugar de una referencia de su propia copia de la variable. Esto se llama Por valor.

Probablemente ya sabías eso.

Volviendo al lenguaje C, la Función A pasa a la Función B algunas variables. Estos parámetros de función son copias nativas, por valor. Para que la Función B manipule la copia que pertenece a la Función A, la Función A debe pasar un puntero a la variable, para que se convierta en un pase Por Referencia.

“Oye, aquí está la dirección de memoria de mi variable entera. Pon el nuevo valor en esa ubicación de dirección y continuaré más tarde”.

Tenga en cuenta que el concepto es similar pero no 100% análogo. Los punteros pueden hacer mucho más que simplemente pasar “por referencia”. Los punteros permiten que las funciones manipulen ubicaciones arbitrarias de memoria a cualquier valor requerido. Los punteros también se utilizan para apuntar a nuevas direcciones de código de ejecución para ejecutar dinámicamente lógica arbitraria, no solo variables de datos. Los punteros pueden incluso apuntar a otros punteros (puntero doble). Eso es poderoso pero también bastante fácil de introducir errores difíciles de detectar y vulnerabilidades de seguridad.

  • -1, no explica nada más que afirmar que el puntero es útil.

    – Johan

    5 oct 2013 a las 16:17

avatar de usuario
usuario9282

Si no has visto punteros antes, seguramente te estás perdiendo esta mini-joya:

void strcpy(char *dest, char *src)
{    
        while(*dest++ = *src++);
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad