¿Cuál es una buena explicación para los punteros? [cerrado]

71

En tus propios estudios (por tu cuenta o para una clase), ¿tuviste un momento "ah ha" en el que finalmente entendiste los punteros? ¿Tiene una explicación que usa para los programadores principiantes que parece particularmente efectiva?

Por ejemplo, cuando los principiantes se encuentran con los punteros en C, pueden simplemente agregar & s y * s hasta que se compile (como lo hice una vez). Tal vez fue una imagen, o un ejemplo realmente bien motivado, lo que hizo que los punteros "hicieran clic" para usted o su estudiante. ¿Qué fue y qué probaste antes que parece que no funcionó? ¿Hubo algún requisito previo de los temas (por ejemplo, estructuras o matrices)?

En otras palabras, ¿qué era necesario para comprender el significado de & sy * , cuando podría usarlos con confianza? Aprender la sintaxis y la terminología o los casos de uso no es suficiente, en algún momento la idea debe ser internalizada.

Actualización: Realmente me han gustado las respuestas hasta ahora; por favor sigan viniendo Hay muchas perspectivas excelentes aquí, pero creo que muchas son buenas explicaciones / eslóganes para nosotros mismos después que hemos internalizado el concepto. Estoy buscando los contextos y circunstancias detallados cuando se te ocurrió.

Por ejemplo:

  

Sólo entendí un poco los punteros   sintácticamente en C. Oí dos de mis   amigos explicando los punteros a otro   amigo, quien preguntó por qué un struct era   Pasó con un puntero. El primero   amigo habló sobre cómo se necesitaba   Ser referenciado y modificado, pero fue   sólo un breve comentario de la otra   amigo donde me golpeó: "es también   Más eficiente. "Pasando 4 bytes.   en lugar de 16 bytes fue el final   Cambio conceptual que necesitaba.

    
pregunta Macneil 30.07.2015 - 15:56

32 respuestas

25

Diagrama de memoria como una cuadrícula

Por lo general, lo que hago es representar la memoria como una "cuadrícula", de modo que pueda inventar direcciones, resaltar diferentes espacios de memoria y escribir en los valores de las celdas (o incluso más, sus representaciones binarias) y vincular los punteros en la memoria para Los valores a los que apuntan. (Y luego mencionar que es una simplificación).

Por lo general, es un momento "ohhhh" para la mayoría de mis alumnos.

Malabares de símbolos

Luego, cuando se trata de que dejen de olvidar cómo usar & y *, es muy simple: preséntelo de la misma manera que hacen los cálculos matemáticos o físicos. Si divide una distancia en km por un tiempo en hora, obtiene una velocidad en km / h. Lo que hay en tiene que estar fuera. Simple.

printf al Rescate

Hacer solo unos pocos ejemplos básicos que representan visualmente lo que explicaste con ellos los reconforta en lo que creen que entendieron, o les da la oportunidad de decir "ah, no entiendo esto".

Sea extenso

Cubra los punteros para tipos simples y asegúrese de que comprendan la diferencia entre el direccionamiento y el tamaño de un tipo de datos, luego las estructuras, luego las matrices y los múltiples niveles.

Luego inicia la aritmética de punteros.

Addendum: Recursion

Usualmente explico la recursión de manera similar, usando una representación visual. Pídales que impriman el alfabeto usando una función prefabricada que escribe un solo carácter y luego pídales que lo impriman en orden inverso simplemente cambiando dos líneas.

Por lo general, hay un "¿qué ...?" momento, y cuando agrega solo otro parámetro a su printf para imprimir valores numéricos y sangrar los pasos, se convierte en un suspiro de alivio.

Alternativas: el modelo Play-Doh y las copas de agua

