¿Las mentes jóvenes necesitan aprender los conceptos de puntero?

89

¿Por qué el maestro C Dennis Ritchie introdujo punteros en C? ¿Y por qué los otros lenguajes de programación como VB.NET o Java o C # los eliminaron? He encontrado algunos puntos en Google, y también quiero escuchar sus comentarios. ¿Por qué están eliminando los conceptos de puntero en los idiomas modernos?

La gente dice que C es el lenguaje básico y los punteros son el concepto que hace que C sea poderoso y sobresaliente y hace que C siga compitiendo con lenguajes más modernos. Entonces, ¿por qué eliminaron los punteros en los idiomas más modernos?

¿Crees que el conocimiento de los punteros sigue siendo importante para los nuevos programadores? La gente está usando VB.NET o Java en estos días, que admite funciones más avanzadas que C (y no utiliza ningún concepto de puntero) y muchas personas como veo ahora (mis amigos) eligen estos lenguajes ignorando C ya que admiten funciones avanzadas. Les digo que comiencen con C. Dicen que es un desperdicio aprender los conceptos de punteros cuando estás haciendo cosas avanzadas en VB.NET o Java que no son posibles en C.

¿Qué piensas?

Actualizado :

Los comentarios que leí en Google son:

  1. Las computadoras anteriores eran demasiado lentas y no estaban optimizadas.

  2. El uso de punteros permite acceder a una dirección directamente y esto ahorra tiempo en lugar de hacer una copia de ella en las llamadas a funciones.

  3. La seguridad es significativamente peor usando punteros, y es por eso que Java y C # no los incluyeron.

Estos y algo más de lo que encontré. Todavía necesito algunas respuestas valiosas. Eso sería muy apreciado.

niko
fuente
52
Java no tiene punteros? Eso no es cierto. Cada referencia de objeto en Java es, básicamente, un puntero.
quant_dev
20
Lo que quant_dev significa es que Java está lleno de punteros que se usan de forma transparente, mientras que los programadores no pueden usarlos explícitamente.
sakisk
99
Aquí hay un artículo de Joel Spolsky que es relevante ... joelonsoftware.com/articles/fog0000000319.html
Joe Internet
11
"¿Por qué el maestro C Dennis Ritchie introdujo punteros en c?" Los punteros no se introdujeron en c, vinieron directamente de la práctica de ensamblaje, nombre incluido.
dmckee
14
@quaint_dev: Bueno, Java realmente no tiene punteros. Las referencias no pueden hacer todo lo que los punteros pueden hacer, por lo que intentar comprender los punteros en términos de referencias no es el camino a seguir (y un error que muchos programadores que aprenden C o C ++ hacen). Los punteros pueden hacer aritmética. Las referencias no pueden. (Una limitación que realmente apesta cada vez que me veo obligado a usar Java)
Billy ONeal

Respuestas:

128

En aquellos días, los desarrolladores estaban trabajando mucho más cerca del metal. C fue esencialmente un reemplazo de nivel superior para el ensamblaje, que está casi tan cerca del hardware como puede obtener, por lo que era natural que necesitara punteros para ser eficiente en la resolución de problemas de codificación. Sin embargo, los punteros son herramientas afiladas, que pueden causar grandes daños si se usan descuidadamente. Además, el uso directo de punteros abre la posibilidad a muchos problemas de seguridad, que no eran un problema en aquel entonces (en 1970, Internet consistía en unas pocas docenas de máquinas en un par de universidades, y ni siquiera se llamaba así ...), pero se volvió más y más importante desde entonces. Así que hoy en día los lenguajes de nivel superior están diseñados conscientemente para evitar punteros de memoria sin procesar.

Decir que "las cosas avanzadas hechas en VB.Net o Java no son posibles en C" muestra un punto de vista muy limitado, por decir lo menos :-)

