tutorialspoint significado punteros dogs array c++ pointers

significado - struct c++



C++: ¿Cuáles son los escenarios en los que el uso de punteros es una "buena idea"(TM)? (11)

Posible duplicado:
Usos comunes para los punteros?

Todavía estoy aprendiendo los conceptos básicos de C ++ pero ya sé lo suficiente como para hacer pequeños programas útiles.

Entiendo que el concepto de punteros y los ejemplos que veo en los tutoriales tienen sentido para mí. Sin embargo, en el nivel práctico, y como soy un (antiguo) desarrollador de PHP, todavía no estoy seguro de usarlos en mis programas.

De hecho, hasta ahora no he sentido la necesidad de usar ningún puntero. Tengo mis clases y funciones y parece que estoy funcionando perfectamente bien sin usar ningún puntero (y mucho menos punteros a punteros). Y no puedo evitar sentirme un poco orgulloso de mis pequeños programas.

Aún así, soy consciente de que me falta una de las características más importantes de C ++ , una de doble filo: los punteros y la administración de la memoria pueden crear estragos, bloqueos aparentemente aleatorios, errores difíciles de encontrar y agujeros de seguridad ... pero al mismo tiempo, Usados ​​adecuadamente, deben permitir una programación inteligente y eficiente .

Entonces: dime lo que me estoy perdiendo al no usar punteros.

¿Cuáles son los buenos escenarios donde el uso de punteros es una necesidad?
¿Qué te permiten hacer que no podrías hacer de otra manera?
¿De qué manera hacen que tus programas sean más eficientes?

¿Y qué hay de los punteros a los punteros?

[Editar: Todas las diversas respuestas son útiles. Un problema en SO es que no podemos "aceptar" más de una respuesta. A menudo me gustaría poder hacerlo. En realidad, son todas las respuestas combinadas que ayudan a comprender mejor el panorama completo. Gracias.]


En general, los punteros son útiles ya que pueden contener la dirección de una porción de memoria. Son especialmente útiles en algunos controladores de bajo nivel donde se utilizan de manera eficiente para operar en una pieza de byte a byte de memoria. Son la invención más poderosa que C ++ hereda de C.

En cuanto a puntero a puntero, aquí hay un ejemplo de "hola mundo" que muestra cómo usarlo.

#include <iostream> void main() { int i = 1; int j = 2; int *pInt = &i; // "pInt" points to "i" std::cout<<*pInt<<std::endl; // prints: 1 *pInt = 6; // modify i, i = 6 std::cout<<i<<std::endl; // prints: 6 int **ppInt = &pInt; // "ppInt" points to "pInt" std::cout<<**ppInt<<std::endl; // prints: 6 **ppInt = 8; // modify i, i = 8 std::cout<<i<<std::endl; // prints: 8 *ppInt = &j; // now pInt points to j *pInt = 10; // modify j, j = 10 std::cout<<j<<std::endl; // prints: 10 }

Como vemos, "pInt" es un puntero a entero que apunta a "i" al principio. Con él, puedes modificar "i". "ppInt" es un puntero a puntero que apunta a "pInt". Con él, puedes modificar "pInt", que es una dirección. Como resultado, "* ppInt = & j" hace que "pInt" apunte a "j" ahora. Así que tenemos todos los resultados anteriores.


Hay varios escenarios donde se requieren punteros:

  • Si está utilizando clases base abstractas con métodos virtuales. Puede mantener un std :: vector y recorrer todos estos objetos y llamar a un método virtual. Esto requiere punteros.
  • Puede pasar un puntero a un búfer a un método que se lee desde un archivo, etc.
  • Necesitas mucha memoria asignada en el montón.

Es bueno preocuparse por los problemas de memoria desde el principio. Entonces, si empiezas a usar punteros, también puedes echar un vistazo a los punteros inteligentes, como por ejemplo, boost''s shared_ptr.


Los punteros se utilizan comúnmente en C ++. Sentirse cómodo con ellos, lo ayudará a comprender una gama más amplia de códigos. Dicho esto, si puede evitarlos, es grandioso, sin embargo, a medida que sus programas se vuelven más complejos, es probable que los necesite, aunque solo sea para interactuar con otras bibliotecas.

  • Principalmente los punteros se usan para referirse a la memoria asignada dinámicamente (devuelta por new ).

  • Permiten a las funciones tomar argumentos que no pueden copiarse en la pila, ya sea porque son demasiado grandes o no pueden copiarse, como un objeto devuelto por una llamada del sistema. (Creo que también la alineación de la pila, puede ser un problema, pero demasiado confuso para estar seguro).

  • En la programación integrada, se utilizan para referirse a cosas como los registros de hardware, que requieren que el código escriba en una dirección muy específica en la memoria.

  • Los punteros también se utilizan para acceder a objetos a través de sus interfaces de clase base. Es decir, si tengo una clase B que se deriva de la clase A class B : public A {} . Esa es una instancia del objeto B al que se puede acceder como si fuera clase A proporcionando su dirección a un puntero a la clase A, es decir: A *a = &b_obj;

  • Es un lenguaje C usar punteros como iteradores en arrays. Esto todavía puede ser común en el código C ++ anterior, pero probablemente se considera un primo pobre de los objetos iteradores STL.

  • Si necesita interactuar con el código C, siempre tendrá que manejar los punteros que se utilizan para referirse a objetos asignados dinámicamente, ya que no hay referencias. Las cadenas C son solo punteros a una matriz de caracteres terminados por el carácter nulo ''/ 0''.