De hecho, tuve algunos compañeros de trabajo en una universidad que les mostraron a los estudiantes un video que explica los punteros y los accesos a la memoria usando Play-Doh Paste. Fue increíblemente inteligente y bien hecho, aunque yo nunca utilicé esa técnica, a excepción de los estudiantes muy jóvenes interesados en comprender la programación (pero generalmente aquellos a los que no los llevaría a un lenguaje usando punteros demasiado pronto). Básicamente, utiliza pequeñas bolas de play-doh que puedes unir a otras bolas más grandes de play-doh que representan espacios de memoria, y que puedes combinar para vincularlas (como en una estructura de datos vinculada) o combinarlas (como en un contiguo). espacio de memoria). El uso de diferentes colores para los espacios de memoria apuntados y los punteros también ayudan. Pero sigo pensando que la cosa de la memoria como una cuadrícula funciona mejor, ya que se puede demostrar claramente que la señalización es realmente una cuestión de "direccionamiento", como en un "mapa / cuadrícula". Mientras que el modo Play-doh todavía los confunde al pensar que las cosas realmente se "tocan" entre sí en la memoria.

La cosa de la Copa del agua también fue utilizada directamente por un colega, pero no sé si se le ocurrió. Fue un enfoque interesante, pero noté que muchos estudiantes quedaron desconcertados por la explicación. Algo parecido a técnica de la taza de café de DevSolo . Pero creo que en realidad es engañoso, ya que haces que los estudiantes confundan contenedores, estructuras de datos, punteros y matrices. Podría ser un enfoque interesante para explicar las matrices al principio, supongo, pero no me atendré a ello por mucho tiempo.

    
respondido por el haylem 12.04.2017 - 09:31
79

Alguien mucho más sabio de lo que dije una vez:

  

La monja Wu Jincang preguntó a la Sexta.   Patriach Huineng, "he estudiado la   Mahaparinirvana sutra durante muchos años,   Sin embargo, hay muchas áreas que no   entiendo muy bien. Por favor ilumina   yo. "

     

El patriach respondió: "Yo soy   analfabeto. Por favor lea el   Personajes para mi y tal vez estare.   capaz de explicar el significado. "

     

Dijo la monja: "Ni siquiera puedes   Reconocer a los personajes. Cómo estás   ¿Entonces para entender el significado? "

     

"La verdad no tiene nada que ver con las palabras.   La verdad puede ser comparada con lo brillante.   luna en el cielo. Palabras, en este caso,   Puede ser comparado a un dedo. El dedo   puede apuntar a la ubicación de la luna.   Sin embargo, el dedo no es la luna.   Para mirar a la luna, es necesario.   para mirar más allá del dedo, ¿verdad? "

    
respondido por el Frank Shearar 09.11.2010 - 16:16
46

Encontré que los diagramas fueron muy útiles. Ejemplo:


Este tipo de diagrama me ayudó a ver que los punteros eran su propia variable, pero contenían un valor que era la ubicación de otro objeto, es decir, una matriz o una cadena. Además, cuando termine a lápiz, podría usarlo para trazar mi programa en papel o en una pizarra / pizarra.

    
respondido por el Michael K 09.11.2010 - 21:02
32

La primera vez que "aprendí" acerca de los punteros, fue como que me empujaron a ello. Mi universidad había tomado la decisión mucho tiempo antes de inscribirme para centrar el plan de estudios en torno a Java, por lo que cuando mi profesor de Estructuras de datos dio una conferencia en C y nos pidió que implementáramos una lista XOR con sugerencias, sentí que estaba entrando en algo. manera sobre mi cabeza.

Entendí la definición:

  

Un puntero es una variable que contiene   una dirección de una variable

Pero todavía no entendía gran parte del concepto. Mirando hacia atrás, creo que se centró en tres cosas:

  1. ¿Qué es exactamente es una ubicación de memoria? (En ese momento no tomé una clase de Organización de Computadoras)

  2. La sintaxis incómoda (Entonces, um ... por qué exactamente se define como "int * ip" pero luego me refiero a la variable como "ip"?)

  3. ¿Qué tan exactamente es beneficioso almacenar la dirección de una variable en lugar de simplemente usar la variable?

No fue hasta que compré el libro K & R y terminé todos los problemas que realmente entendí los indicadores. Además del hecho de que durante mucho tiempo completé la clase de Organización de la Computadora (que creo que debería requerirse antes de aprender C), parte de esto tuvo que ver con el hecho de que me di cuenta de que los punteros se pueden usar para funciones, matrices, estructuras ... para hacer cosas útiles y no simplemente como almacenamiento para direcciones de variables ordinarias.