En primer lugar, todos estos lenguajes (incluso el ensamblaje) están completos, por lo que, en teoría, todo lo que es posible en un idioma, es posible en todos. Solo piense en lo que sucede cuando se compila y ejecuta un fragmento de código VB.Net o Java: eventualmente, se traduce (o se asigna a) código de máquina, porque eso es lo único que la máquina entiende. En lenguajes compilados como C y C ++, en realidad puede obtener el cuerpo completo del código de máquina equivalente al código fuente original de nivel superior, como uno o más archivos / bibliotecas ejecutables. En los lenguajes basados ​​en VM, es más complicado (y puede que ni siquiera sea posible) obtener la representación de código de máquina equivalente completa de su programa, pero aún así está allí en algún lugar, dentro de las profundidades del sistema de tiempo de ejecución y el JIT.

Ahora, por supuesto, es una pregunta completamente diferente si alguna solución es factible en un idioma específico. Ningún desarrollador sensato comenzaría a escribir una aplicación web en conjunto :-) Pero es útil tener en cuenta que la mayoría o todos esos lenguajes de nivel superior están construidos sobre una gran cantidad de código de biblioteca de clase y tiempo de ejecución, una gran parte de que se implementa en un lenguaje de nivel inferior, generalmente en C.

Entonces, para llegar a la pregunta,

¿Crees que el conocimiento sobre los consejos para los jóvenes [...] es importante?

El concepto detrás de los punteros es indirección . Este es un concepto muy importante y, en mi humilde opinión, todo buen programador debería comprenderlo en cierto nivel. Incluso si alguien está trabajando únicamente con lenguajes de nivel superior, la indirección y las referencias siguen siendo importantes. No comprender esto significa no poder utilizar toda una clase de herramientas muy potentes, lo que limita seriamente la capacidad de resolución de problemas a largo plazo.

Entonces, mi respuesta es sí, si quieres convertirte en un programador verdaderamente bueno, también debes comprender los punteros (así como la recursividad: este es el otro obstáculo típico para los desarrolladores en ciernes). Es posible que no necesite comenzar con esto: no creo que C sea óptimo como primer idioma hoy en día. Pero en algún momento uno debería familiarizarse con la indirección. Sin ella, nunca podremos entender cómo funcionan realmente las herramientas, bibliotecas y marcos que estamos utilizando. Y un artesano que no entiende cómo funcionan sus herramientas es muy limitado. Es justo que uno también lo entienda en lenguajes de programación de alto nivel. Una buena prueba de fuego es implementar correctamente una lista doblemente vinculada: si puede hacerlo en su idioma favorito, puede afirmar que entiende la indirección lo suficientemente bien.

Pero si no fuera por otra cosa, deberíamos hacerlo para aprender a respetar a los programadores de antaño que lograron construir cosas increíbles utilizando las herramientas ridículamente simples que tenían (en comparación con lo que tenemos ahora). Todos estamos parados sobre los hombros de gigantes, y nos hace bien reconocer esto, en lugar de pretender que somos nosotros mismos los gigantes.

Péter Török
fuente
55
Esta es una buena respuesta, pero en realidad no responde a la pregunta: "¿Las mentes jóvenes necesitan aprender los conceptos de puntero?"
Falcon
11
+1 Buena respuesta. Sin embargo, dejaría caer el argumento de integridad de Turing: para la programación práctica, es un arenque rojo, como también notarás más adelante. Es la teoría de la computabilidad, es decir, estar completo solo significa que hay un programa en el espacio (para muchos idiomas, infinito) de programas potenciales que implementa el mismo algoritmo, no si es realmente factible o incluso humanamente posible. Solo señalar que todo es código de máquina al final prueba el punto igual de bien sin plantar el estúpido "¡Puedo hacer todo en un idioma ya que todos son lo mismo, harhar!" semilla.
55
+1 para "Y un artesano que no entiende cómo funcionan sus herramientas es muy limitado"
Rápidamente ahora el
66
Además, no comprender la mecánica de los punteros (y por referencias de extensión) significa que no comprende los conceptos de copia de estructura de datos superficial / profunda, lo que puede causar serios errores difíciles de rastrear. Incluso en idiomas "modernos" de alto nivel.
Mavrik
1
C fue diseñado para ser ensamblador portátil para Unix, es decir, cerca del metal.
39