Una vez que se sienta cómodo con los punteros, los punteros a los punteros no parecerán tan terribles. El ejemplo más obvio es la lista de argumentos para main() . Esto normalmente se declara como char *argv[] , pero lo he visto declarado (legalmente creo) como char **argv .

La declaración es de estilo C, pero dice que tengo un conjunto de punteros a punteros a char. Lo que se interpreta como una matriz de tamaño arbitrario (el tamaño es llevado por argc) de cadenas de estilo C (matrices de caracteres terminadas por el carácter nul ''/ 0'').


Puede usarlos para listas enlazadas, árboles, etc. Son estructuras de datos muy importantes.


Si no ha sentido la necesidad de apuntadores, no pasaría mucho tiempo preocupándome por ellos hasta que surja una necesidad.

Dicho esto, una de las principales formas en que los punteros pueden contribuir a una programación más eficiente es evitar copias de datos reales. Por ejemplo, supongamos que estaba escribiendo una pila de red. Recibe un paquete de Ethernet para ser procesado. Sucede sucesivamente que los datos suben de la pila del controlador Ethernet "sin procesar" al controlador IP al controlador TCP, por ejemplo, al controlador HTTP a algo que procesa el HTML que contiene.

Si está haciendo una nueva copia de los contenidos para cada uno de ellos, terminará haciendo al menos cuatro copias de los datos antes de que realmente pueda renderizarlos.

El uso de punteros puede evitar mucho de eso: en lugar de copiar los datos en sí, simplemente se pasa un puntero a los datos. Cada capa sucesiva de la pila de red mira su propio encabezado y pasa un puntero a lo que considera la "carga útil" hasta la siguiente capa superior de la pila. La siguiente capa mira su propio encabezado, modifica el puntero para mostrar lo que considera la carga útil y lo pasa a la pila. En lugar de cuatro copias de los datos, las cuatro capas funcionan con una copia de los datos reales.


Solo quiero decir que rara vez uso punteros. Uso referencias y objetos stl (deque, list, map, etc).

Una buena idea es cuándo debe devolver un objeto donde la función de llamada debería liberarse o cuando no desea devolver por valor.

List<char*>* fileToList(char*filename) { //dont want to pass list by value ClassName* DataToMyClass(DbConnectionOrSomeType& data) { //alternatively you can do the below which doesnt require pointers void DataToMyClass(DbConnectionOrSomeType& data, ClassName& myClass) {

Esa es prácticamente la única situación que uso, pero no estoy pensando en eso. Además, si quiero una función para modificar una variable y no puedo usar el valor de retorno (digamos que necesito más de uno)

bool SetToFiveIfPositive(int**v) {


Un gran uso para los punteros es el tamaño dinámico de los arreglos. Cuando no sepa el tamaño de la matriz en el momento de la compilación, deberá asignarla en tiempo de ejecución.

int *array = new int[dynamicSize];

Si su solución a este problema es usar std::vector de la STL, ellos usan la asignación de memoria dinámica entre bambalinas.


Un puntero tiene un valor especial, NULL , que la referencia no. Yo uso punteros donde NULL es un valor válido y útil.


Utilizo punteros cuando quiero dar un acceso de clase a un objeto, sin darle la propiedad de ese objeto. Incluso entonces, puedo usar una referencia, a menos que necesite poder cambiar el objeto al que estoy accediendo y / o no necesito la opción de ningún objeto, en cuyo caso el puntero sería NULL.


Esta pregunta se ha hecho en SO antes . Mi respuesta desde allí:

Utilizo punteros una vez cada seis líneas en el código C ++ que escribo. De la parte superior de mi cabeza, estos son los usos más comunes:

  • Cuando necesito crear dinámicamente un objeto cuya duración exceda el alcance en el que se creó.
  • Cuando necesito asignar un objeto cuyo tamaño es desconocido en tiempo de compilación.
  • Cuando necesito transferir la propiedad de un objeto de una cosa a otra sin copiarlo realmente (como en una lista enlazada / montón / lo que sea de estructuras realmente grandes y caras)
  • Cuando necesito referirme al mismo objeto desde dos lugares diferentes.
  • Cuando necesito cortar una matriz sin copiarla.
  • Cuando necesito usar los intrínsecos del compilador para generar instrucciones específicas de la CPU, o solucionar situaciones en las que el compilador emita un código subóptimo o ingenuo.
  • Cuando necesito escribir directamente en una región específica de la memoria (porque tiene IO asignada en memoria).

What are good scenarios where using pointers is a must?
Entrevistas Implementar strcpy.

What do they allow you to do that you couldn''t do otherwise?
Uso de la jerarquía de herencia. Estructuras de datos como árboles binarios.

In which way to they make your programs more efficient?
Le dan más control al programador, para crear y eliminar recursos en tiempo de ejecución.

And what about pointers to pointers???
Una pregunta frecuente de la entrevista. ¿Cómo va a crear una matriz bidimensional en el montón.