Sin embargo, mi momento "aha" fue el modo en que K & R explicó la torpe sintaxis de definir un puntero simple. Tomé notas a lo largo del libro (en el que reformulo los puntos hechos por el libro en mis propias palabras para mejorar mi comprensión), y este es el relacionado con eso:

  

Un puntero es una variable que contiene   Una dirección a una variable. Un puntero es   tanto definidos como desreferenciados   (dando el valor almacenado en el   ubicación de memoria que apunta a)   con el operador '*'; la expresion   es mnemotécnico.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

Siempre sentí que no podía captar completamente los conceptos más avanzados de los punteros hasta que tenía algo tan elemental arraigado en mi cabeza. Después de esa tarea me había molestado infinitamente (por cierto, no me fue muy bien) por qué "* ip" no existía justo después de que (pensé que) definí "* ip". Dominar esto es esencial para conceptos más avanzados que incluyen punteros, como punteros de función y definiciones más complicadas como esta:

char (*(x())[])()

En definitiva, creo que el concepto de punteros requiere:

  1. Una comprensión básica de cómo la memoria se presenta en una computadora (y que la memoria es).

  2. Conocimiento de cuán poderoso     Los punteros pueden ser (uso del mundo real,     no es solo otro concepto abstracto     que aprendan por el bien de     aprendizaje).

  3. Descifrando el     jeroglíficos conocidos coloquialmente como     "una definición de un puntero"

Así que, en general, creo que debería haber al menos 3 momentos "aha" al aprender sobre los punteros. Todavía soy un estudiante, así que pensé que apreciarías el punto de vista de alguien que todavía está (relativamente) recién aprendiendo el concepto.

    
respondido por el Kevin 10.11.2010 - 01:01
18

El puntero es un poco como los accesos directos de aplicaciones en su escritorio. Eliminar el acceso directo y el destino sigue existiendo. Inicia el acceso directo y se inicia el destino.

Siempre explico el funcionamiento de esto simplemente creando un archivo txt en mi escritorio y dos accesos directos al archivo. Después de copiar y eliminar los accesos directos, puede ver que las personas entienden la idea detrás de las "referencias".

Una vez que el grupo entienda lo básico detrás de los accesos directos, puede comenzar a explicar los punteros de la forma que desee. Probablemente lo entenderán con bastante facilidad.

    
respondido por el Barfieldmv 10.11.2010 - 12:00
12

Hace 8-10 años, enseñé un curso de introducción "C" en un colegio comunitario. Este fue siempre un tema divertido para explorar. Lo que parecía funcionar mejor, y esto fue después de discutir con un compañero de trabajo varias veces, fue usar una taza de café y la mano.

Utilicé la analogía de una taza de café (o una fila de ellas para arreglos) como variable (puede contener algo). Luego usé mi mano, que también podía sostener algo o, extendiendo mi dedo índice para "señalar" una taza de café.

Una mano cercana era nula, un dedo apuntando a mi cabeza (como una pistola simulada) era un puntero colgante.

Luego, con algunas demostraciones y viajes a través del depurador, hizo clic con la mayoría.

    
respondido por el DevSolo 09.11.2010 - 16:20
10

Realmente me preocupo bastante cuando escucho la pregunta "¿Cómo conseguiste una idea de los punteros?" Siempre pensé que el concepto era increíblemente simple, y una evolución lógica de los lenguajes que proporciona un gran poder a los programadores.

Lo que me preocupa es que nunca me resultó difícil entender el concepto de punteros. Entonces, cuando estás aquí "cuando finalmente lo obtuviste" una y otra vez, empiezas a pensar:

  

¿Realmente lo entiendo? Tal vez nunca lo hice?

Tal vez la razón por la que el concepto parece ser complicado es porque seguimos diciéndole a todos los que aún no los han encontrado que los indicadores son tan difíciles, y aquí hay cientos de maneras en las que puedes aprender.

Simplemente estoy lanzando esa idea, por supuesto, personalmente me encanta un buen diagrama y ¡Steve Gibson siempre hace un trabajo fantástico de explicar cualquier cosa !

    
respondido por el Marcus Whybrow 11.11.2010 - 09:45
7