Creo que necesitas diferir.

Java y otros lenguajes de nivel superior no eliminaron punteros. Lo que hicieron fue eliminar la aritmética de puntero simple.

De hecho, Java todavía permite una aritmética de puntero protegida y restringida : el acceso a la matriz. En la antigua C simple, el acceso a la matriz no es más que desreferenciar. Es una notación diferente, un azúcar sintáctico, si quieres, para comunicar claramente lo que estás haciendo.
Aún así, array[index]es equivalente a *(array+index). Por eso también es equivalente a, index[array]aunque supongo que algunos compiladores de C podrían darte una advertencia, si haces eso.
Como corolario, pointer[0]es equivalente a *pointer. Esto se debe simplemente a que el "puntero a una matriz" es la dirección de la primera entrada de la matriz y las direcciones de los elementos posteriores se calculan agregando el índice.

En Java, la aritmética de puntero simple (referencia y desreferenciación) ya no existe. Sin embargo, existen punteros. Los llaman referencias, pero no cambia lo que es. Y el acceso a la matriz sigue siendo exactamente lo mismo: mire la dirección, agregue el índice y use esa ubicación de memoria. Sin embargo, en Java, comprobará si ese índice está o no dentro de los límites de la matriz que asignó originalmente. Si no, arrojará una excepción.

Ahora la ventaja del enfoque de Java es que no tiene código, que simplemente escribe bytes arbitrarios en ubicaciones de memoria arbitrarias. Esto mejora la seguridad y también la seguridad, porque si no puede verificar los desbordamientos del búfer y demás, el tiempo de ejecución lo hará por usted.

La desventaja de esto es que es simplemente menos poderoso. Es posible realizar una programación segura de la memoria en C. Es imposible beneficiarse de la velocidad y las posibilidades de programación insegura en Java.

En realidad, no hay nada difícil sobre punteros o aritmética de punteros. Normalmente se explican de manera complicada, mientras que todo un puntero es un índice de una matriz gigante (su espacio de memoria), todo lo que hace referencia a un valor es darle al índice dónde encontrarlo, todo lo que hace la desreferenciación es buscar El valor en un índice dado. (Esto está un poco simplificado, porque no tiene en cuenta que los valores son de diferente tamaño en la memoria, dependiendo de su tipo. Pero eso es un detalle circunstancial, en lugar de una parte del concepto real)

En mi humilde opinión, todos en nuestro trabajo deberían ser capaces de entender eso, o simplemente están en el campo equivocado.

