vectores sirven que punteros para operadores matrices los lenguaje dobles direccion cadenas c++ pointers

c++ - sirven - punteros y matrices en c



¿Para qué sirve la indirección múltiple en C++? (8)

¿Bajo qué circunstancias podría desear usar direccionamiento indirecto múltiple (es decir, una cadena de punteros como en Foo ** ) en C ++?


Carl: Tu ejemplo debería ser:

*p = x;

(Tienes dos estrellas) :-)


El uso más común como @aku señaló es permitir que un cambio en un parámetro de puntero sea visible después de que la función regrese.

#include <iostream> using namespace std; struct Foo { int a; }; void CreateFoo(Foo** p) { *p = new Foo(); (*p)->a = 12; } int main(int argc, char* argv[]) { Foo* p = NULL; CreateFoo(&p); cout << p->a << endl; delete p; return 0; }

Esto se imprimirá

12

Pero hay varios otros usos útiles, como en el siguiente ejemplo, para iterar una matriz de cadenas e imprimirlas en el resultado estándar.

#include <iostream> using namespace std; int main(int argc, char* argv[]) { const char* words[] = { "first", "second", NULL }; for (const char** p = words; *p != NULL; ++p) { cout << *p << endl; } return 0; }


El uso más común de IMO es pasar referencia a variable de puntero

void test(int ** var) { ... } int *foo = ... test(&foo);

Puede crear una matriz dentada multidimensional utilizando dos punteros:

int ** array = new *int[2]; array[0] = new int[2]; array[1] = new int[3];


En C, la expresión idiomática es absolutamente necesaria. Considere el problema en el que desea que una función agregue una cadena (C pura, por lo tanto, una char *) a una matriz de punteros a char *. El prototipo de función requiere tres niveles de direccionamiento indirecto:

int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);

Lo llamamos de la siguiente manera:

unsigned int the_count = 0; char **the_list = NULL; AddStringToList(&the_count, &the_list, "The string I''m adding");

En C ++ tenemos la opción de usar referencias en su lugar, lo que produciría una firma diferente. Pero aún necesitamos los dos niveles de direccionamiento indirecto que solicitó en su pregunta original:

int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);


Si pasa un puntero como parámetro de salida, es posible que desee pasarlo como Foo** y establecer su valor como *ppFoo = pSomeOtherFoo .

Y desde el departamento de algoritmos y estructuras de datos, puede usar ese doble direccionamiento indirecto para actualizar los punteros, que puede ser más rápido que, por ejemplo, intercambiando objetos reales.


Un ejemplo simple sería usar int** foo_mat como una matriz 2d de enteros. O también puede usar punteros a punteros, digamos que tiene un puntero void* foo y tiene 2 objetos diferentes que tienen una referencia con los siguientes miembros: void** foo_pointer1 y void** foo_pointer2 , al tener un puntero a un puntero, puedes verificar si *foo_pointer1 == NULL que indica que foo es NULL. No podría verificar si foo es NULL si foo_pointer1 fuera un puntero regular. Espero que mi explicación no haya sido demasiado desordenada :)


Un escenario común es cuando necesita pasar un puntero nulo a una función y hacer que se inicialice dentro de esa función y se use fuera de la función. Sin indirección de multiplicidad, la función de llamada nunca tendría acceso al objeto inicializado.

Considere la siguiente función:

initialize(foo* my_foo) { my_foo = new Foo(); }

Cualquier función que llame ''initialize (foo *)'' no tendrá acceso a la instancia inicializada de Foo , ya que el puntero que se pasa a esta función es una copia. (El puntero es solo un entero después de todo, y los enteros se pasan por valor).

Sin embargo, si la función se definió así:

initialize(foo** my_foo) { *my_foo = new Foo(); }

... y se llamó así ...

Foo* my_foo; initialize(&my_foo);

... entonces la persona que llama tendría acceso a la instancia inicializada, a través de ''mi_foo'', porque es la dirección del puntero que se pasó a ''inicializar''.

Por supuesto, en mi ejemplo simplificado, la función ''inicializar'' podría simplemente devolver la instancia recién creada a través de la palabra clave return, pero eso no siempre se adapta, tal vez la función necesite devolver algo más.


Por lo general, cuando pasa un puntero a una función como valor de retorno:

ErrorCode AllocateObject (void **object);

donde la función devuelve un código de error de éxito / falla y rellena el parámetro del objeto con un puntero al nuevo objeto:

*object = new Object;

Esto se usa mucho en la programación COM en Win32.

Esto es más una cosa de C que hacer, en C ++ a menudo puedes incluir este tipo de sistema en una clase para hacer que el código sea más legible.