Nunca tuve muchos problemas con los punteros en C, pero eso puede deberse a que primero tuve que aprender el ensamblador. En realidad, fue un alivio no tener que gestionar las direcciones por mi cuenta. Entonces, tal vez la respuesta (suponiendo que esto es algo que estás enseñando) es darles a los estudiantes un lenguaje de ensamblaje emulado con el cual trabajar. Ellos lo lo resolverán en el proceso de escribir algo más sofisticado que "Hola, mundo".

    
respondido por el Larry Coleman 09.11.2010 - 18:31
6

¿Cómo aprendí realmente acerca de los punteros? Escribiendo un simple compilador de primer año de universidad.

¿Cómo explicar los punteros en términos sencillos? Me gusta la analogía (¿con fecha?) De un catálogo de biblioteca almacenado en tarjetas de índice. Cada tarjeta ("puntero") contiene información sobre dónde se encuentra algún libro ("datos"), pero en realidad no contiene el libro en sí. Si modifica la tarjeta ("aritmética de punteros"), todo lo que hace es cambiar el libro al que apunta y no tiene ningún impacto en el libro en sí, solo tenga cuidado de no arruinar la dirección o podría apuntar a un libro inexistente. o incluso la biblioteca equivocada. Sin embargo, si sigue la "dirección" en la tarjeta y va a la parte adecuada de la biblioteca ("quita la referencia al puntero"), puede ver / modificar el libro en sí.

    
respondido por el Yevgeniy Brikman 09.11.2010 - 19:36
6

Un puntero es una variable cuyo valor es la dirección de memoria de otra variable.

    
respondido por el kirk.burleson 09.11.2010 - 20:26
5

Supondré que alguien que va a aprender punteros sabe cuáles son las variables normales y cómo funcionan en C. Ahora, intentemos definir punteros con algunos de sus atributos-

  • También son variables, pero de diferente naturaleza. Supongamos que hay dos capas en el espacio variable. Las variables normales de diferentes tipos residen en la capa superior y los punteros en la capa inferior. Como esta figura-

  • Comosugiereelnombre'Pointer',lospunterospuedenapuntaraalgo.Comonuestrodedopuedeapuntaraalgúnobjeto.¿Cuálessonlascosasqueapuntan?Estassonlasvariablesnormales.Enresumen,"los punteros apuntan a variables normales".

  • Al igual que las variables normales, los punteros también son del mismo número de tipos, como int, char o float. Y un puntero de un tipo específico puede apuntar a solo el mismo tipo de variables.
  • Un puntero puede apuntar a una variable y luego el mismo puntero puede apuntar a otra variable. Sólo el tipo debe ser el mismo. Por lo tanto, la asociación de un puntero con alguna variable no es permanente y se puede cambiar.
  • Entonces, ¿cómo se declara un puntero? Casi como variables normales. Debe preceder el nombre con un asterisco ( * ). Me gusta-

    int *pointer;
    
  • Entonces, ¿cómo se asocia un puntero a una variable? Usando el operador & antes de la variable como esta declaración-

    pointer = &variable;
    
  • ¿Cómo se usa un puntero apuntando a una variable? Esto también se hace precediendo el nombre con un asterisco ( * ). Luego se puede usar en lugar de la variable que está apuntando ahora-

    *pointer = var1 + var2;
    

    en lugar de

    variable = var1 + var2;
    
  • Ahora, juega con punteros con algún código. Solo acostúmbrate a estas características de los punteros ahora. Hasta este punto, estamos hablando de lo que hacen los punteros. Una vez que esté de acuerdo con eso, comience a estudiar cómo apuntan los punteros a una variable y cómo reaccionan si se les aplican operaciones aritméticas normales. Luego vaya a la relación entre punteros y matrices y punteros a punteros.

Eso es todo lo que sugeriré sobre los punteros de aprendizaje.

    
respondido por el Gulshan 10.11.2010 - 06:30
5

Editado en apoyo del requisito revisado de la pregunta