back2dos
fuente
13
+1 Java y C # todavía tienen punteros y, por supuesto, NullPointerExceptions
jk.
55
También tenga en cuenta que las referencias pueden apuntar a diferentes áreas con el tiempo, ya que el recolector de basura mueve las cosas. Los punteros suelen ser estáticos.
3
+1: esto! Y creo que hay dos cosas difíciles de entender sobre los punteros (en general): la indirección (que ocurre en C, C #, Java, ...) y la aritmética de punteros (que no sucede en Java de la misma manera). En mi opinión, ambos son conceptos importantes para aprender y ambos son grandes obstáculos para los principiantes. Pero no deben confundirse: la indirección puede suceder sin la aritmética del puntero.
Joachim Sauer
2
En realidad, back2dostenía razón la primera vez, ya que (array + index)ya tiene en cuenta el tamaño de los objetos (en C).
Matthew Flaschen
44
@CyberSkull, la respuesta fue dar el equivalente sintáctico de array[index], y eso es todo *(array+index). Si desea mostrar cómo el compilador hace las cosas internamente, puede hablar explícitamente sobre bytes o dar el ensamblado.
Matthew Flaschen
24

El concepto de punteros es importante en el cuerpo de conocimiento general de programación de computadoras. Comprender el concepto es bueno para ser programadores o programadores de cualquier idioma, incluso si el idioma no lo admite directamente.

Los punteros tienen su uso en estructuras de datos (listas vinculadas) y diseño de bases de datos (clave externa).

Lenguajes como VB y C # pueden pasar datos por "referencia" a métodos, que pueden considerarse como un tipo de puntero.

Comprender dónde se asignan los datos en la memoria (pila vs. montón) sigue siendo importante para la eficiencia de los algoritmos.

Aprender los conceptos básicos correctamente es importante en mi opinión.

Ninguna posibilidad
fuente
Creo que el concepto general es útil, pero nunca he encontrado una situación en la que necesite un puntero (siempre que use Java y PHP principalmente). Los únicos ejemplos que obtuvieron mis cursos de C ++ para los punteros fue usarlos para crear estructuras de datos más complejas, como listas y diccionarios que existen en cualquier lenguaje de programación de alto nivel para empezar ...
Ben Brocka
2
En cierto modo, tiene razón, pero cuando pasa datos a métodos, lo más probable es que, en algunos casos, pase un puntero a la variable. Sin embargo, el concepto de puntero es útil (en mi opinión) independientemente de su implementación en un lenguaje de software.
NoPuerto
1
@SirTapTap: Eso es porque si aprendiste C ++ en algún tipo de curso, te enseñan C ++. No es la mejor manera de usar C ++. La aritmética de puntero generalmente se pasa por alto porque es algo con lo que puedes tener un conocimiento pasajero de C ++ y no saberlo. Pero incluso cosas como iterar sobre una colección general se hacen con punteros en C ++ real / idiomático. (Como es la base de cómo funciona la Biblioteca de plantillas estándar)
Billy ONeal
@BillyONeal Pointers fueron casi la mitad del curso, realmente, todavía nunca encontré un uso práctico para punteros (inteligentes) como programador, dado que nunca he necesitado ese control directo sobre la memoria en nada que haya hecho. Por supuesto, siempre existe la posibilidad de que el curso se haya enseñado mal, no era exactamente mi favorito.
Ben Brocka
1
@SirTapTap: Uso práctico: cada colección y algoritmo en el STL. std::sort, std::partition, std::find, Etc. Trabajan con los punteros, y trabajan con los objetos que actúan como punteros (iteradores). Y trabajan sobre cualquier colección general; listas vinculadas, matrices dinámicas, deques, árboles o cualquier otro tipo de colección definida por el usuario. No puedes ese tipo de abstracción sin punteros.
Billy ONeal
19

¡¡¡Si si SI SI y si!!!

Si no conoce los conceptos básicos, NUNCA podrá resolver los problemas realmente difíciles, extraños, difíciles y complicados que se le presenten.

Y si comprende los conceptos básicos realmente bien, es MUCHO más comercializable en el mercado laboral.


Trabajé una vez con un tipo que había estado programando durante 10 años y no tenía idea de cómo funcionaban los punteros. Yo (mucho más joven) pasé horas en una pizarra blanca educándolo. Eso me abrió los ojos. No tenía IDEA sobre tantas cosas básicas.

Sepa todo lo que pueda.

rápidamente_ahora
fuente
Pero, ¿cuáles son los conceptos básicos? Asamblea, código binario?
SiberianGuy
55
Si bien su punto general de "saber todo lo que pueda" es acertado, cuestionaría la idea de que "NUNCA podrá resolver los problemas realmente difíciles, extraños, difíciles y complicados que se le presenten" si usted No entiendo los punteros. Esto de alguna manera implica que todos los problemas difíciles pueden resolverse utilizando estos punteros "mágicos", lo cual no es el caso. Es útil conocer los conceptos entre punteros, pero no son directamente esenciales para muchos campos de programación.
Dan Diplo
44
@Idsa: no, aún más básico, muchos programadores de hoy en día ni siquiera saben cómo funcionan los transistores y las puertas lógicas en los chips 'ole', y seguramente deberían haber sabido cómo se mueven los electrones y el efecto de la incertidumbre cuántica en la miniaturización; ¡Ni siquiera he comenzado con charlatanes, liptons y bisontes! y las partículas de bisonte de Hipo!
Lie Ryan
2
Conceptos básicos ... cosas como cómo se almacenan las cosas. La diferencia entre un byte, una palabra, cómo funciona el trabajo con y sin signo. Cómo funcionan los punteros. Que personaje es. Cómo se codifican las cosas en ASCII (y en estos días, Unicode). Cómo se puede crear una lista vinculada en la memoria utilizando solo estructuras simples. Cómo funcionan realmente las cuerdas. De estas pequeñas cosas, crecen cosas más grandes.
rapid_now
55
Saber todo lo que puedas es un buen principio, pero creo que tienes el carro antes que el caballo. Los buenos desarrolladores se esfuerzan por aprender todo lo que pueden porque son buenos desarrolladores. El anhelo de conocimiento es un rasgo de un buen desarrollador. No es la causa de un buen desarrollador. Salir y aprender tanto como puedas no te hará un buen desarrollador. Te convertirá en una enciclopedia ambulante, nada más. Si eres un buen desarrollador, ENTONCES puedes APLICAR ese conocimiento que obtuviste para resolver problemas. Pero si aún no eras un buen desarrollador, el conocimiento no te dará mucho.
corsiKa
18

Sí, la comprensión es importante.

Hace unos meses estaba programando en C #, y quería hacer una copia de una lista. Por supuesto, lo que hice fue NewList = OldList;y luego comencé a modificar NewList. Cuando intenté imprimir ambas listas, ambas eran iguales, ya que NewListsolo era un puntero OldListy no una copia, por lo que en realidad estaba cambiando OldListtodo el tiempo. No me llevó mucho tiempo darme cuenta de eso, pero algunos de mis compañeros de clase no fueron tan rápidos y tuvieron que explicar por qué está sucediendo esto.

Ejemplo:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

Y, por supuesto, el resultado es así:

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

Saber cómo usarlos no es tan importante, ¡pero comprenderlos es crucial!

Bojan Kogoj
fuente
2
En vez por qué usarlos y cuándo utilizarlos es más importante :)
Niko
55
" NewListera solo un puntero a OldList" - para ser precisos, ambos NewListy OldListsolo eran punteros, refiriéndose al mismo Listobjeto.
Péter Török
También es importante comprender que la nueva lista para la que creó bya no tiene referencias y ahora es basura.
TMN
14

