A menudo me cuesta ver las ventajas de los punteros (a excepción de la programación de bajo nivel).
¿Por qué usar char * en lugar de String o char [] o qué ventajas aporta la aritmética de puntero?
Entonces, ¿cuáles son los pros y los casos de uso de punteros?
Respuestas:
Los punteros son necesarios para la ubicación dinámica de la memoria, muchas estructuras de datos y el manejo eficiente de grandes cantidades de datos. Sin punteros, tendría que asignar todos los datos del programa globalmente o en funciones o su equivalente, y no tendría ningún recurso si la cantidad de datos creciera más de lo que originalmente había permitido. Dudo en usar absolutos aquí, pero que yo sepa, todos los lenguajes de computadora modernos tienen punteros de una forma u otra.
En la mayoría de los lenguajes que usan punteros, hay ciertos tipos de referencias que son punteros, y tal vez ciertos tipos de referencias que no lo son, y no hay más diferencia de notación. Una
cons
celda Lisp es un par de punteros, aunque afixnum
no es un puntero. En Java, la variable utilizada para la instancia de una clase es un puntero, peroint
no lo es. La sintaxis del lenguaje no refleja eso.C es inusual porque los punteros son opcionales, explícitos y permiten la aritmética explícita de punteros. Es perfectamente posible escribir
struct foo bar; struct foo * baz;
, y una vez que haya asignado memoriabaz
, puede usar ambosbar
ybaz
representarstruct foo
s. Como los punteros son opcionales, es útil tener diferencias notacionales. (Es esencial en C ++ para los punteros inteligentes, tal como se indicaboost::shared_ptr<foo> bar;
,bar.reset()
tiene un significado ybar->reset()
es probable que tenga un gran uno diferente).(En realidad, los punteros explícitos a menudo se usaban en otros lenguajes cuando C se estaba desarrollando originalmente, como
^
en Pascal. C es un lenguaje más antiguo que la mayoría de uso común en la actualidad, y se nota).Uno de los objetivos de diseño de C era escribir Unix y, por lo tanto, necesitaba manejar ubicaciones de memoria de manera detallada. (C es en realidad uno de una familia de lenguajes de implementación de sistemas comunes cuando se diseñó, otro ejemplo es Cybol para computadoras Control Data. C es el que se convirtió en un gran éxito). Por lo tanto, es posible manipular los punteros C directamente, asignando direcciones de memoria y calculando nuevas. Esto también condujo a algunas decisiones de diseño en C. Las matrices C se basan en gran medida en la aritmética del puntero, y de hecho una matriz se desintegra en un puntero en muchas situaciones. El paso de variables a funciones C por referencia se realiza mediante puntero. No había una gran necesidad de matrices y variables de paso por referencia en la forma que tenían otros lenguajes contemporáneos, por lo que C no los obtuvo.
Entonces, la respuesta es que, en la mayoría de los idiomas hoy en día, usas punteros constantemente sin que se te recuerde el hecho. En C, y en menor medida en C ++, utiliza punteros para hacer cosas de bajo nivel o para lograr cosas de alto nivel para las que no hay una notación especial.
fuente
Estructuras de datos complejas. No puede construir algo como una lista vinculada o un árbol binario sin punteros.
No hay "pros" y "contras" de punteros. Son solo una herramienta, como un martillo.
fuente
Las referencias en C ++, Java y otros tipos de lenguajes son solo 'punteros seguros'. Y estas referencias se usan mucho en Java.
fuente
NULL
y no se pueden modificar después de crearlos.Casi cualquier programa de computadora necesita inspeccionar y cambiar los valores en la memoria (conocidos como espiar y meter, para aquellos de nosotros que tenemos la edad suficiente). Debe controlar dónde están esos valores en la memoria, de modo que el resultado sea predecible (y en ciertos casos, el orden es importante: cargar un código ejecutable es un ejemplo). Por lo tanto, debe tener un tipo de datos que represente una ubicación en la memoria. Incluso si su entorno de programación lo oculta bajo una abstracción, todavía está allí.
fuente
char*
es un mal ejemplo de punteros. Probablemente sea mejor usarstd::string
(o algún tipo mejor que maneje su especialidad unicode / ansi / multibyte) quechar*
. Para casi cualquier otro ejemplo de punteros (Employee*
,PurchaseOrder*
, ...), sin embargo, hay muchas ventajas:De hecho, los punteros son tan importantes que la mayoría de los idiomas que parecen no tenerlos en realidad solo los tienen. Los tipos de referencia en C # y Java son esencialmente punteros disfrazados de objetos sólidos.
Ahora, la manipulación del puntero (
p++
en un puntero, op += delta
) es una historia completamente diferente. Algunas personas piensan que es peligroso, algunas personas piensan que es genial. Pero eso está aún más lejos de tu pregunta.fuente
Los punteros pueden ser más rápidos y pueden generar menos gastos generales, tanto en estructuras de datos como en mantener baja la huella de ejecución del programa. (Tenga en cuenta la palabra 'puede').
En general, la regla es que si asignó un recurso, ya sea realizando su propia asignación o haciendo que algo lo haga en su nombre, entonces es su trabajo liberarlo cuando haya terminado.
La carga de hacer lo anterior es volver a colocar la responsabilidad en el desarrollador, en lugar de que el tiempo de ejecución lo haga. Esto tiene algunas ventajas más, ya que las cosas pueden durar más tiempo, cruzar fronteras o eliminarse en momentos más oportunos o no tener que cargar con el peso de un recolector de basura.
En casos exóticos, que generalmente incluyen excepciones y alcance, hay algunos casos extremos que requieren que uno sea un poco más cuidadoso si se evita el código que hace la limpieza. Siendo realistas, estos casos se pueden diseñar alrededor. Vivimos sin código administrado durante muchas décadas.
A menudo, lo que hace que los punteros sean "difíciles" es simplemente no entender lo que está sucediendo a nivel de hardware. No es más que indirección.
Los punteros le brindan mucho más acceso sin procesar, y esto puede ser muy útil, inteligente o necesario. Puede apuntar a cualquier lugar y tratarlo casi como cualquier cosa. Si usas tus poderes divinos para bien, es muy, muy bueno.
La desventaja generalmente es un desperdicio al olvidarse de liberar algo, o al liberarlo más de una vez, o al hacer referencia a algo después de su lanzamiento, o al volver a hacer referencia a algo cuando no está apuntando a ninguna parte. Estas cosas a menudo resultan en choques espectaculares, y para ser honesto, generalmente son indicativos de que tienes un problema lógico, en lugar de que los indicadores sean frágiles.
Si es un desarrollador sólido, el uso de punteros no debería ser más problemático que cualquier otra estructura de datos. Nuevamente, no es ciencia espacial, y la gente lo hizo durante décadas sin siquiera pestañear. Simplemente se enseña menos a fondo en estos días.
Dicho todo esto, a menos que necesite punteros, la conveniencia y los casos exóticos que proporciona una buena recolección de basura hace que trabajar en un entorno administrado sea mucho más agradable. Es genial poder tomar algo de memoria, usarlo y abandonarlo, sabiendo que en algún momento posterior, podría descartarse, si tiene sentido hacerlo. Eso es un poco menos de código por parte del codificador, a cambio de un tiempo de ejecución que levanta un poco más.
fuente
La mejor respuesta está incluida en la pregunta: los punteros son para programación de bajo nivel. De acuerdo, si estás usando C, no usar punteros es como programar con una mano atada a la espalda, pero la respuesta es usar un lenguaje de nivel superior.
fuente
Los punteros proporcionan una visibilidad en la máquina que se requiere para la programación más interesante. La mayoría de los idiomas modernos simplemente te ocultan los fragmentos arenosos.
fuente