Mi camino hacia el entendimiento "post-puntero" (si recuerdo bien) fue así. Tuve una experiencia sencilla en la programación de ensamblajes cuando aún estaba andando por ahí con un BBC Micro , así que tuve el concepto de memoria como un montón de cajas (ver más abajo para esto). Esto fue reforzado por el uso de matrices. Sin embargo, estaba entrando en el mundo de C y tuve que lidiar con las cadenas y eso significaba punteros. En BASIC esto fue trivial, en ensamblador nunca tuve que trabajar con ellos, y ahora en C clásico todo es punteros y cosas. Ah, pero puedo volver a los arreglos con cadenas (terminadas en nulo) como esta:

char s[] = "Hello, world!";
printf("%s",s);

Todo muy bien, eso es solo una serie de caracteres (8 bits por carácter en mi pequeño mundo) con un carácter cero al final para mostrar dónde termina. El printf solo toma esa matriz y corre sobre ella imprimiéndola. Pero, ¿y si quiero pasar esta cadena a una función?

void print_str(char* p) {
  printf("%s",p);
}

¿Es lo que dice el manual, pero de qué se trata? Hmm, char * significa "puntero a un char". Ok me perdiste Entonces me di cuenta de que el carácter * hace que p sea equivalente a s [0]. Está bien, puedo usar eso, pero todavía no he manipulado qué son los punteros. Quiero decir, ¿cómo puedo configurar algunos datos con una de estas cosas? De vuelta al manual otra vez ...

char* p = "Hello World!";

Mientras escribo lo anterior, me digo a mí mismo "declarar un puntero a un carácter y establecerlo como este conjunto de caracteres". De alguna manera ese puntero elimina la necesidad de una matriz. Supongo que es el compilador haciendo algunas cosas por mí para un cambio. Entonces, ¿cómo puedo cambiar la matriz con este puntero? Sé que podría usar la versión de matriz

 s[2] = 'L'; 

pero ¿cuál es el equivalente en "puntero hablar"? De vuelta a ese manual otra vez ...

*(p+2) = 'L';

Supongo que * simplemente significa "el contenido de la dirección de memoria" y (p+2) es s[2] . Lo que significaba que el puntero p era ... simplemente ... una ... dirección ... ¡bong!

Que hay el sonido de la iluminación. De repente, piqué los punteros (fue hace mucho tiempo, nosotros, los antiguos, no "creímos" hasta más tarde). Fue simplemente indirección.

Original:

OK, mi valor 2c:

Imagina que la memoria es un montón de cajas. Cada casilla tiene un número en el lado (la dirección). Cada caja contiene un número (el contenido). Puede trabajar con estos cuadros de dos maneras: variables (quiero el contenido del cuadro N), punteros (quiero el contenido del cuadro cualquiera que sea el cuadro N ). Los punteros son simplemente indireccionales.

Y para la gran respuesta que cubre todo lo que siempre necesitarás saber, lee esto .

    
respondido por el Gary Rowe 02.12.2010 - 01:04
4

Consigue algunos pequeños bloques de madera.

agrega ganchos de metal en un extremo y ojos de metal en el otro.

ahora puedes hacer una lista vinculada con cosas con las que puedes jugar.

Intenta explicar con este apoyo físico. A menudo deseaba tener esto cuando enseñaba a los estudiantes de primer año (estudiantes de primer año) a los punteros.

El pequeño gancho de metal es el puntero, el bloque de madera al que apunta la cosa.

DEFIERO que alguien no lo obtenga después de jugar con los bloques.

    
respondido por el Tim Williscroft 11.11.2010 - 23:45
4

Hice mi vida más fácil cuando eliminé toda la pelusa y comencé a tratar el puntero como cualquier otra variable en lugar de alguna entidad mágica (hace mucho tiempo en el grado 11). Solo sé 3 cosas:

  1. El puntero es una variable que almacena la dirección de otra variable (o simplemente de cualquier dirección).
  2. * se usa para obtener el valor en la ubicación de la memoria que está almacenada en la variable del puntero.
  3. & el operador da la dirección de una ubicación de memoria.