Apunta el concepto! = Apunta la aritmética! = Apunta la sintaxis

Lo primero siempre es importante, si necesita (y lo hace) comprender la copia profunda / superficial, pasar por referencia / pasar por valor, etc. Las otras dos solo importan si su idioma del día le permite usarlas.

Alien Life Form
fuente
1
Hoy en día necesita conocer solo el concepto básico de referencias, no la sintaxis / matemática del puntero. Aprendí punteros (con aritmética y sintaxis) en C en el pasado. Los lenguajes en los que ahora programo no tratan con punteros de estilo C que te permiten hacer cosas inseguras. Uno puede entender por qué en Python a=[1,2]; b=a; a.append(3)ambos ay los dos harán referencia bal mismo objeto [1,2,3]sin saber cosas como en C, el ielemento th de una matriz puede ser referenciado por arr[i]o i[arr]como ambos lo son *(arr+i). Prefiero cuando el idioma no se deja i[arr]usar.
dr jimbob
" Los otros dos solo importan si tu idioma del día te permite usarlos ". Esa oración lleva consigo su propio autodestructor. El idioma del día es, por definición, muy poco probable que sea el mismo idioma que se usa mañana. Y mañana es posible que se enfrente a un lenguaje con puntero habilitado. ¿Línea de fondo? Mejor uno lo entiende ahora, una vez y para siempre. No es tan difícil, pero vale la pena.
JensG
14

¿Por qué el maestro C Dennis Ritchie introdujo punteros en C?

Porque los punteros son un mecanismo muy poderoso que se puede usar de muchas maneras.

¿Y por qué los otros lenguajes de programación como VB.NET o Java o C # los eliminaron?

Porque los punteros son un mecanismo muy peligroso que puede ser mal utilizado de muchas maneras.

Creo que los programadores deberían aprender sobre los punteros, pero desde una perspectiva educativa, no es prudente presentarlos temprano. La razón es que se usan para tantos propósitos diferentes, que es difícil saber como principiante por qué está usando un puntero en una circunstancia particular.

