¿Cómo funcionan los punteros a punteros en C? (¿y cuándo podrías usarlos?)

Resuelto asked hace 15 años • 0 respuestas

¿Cómo funcionan los punteros a punteros en C?
¿Cuándo podrías usarlos?

 avatar May 22 '09 18:05
Aceptado

Supongamos una computadora de 8 bits con direcciones de 8 bits (y por lo tanto solo 256 bytes de memoria). Esto es parte de esa memoria (los números de arriba son las direcciones):

  54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    | 58 |    |    | 63 |    | 55 |    |    | h  | e  | l  | l  | o  | \0 |    |
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+

Lo que puede ver aquí es que en la dirección 63 comienza la cadena "hola". Entonces, en este caso, si esta es la única aparición de "hola" en la memoria, entonces,

const char *c = "hello";

... se define ccomo un puntero a la cadena (de solo lectura) "hola" y, por lo tanto, contiene el valor 63. cdebe almacenarse en algún lugar: en el ejemplo anterior, en la ubicación 58. Por supuesto, no solo podemos señalar caracteres , pero también a otros indicadores. P.ej:

const char **cp = &c;

Ahora cpapunta a c, es decir, contiene la dirección de c(que es 58). Podemos ir aún más lejos. Considerar:

const char ***cpp = &cp;

Ahora cppalmacena la dirección de cp. Entonces tiene el valor 55 (basado en el ejemplo anterior), y lo has adivinado: está almacenado en la dirección 60.


En cuanto a por qué uno usa punteros a punteros:

  • El nombre de una matriz normalmente produce la dirección de su primer elemento. Entonces, si la matriz contiene elementos de tipo t, una referencia a la matriz tiene tipo t *. Ahora considere una matriz de matrices de tipo t: naturalmente, una referencia a esta matriz 2D tendrá tipo (t *)*= t **y, por lo tanto, es un puntero a un puntero.
  • Aunque un conjunto de cadenas parezca unidimensional, en realidad es bidimensional, ya que las cadenas son conjuntos de caracteres. Por eso: char **.
  • Una función fnecesitará aceptar un argumento de tipo t **si va a alterar una variable de tipo t *.
  • Hay muchas otras razones que son demasiado numerosas para enumerarlas aquí.
Stephan202 avatar May 22 '2009 11:05 Stephan202

¿Cómo funcionan los punteros a punteros en C?

Primero, un puntero es una variable, como cualquier otra variable, pero que contiene la dirección de una variable.

Un puntero a un puntero es una variable, como cualquier otra variable, pero que contiene la dirección de una variable. Esa variable resulta ser un puntero.

¿Cuándo los usarías?

Puede usarlos cuando necesite devolver un puntero a alguna memoria en el montón, pero sin usar el valor de retorno.

Ejemplo:

int getValueOf5(int *p)
{
  *p = 5;
  return 1;//success
}

int get1024HeapMemory(int **p)
{
  *p = malloc(1024);
  if(*p == 0)
    return -1;//error
  else 
    return 0;//success
}

Y lo llamas así:

int x;
getValueOf5(&x);//I want to fill the int varaible, so I pass it's address in
//At this point x holds 5

int *p;    
get1024HeapMemory(&p);//I want to fill the int* variable, so I pass it's address in
//At this point p holds a memory address where 1024 bytes of memory is allocated on the heap

También hay otros usos, como que el argumento main() de cada programa C tiene un puntero a un puntero para argv, donde cada elemento contiene una matriz de caracteres que son las opciones de la línea de comando. Sin embargo, debe tener cuidado cuando use punteros de punteros para apuntar a matrices bidimensionales, es mejor usar un puntero a una matriz bidimensional.

¿Por qué es peligroso?

void test()
{
  double **a;
  int i1 = sizeof(a[0]);//i1 == 4 == sizeof(double*)

  double matrix[ROWS][COLUMNS];
  int i2 = sizeof(matrix[0]);//i2 == 240 == COLUMNS * sizeof(double)
}

A continuación se muestra un ejemplo de un puntero a una matriz bidimensional realizado correctamente:

int (*myPointerTo2DimArray)[ROWS][COLUMNS]

Sin embargo, no puede usar un puntero a una matriz bidimensional si desea admitir un número variable de elementos para las FILAS y COLUMNAS. Pero cuando sepa de antemano que usaría una matriz bidimensional.

Brian R. Bondy avatar May 22 '2009 11:05 Brian R. Bondy