El resto es azúcar sintáctico y sentido común. Solo escribe algunos programas simples en C (como implementar una biblioteca de listas vinculadas) usando punteros para entenderlo.

    
respondido por el Sridhar Iyer 11.11.2010 - 23:59
2
  1. El puntero se puede considerar como una generalización de un índice en una matriz.
    • Considere que una matriz grande se puede cortar en una serie de matrices de tamaño variable, no superpuestas, más pequeñas. Ahora, estos arreglos más pequeños son lo que usualmente consideramos como arreglo. El más grande es el espacio de memoria de toda la computadora. El proceso de cortar matrices más pequeñas se llama asignación de memoria.
  2. Un conjunto de estructuras que están enlazadas entre sí por algunos punteros puede considerarse como un gráfico dirigido .
    • Cada vértice es una variable que puede contener algún valor.
    • Algunas variables son punteros, y cada puntero puede tener exactamente un borde saliente en otra cosa.
    • Las variables que no son punteros no tendrán ningún borde de salida. Podrían tener cualquier cantidad de ventaja entrante.
respondido por el rwong 10.11.2010 - 06:23
2

No puedo recordar las circunstancias en torno a mis punteros-aha-momento, pero he reajustado retroactivamente la memoria en mi entendimiento de una matriz de estilo c. (es decir, arr[3] es lo mismo que *(arr+3) )

Por alguna razón, me parece sumamente útil ver los punteros como matrices cuando me encuentro con una situación de puntero.

    
respondido por el Zaz 10.11.2010 - 09:16
2

Básicamente, @Gary Rowe presentó el modelo correcto. La memoria como un conjunto de cuadros con direcciones (números) en ellos. Cada caja almacena un valor (número).

La idea de un puntero es interpretar el valor en un cuadro como la dirección de otro cuadro. Este valor se utiliza para hacer referencia a un cuadro específico, por lo que se denomina referencia . Por lo tanto, desreferenciación es el proceso de abrir el cuadro al que se hace referencia.

si v es una variable (cuadro), entonces la declaración

  • v significa el valor de v , es decir, dame lo que hay en el cuadro
  • *v significa anular la referencia al valor de v , es decir, dame lo que está en el cuadro al que se hace referencia por el valor de v
  • &v significa la referencia v , es decir, dame la dirección en el cuadro

Creo que no sirve para presentar punteros como algo completamente diferente. Era un concepto difícil de comprender cuando era un niño. Siempre parecía una magia oscura que nunca entendí, que necesitaba muchos caracteres especiales. La primera vez que lo entendí fue cuando escribí un juego pequeño con doble dirección indirecta en un lenguaje que no tiene aritmética de punteros. Eso me iluminó.

Los punteros son una cuestión de interpretación. Creo que explicar eso hace las cosas mucho más fáciles. Y la aritmética de punteros son operaciones extremadamente simples e intuitivas si se muestra un ejemplo simple con una memoria de 10 variables.

    
respondido por el back2dos 10.11.2010 - 13:04
2

La explicación que realmente me sorprendió fue:

  

Considere una cuadrícula de la ciudad con diferentes casas construidas en terrenos.   En tu mano sostienes un pedazo de papel. En el papel que has escrito:

     

La casa de David,

     

112 tal y tal calle.

     

La hoja de papel (variable de puntero) contiene una dirección que apunta a la casa de David. Cuando quiere decirle a un amigo que eche un vistazo a la casa fresca de David, es mucho más fácil usar el pedazo de papel como referencia a la casa que enviar el edificio real de dos pisos por correo.

     

Al igual que con los punteros reales, puedes tener algunos problemas cuando sigues la dirección en tu hoja de papel. David podría haberse movido y cuando llegas allí, simplemente encuentras un gran agujero en el suelo. En este caso, hubiera sido mejor borrar la dirección en el papel cuando David se mudó o al menos cambiarla por la nueva. También puedes encontrar que vas a la dirección y entras en lo que crees que es la sala de estar de tu amigo David, pero esta vez terminas en una piscina completamente desconocida. Alguien más ha usado el espacio en la dirección que tenía para algo completamente diferente.

    
respondido por el Per Wiklander 12.11.2010 - 00:20
2