Aquí hay una lista incompleta para qué se utilizan los punteros:

  • asignación dinámica ( new T)
  • estructuras de datos recursivas ( struct T { T* next; /* ... */ };)
  • iteradores sobre matrices ( for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • acceso compartido a objetos ( T* new_pointer = existing_pointer;)
  • subtipo polimorfismo ( T* pointer_to_base = pointer_to_derived;)
  • llamada heredada por referencia ( mutate(&object);)
  • tipos opcionales ( if (p) { /* ... */ })

Tenga en cuenta que el uso de un mecanismo único para todos estos conceptos demuestra tanto el poder como la elegancia para el programador experimentado y el gran potencial de confusión para alguien nuevo en la programación.

FredOverflow
fuente
" ¿Por qué el maestro C Dennis Ritchie introdujo punteros en C ? Porque los punteros son un mecanismo muy poderoso que puede usarse de muchas maneras". - No lo sé con certeza, pero supongo que tiene algo que ver con las instrucciones de la máquina para incluirlas en el lenguaje C, y los predecesores de los programadores de C. Assembler están acostumbrados a pensar en punteros, por lo que habría sido una sorpresa si no hubiera usado estos poderosos mecanismos conocidos. Cualquier otra cosa habría estado demasiado lejos para 1978 o incluso para la década de 1960.
JensG
12

¿Por qué? Puede escribir un sistema enorme con el diseñador de formularios y el generador de código. ¿No es suficiente? (ironía)

Y ahora en serio, los punteros no son una parte crucial de la programación en muchas áreas, pero permiten a las personas comprender cómo funcionan los elementos internos. Y si no tenemos a nadie que entienda cómo funcionan las partes internas, habrá una situación en la que SQL2020, Windows 15 y Linux 20.04 se escribirán en una máquina virtual recolectada de basura que ejecuta más de 30 capas de abstracción, con código generado a través de IDE, en JavaScript .

Esto definitivamente no es lo que quiero ver.

Entonces sí, definitivamente tienen que hacerlo.

Descifrador
fuente
2
¡Buen humor! +1 y totalmente de acuerdo.
heltonbiker
7

Ni Java ni C # eliminaron punteros, tienen referencias que son casi las mismas. Lo que se eliminó es la aritmética de puntero, que se puede omitir en un curso introductorio.
No se podría realizar una aplicación no trivial sin el concepto de punteros o referencias, por lo que vale la pena enseñar (No se podría hacer una asignación dinámica de memoria sin ellos).

Considere lo siguiente en C ++ y Java, y supongo que no es muy diferente en C #:
aClass *x = new aClass();
aClass x = new aClass();
Realmente no hay demasiada diferencia entre punteros y referencias, ¿verdad?
La aritmética del puntero debe evitarse a menos que sea necesario y cuando se programe con modelos de alto nivel, por lo que no hay muchos problemas allí.

Petruza
fuente
6

El programador profesional debe dominar los punteros.

Las personas que desean conocer la programación deben aprender sobre su existencia e implicaciones, pero no necesariamente usarlas.

Las personas que desean resolver problemas personales a través de la programación (como yo, que usa muchos scripts de Python) podrían ignorarlos.

Bueno, esa es mi opinión ...; o)

heltonbiker
fuente
3

Los punteros de dirección variable son un caso específico del concepto más generalizado de indirección. La indirecta se usa en la mayoría de los lenguajes modernos (¿todos?) En muchos constructos, como delegados y devoluciones de llamada. Comprender el concepto de indirección le permite saber cuándo y cómo utilizar mejor estas herramientas.

Dave Nay
fuente
3

Absufreakinglutely ! Todos los que programan deben comprender los punteros y la indirección.

Los punteros son cómo se realiza una gran cantidad de acceso a datos en todos los idiomas. Los punteros son una característica de hardware de todos los microprocesadores. Los lenguajes de alto nivel como Java, VB & C # esencialmente bloquean el acceso directo a los punteros de los usuarios del lenguaje con referencias. Las referencias se refieren a objetos a través del esquema de gestión de memoria del lenguaje (podría ser un puntero con metadatos o simplemente un número para una tabla de memoria, por ejemplo).

Comprender cómo funcionan los punteros es fundamental para comprender cómo funcionan realmente las computadoras. Los punteros también son más flexibles y potentes que las referencias.

Por ejemplo, la razón por la cual las matrices comienzan en el índice cero es porque las matrices son en realidad una forma abreviada de aritmética de puntero. Sin aprender cómo funcionan los punteros, muchos programadores principiantes no obtienen matrices.

int a, foo[10];
foo[2] = a;

La línea 2 en la aritmética del puntero sería:

*(foo + sizeof(int) * 2) = a;

¡Sin comprender los punteros, uno no puede entender la administración de memoria, la pila, el montón o incluso las matrices! Además, uno debe comprender los punteros y la desreferenciación para comprender cómo se pasan las funciones y los objetos.

TL: DR : Comprender los punteros es fundamental para entender que las computadoras realmente funcionan .

CyberSkull
fuente
2

Creo que todo se reduce al hecho de que la necesidad de lidiar con los punteros disminuyó a medida que los programadores lidiaron menos con el hardware directo en el que se estaban ejecutando. Por ejemplo, asignar una estructura de datos de lista vinculada de una manera que se ajuste perfectamente a la secuencia de módulos de memoria de 640 bytes que tenía el hardware especializado.

Tratar con punteros manualmente puede ser propenso a errores (lo que lleva a pérdidas de memoria y código explotable) y lleva mucho tiempo hacerlo bien. Entonces, Java y C #, etc. ahora administran su memoria y sus punteros a través de sus máquinas virtuales (VM). Esto podría decirse que es menos eficiente que usar C / C ++ sin formato, aunque las máquinas virtuales están mejorando constantemente.

C (y C ++) siguen siendo lenguajes ampliamente utilizados, especialmente en los espacios de computación de alto rendimiento, juegos y hardware integrado. Estoy personalmente agradecido de haber aprendido acerca de los punteros ya que la transición a las referencias de Java (un concepto similar a los punteros) fue muy fácil y no me perdí cuando vi mi primera NullPointerException (que realmente debería llamarse NullReferenceException, pero estoy divagando) .

Aconsejaría aprender sobre el concepto de punteros, ya que todavía sustentan muchas estructuras de datos, etc. Luego, elija un idioma en el que le encanta trabajar, sabiendo que si surge algo como un NPE, ya sabe lo que realmente está sucediendo. .

Martijn Verburg
fuente
0

Esta es la verdad objetiva:

Algunos idiomas admiten acceso directo a memoria (punteros), otros no. Hay buenas razones para cada caso.

  1. Como alguien dijo aquí, en los días de C, la administración automática de memoria no era tan elaborada como lo es hoy. Y la gente ya estaba acostumbrada, de todos modos. Los buenos programadores en ese entonces tenían una comprensión mucho más profunda de los programas de computadora que de nuestra generación (tengo 21 años). Han estado usando tarjetas perforadas y días de espera durante algún tiempo de compilación en el mainframe. Probablemente sabían por qué existía cada parte de su código.

  2. La ventaja obvia de lenguajes como C es que le permiten tener un control más fino sobre su programa. ¿Cuándo lo necesitas en estos días? Solo cuando crea aplicaciones de infraestructura, como programas relacionados con el sistema operativo y entornos de tiempo de ejecución. Si solo desea desarrollar un software bueno, rápido, robusto y confiable, la administración de memoria automática es su mejor opción.

  3. El hecho es que el acceso directo a la memoria se ha abusado principalmente en el transcurso del historial de desarrollo de software. La gente había estado creando programas que perdían memoria, y en realidad eran más lentos debido a la asignación de memoria redundante (en C es fácil y común extender el espacio de memoria virtual del proceso para cada asignación individual).

  4. En estos días, las máquinas virtuales / tiempos de ejecución hacen un trabajo mucho mejor que el 99% de los programadores para asignar y liberar memoria. Además de eso, le permiten una flexibilidad adicional en el flujo que desea que tenga su programa, porque (en su mayoría) no está ocupado liberando memoria asignada en el momento y lugar correctos.

  5. En cuanto al conocimiento. Creo que es admirable que los programadores sepan cómo se implementan los entornos en los que programan. No necesariamente a los detalles más pequeños, sino al panorama general.