Si quieres explicar los punteros, primero debes explicar la memoria. Usualmente hago eso con papel cuadriculado / cuadrado con filas y columnas. Si el "estudiante" entiende la memoria, ella puede entender qué es una dirección. Si tienes una dirección, tienes punteros.

Puedes jugar con esta abstracción. P.ej. escriba la dirección (número) de un cuadrado en otro cuadrado. Ahora dibuja una flecha desde el cuadro del puntero hasta el cuadro de destino. Ahora sobrescriba el puntero (por ejemplo, increméntelo) y ajuste la flecha. Escriba una dirección en otra casilla y deje que el alumno dibuje la flecha ...

Siguiente paso: asigne un nombre a ciertos cuadrados (como el puntero). Ahora puedes explicar la desreferenciación. Eso es.

    
respondido por el EricSchaefer 13.11.2010 - 16:27
2

Quizás sea solo yo, pero trabajo bien con analogías. Así que digamos que tienes un amigo (función / clase) "Foo", que quiere tener a otra persona (función / clase diferente), "Barra", te contacta por alguna razón. "Foo" podría llevarte a ver "Bar", pero eso no es conveniente, mover a todos esos seres (instancias) alrededor. Sin embargo, "Foo" podría enviar a "Bar" su número de teléfono (puntero). De esa manera, sin importar dónde se encuentre, "Foo" sabe cómo contactarlo sin tener que encontrarlo.

Y, digamos que "Bar" tiene un conocido, "Baz", que también quiere ponerse en contacto contigo. Pero protege su número de teléfono y no quiere que todos tengan "Baz" puede llamar a "Bar" (teléfono como puntero), quien puede reenviarle la llamada (otro puntero). Y así una y otra vez en la cadena de amigos y amigas de "Baz".

    
respondido por el Hugo 14.11.2010 - 03:44
2

Los punteros hacen que way tenga más sentido si ha estudiado lenguaje ensamblador y / o arquitectura de computadora. Creo que si enseño una clase de C, comenzaría con un par de semanas de arquitectura para explicar el modelo de memoria y los tipos de instrucciones que realmente ejecuta el procesador.

    
respondido por el Barry Brown 18.11.2010 - 22:39
2

Mi "¡aha!" El momento llegó en este tutorial:

Un tutorial sobre punteros y matrices en C

Para ser exactos, vino en este capítulo: Capítulo 3: Punteros y cadenas

Para ser aún más preciso, vino con esta frase:

  

El parámetro pasado a puts () es un   puntero, ese es el valor de un   puntero (ya que todos los parámetros en C son   pasado por valor), y el valor de un   puntero es la dirección a la que   puntos, o, simplemente, una dirección.

Cuando leí eso, las nubes se separaron y los ángeles explotaron las fanfarrias de las trompetas.

Para, usted ve, cada tutorial en C o libro que había leído antes de eso había afirmado que C podría pasar por valor o por referencia, una mentira infeliz. La verdad es que C siempre pasa por valor, pero a veces el valor que pasa es una dirección. Dentro del método, se hace una copia de esa dirección, al igual que una copia se haría de un int. Pasado. Una copia no está hecha del valor al que apunta el puntero. De este modo, al utilizar el puntero dentro del método, puede acceder al valor original y cambiarlo.

Nunca me convertí en programador en C, pero sí en programador .NET, y los objetos y las referencias a objetos funcionan de la misma manera; la referencia al objeto se pasa por valor (y, por lo tanto, se copia), pero el objeto en sí no se copia. He trabajado con muchos programadores que no entienden esto porque nunca aprendieron punteros.

    
respondido por el Kyralessa 21.04.2011 - 22:11
1

El truco consiste en explicar que la ubicación de una cosa y la cosa en sí no son lo mismo, al igual que la imagen de una tubería no es una canalización . Cuando mueves una cosa, su ubicación cambia. La ubicación permanece y se puede colocar alguna otra cosa allí.

    
respondido por el sal 09.11.2010 - 16:24
1

Un puntero es una nota adhesiva que le indica dónde está algo útil. Contiene la ubicación de la cosa y te dice qué tan grande es la cosa (en C, de todos modos). Así que un puntero doble es como una nota adhesiva que dice "Hay un paquete de seis en el refrigerador". Tienes que ir a buscar el paquete de seis para saber si es Coca Cola o Budweiser.

    
respondido por el philosodad 09.11.2010 - 17:47
1