Creo que saber cómo funcionan los punteros (como mínimo) es interesante. Lo mismo que saber cómo se implementa el polimorfismo. De dónde obtiene su proceso su memoria y cómo. Estas son cosas que siempre me han interesado personalmente. Honestamente puedo decir que me han convertido en un mejor programador, pero no puedo decir que sean una necesidad educativa para cualquiera que quiera convertirse en un buen programador. En cualquier caso, saber más a menudo te hará mejor en tu trabajo.

  1. A mi modo de ver, si todo lo que se le pide es crear una aplicación en Java o C # o algo así, entonces debe centrarse en las técnicas de diseño e implementación adecuadas. Código comprobable, código limpio, código flexible. En ese orden.

Porque incluso si no conoce todos los pequeños detalles, alguien que lo haga podrá cambiar lo que haya creado en algo que simplemente funcione mejor. Y eso a menudo no es un trabajo difícil, una vez que tiene un diseño adecuado, limpio y comprobable (y eso suele ser la mayor parte del trabajo).

Si fuera un entrevistador que buscara contratar a alguien para una aplicación de lenguaje de alto nivel, esas serían las cosas que más me interesarían.

El conocimiento de bajo nivel es una ventaja. Es bueno para depurar y ocasionalmente crear soluciones ligeramente mejores. Te hace una persona interesante, profesionalmente. Le otorga algo de respeto en su lugar de trabajo.

Pero en el mundo de hoy, no es un requisito sagrado.

Yam Marcovic
fuente
-1

Para la mayoría de los propósitos prácticos en idiomas OO de alto nivel, la comprensión de referencias es suficiente, realmente no necesita comprender cómo estos idiomas implementan referencias en términos de punteros.

Hay muchos enfoques multi-paradigmáticos más funcionales y modernos que valoraría mucho más que poder hacer una aritmética de puntero elegante para decir, escribir la función de copia de cadena optimizada número 1000 que probablemente tenga un rendimiento peor que String.copy de su biblioteca estándar de ninguna manera.

Aconsejaría aprender primero conceptos mucho más diferentes y de mayor nivel, y diversificarse para aprender idiomas de diferentes diseños para ampliar su horizonte antes de intentar especializarse en cosas cercanas al hardware.

A menudo veo intentos totalmente fallidos de micro-optimizar el servlet web o código similar para obtener un 5% de ganancia, cuando el almacenamiento en caché (memorización), la optimización de SQL o solo el ajuste de la configuración del servidor web puede producir el 100% o más con poco esfuerzo. Jugar con punteros es una optimización prematura en la mayoría de los casos.

Jürgen Strobel
fuente
-1

Definitivamente, necesitamos tener un concepto completo de puntero, si realmente quieres ser un buen programador. La razón del concepto de puntero fue un acceso directo a su valor que se vuelve más eficiente y efectivo con limitaciones de tiempo ...

Además, hoy en día, considerando las aplicaciones móviles, que tienen una memoria muy limitada, necesitamos usarla con mucho cuidado para que su operación sea muy rápida con la respuesta del usuario ... Entonces, para este propósito, necesitamos una referencia directa al valor ...

Considere los dispositivos de Apple, o el lenguaje Objective C, que funciona totalmente solo con el concepto de puntero. Toda la variable declarada en el objetivo C tiene puntero. Necesitas pasar por la wiki del Objetivo C

DShah
fuente
Las aplicaciones móviles de hoy tienen más memoria disponible que algunos centros de datos en los que C fue concebido. Muchas aplicaciones móviles están escritas en Java, o directamente html + javascript, todas sin punteros (tienen REFERENCIAS). Solo una pequeña fracción de programadores muy especializados puede ver las capas subyacentes del sistema operativo.
Jürgen Strobel