Dado el código:

int v=42; // declarando e inicializando una variable simple

int *p = &v; // creando un punto p a la variable v

Se puede decir lo siguiente sobre el código anterior:

int * p // "int pointer p" ... así es como declara un puntero a una variable de tipo int

*p // "señalado por p" ... esos son los datos a los que p apunta, es lo mismo que v.

&v // "dirección de la variable v" ... esto representa el valor literal para p

    
respondido por el zener 09.11.2010 - 23:50
1

enlace

Este sitio tiene excelentes tutoriales para aprender los punteros y la administración de la memoria.

Le sugeriría que camine a través de los conceptos básicos de los punteros, los indicadores y la memoria que se proporcionan en el sitio. También puede consultar los problemas de las listas vinculadas que aparecen en el enlace para fortalecer aún más los conceptos de puntero.

    
respondido por el deovrat singh 15.11.2010 - 07:43
1

La clave para explicar los punteros es asegurarse de que las personas a las que está explicando ya tengan un entendimiento del concepto de memoria. Aunque sería bueno si realmente lo entendieran en un nivel bajo, creer que la memoria existe como una matriz masiva y entender que puede acceder a cualquier posición en la matriz por su ubicación de índice es suficiente.

El siguiente paso, tener el concepto de pasar la ubicación del índice en lugar de copiar toda la memoria tiene sentido para la mayoría de las personas. Y eso es suficiente para permitir que la mayoría de las personas entiendan por qué los punteros son útiles.

el último paso para comprender los punteros es explicar cómo puede pasar como parámetro una ubicación de índice de memoria para que el método almacene la ubicación de índice donde se almacenan todos los datos. Descubrí que esto puede ser un paso demasiado lejos para que algunas personas puedan lidiar con él.

Una vez que alguien haya comprendido estos pasos básicos, es fácil que comprendan que puedes encadenar los punteros de forma indefinida, siempre y cuando mantengas un registro de las veces que necesitas mirar las direcciones para encontrar el objeto de datos real.

Una vez que alguien haya captado los punteros, lo siguiente que deben entender rápidamente es la diferencia entre la memoria del montón y la memoria de la pila, y por qué los punteros para apilar la memoria son peligrosos cuando se pasan fuera del método.

    
respondido por el Michael Shaw 02.12.2010 - 02:25
0

Recuerdo un libro "Rompecabezas de C" o similar, que leí simplemente porque era uno de los pocos libros relacionados con programación / computadora disponibles en la biblioteca, mi comprensión de C era rudimentaria. Le lanzó una expresión de C y le pidió que la explotara, cada vez más complicada.

    
respondido por el peterchen 10.11.2010 - 13:07
0

Cuando estaba en la universidad, mi profesor tenía algunas diapositivas de Powerpoint realmente nítidas que describían un punto como una variable independiente en sí misma con una flecha a una ubicación de memoria (representada como una matriz) y cuando estábamos haciendo listas vinculadas, lo haría hágalo paso a paso, mostrando cuándo cambia la flecha, cuándo se elimina la referencia del puntero, etc. No había manera de que uno no pudiera entenderlo en un par de minutos. El concepto en sí es realmente fácil, pero hacerlo bien o aplicarlo en programas prácticos requiere más práctica.

    
respondido por el chiurox 10.12.2010 - 14:38
0

Antes de hacer eso, explico que en la programación "todo usa memoria" y la asignación de variables (estática) en la memoria. También explicaré qué es una dirección de memoria y la relación entre el espacio de memoria, la dirección de memoria y las variables.

Finalmente, explico que hay variables y tipos de datos enteros, variables y tipos de datos de cadenas ... y así sucesivamente, hasta explicar que hay un tipo de datos especial que almacena direcciones de memoria, que tiene un valor vacío como 0 o "", llamado nulo .

Y, finalmente, variables asignadas dinámicamente mediante el uso de punteros.

    
respondido por el umlcat 11.03.2011 - 22:27

Lea otras preguntas en las etiquetas