En C, ¿qué significa una declaración de variable con dos asteriscos (**)?

5 minutos de lectura

En C ¿que significa una declaracion de variable con dos
scott davies

Estoy trabajando con C y estoy un poco oxidado. Estoy consciente de * tiene tres usos:

  1. Declarar un puntero.
  2. Desreferenciar un puntero.
  3. Multiplicación

Sin embargo, ¿qué significa cuando hay dos asteriscos (**) antes de una declaración de variable:

char **aPointer = ...

Gracias,

scott

1647572587 129 En C ¿que significa una declaracion de variable con dos
jacob relkin

declara un puntero a un char puntero.

El uso de dicho puntero sería hacer cosas como:

void setCharPointerToX(char ** character) {
   *character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
}
char *y;
setCharPointerToX(&y); //using the address-of (&) operator here
printf("%s", y); //x

Aquí hay otro ejemplo:

char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome

Uso de ** con matrices:

char** array = malloc(sizeof(*array) * 2); //2 elements

(*array) = "Hey"; //equivalent to array[0]
*(array + 1) = "There";  //array[1]

printf("%s", array[1]); //outputs There

los [] El operador en arreglos hace esencialmente aritmética de punteros en el puntero frontal, entonces, la forma array[1] se evaluaría de la siguiente manera:

array[1] == *(array + 1);

Esta es una de las razones por las que los índices de matriz comienzan desde 0porque:

array[0] == *(array + 0) == *(array);

  • ¡Gracias por su respuesta! ¿Cuál es el caso de uso para tener un puntero a un puntero?

    –Scott Davies

    30 de noviembre de 2010 a las 21:31

  • @Jacob: ¿es la sintaxis C válida? No estoy familiarizado con eso.

    –Scott Davies

    30 de noviembre de 2010 a las 21:38

  • A char ** también puede representar una lista de cadenas, por ejemplo argv o la lista de argumentos que pasas a execvp o similar.

    – Matt K.

    30 de noviembre de 2010 a las 21:49

  • @ Matt Esto es cierto. Debería agregar un ejemplo de eso allí.

    –Jacob Relkin

    30 de noviembre de 2010 a las 21:50

C y C++ permiten el uso de punteros que apuntan a punteros (digamos que cinco veces más rápido). Echa un vistazo al siguiente código:

char a;
char *b;
char **c;

a="Z";
b = &a; // read as "address of a"
c = &b; // read as "address of b"

La variable a tiene un personaje. La variable b apunta a una ubicación en la memoria que contiene un carácter. La variable c apunta a una ubicación en la memoria que contiene un puntero que apunta a una ubicación en la memoria que contiene un carácter.

Supongamos que la variable a almacena sus datos en la dirección 1000 (CUIDADO: las ubicaciones de memoria de ejemplo están totalmente inventadas). Supongamos que la variable b almacena sus datos en la dirección 2000, y que la variable c almacena sus datos en la dirección 3000. Teniendo en cuenta todo esto, tenemos el siguiente diseño de memoria:

MEMORY LOCATION 1000 (variable a): 'Z'
MEMORY LOCATION 2000 (variable b): 1000 <--- points to memory location 1000
MEMORY LOCATION 3000 (variable c): 2000 <--- points to memory location 2000

declara aPointer como un puntero a un puntero a char.

Las declaraciones en C se centran en los tipos de expresiones; el nombre común para esto es “declaración imita el uso”. Como un ejemplo simple, supongamos que tenemos un puntero a int llamado p y queremos acceder al valor entero al que apunta actualmente. Lo haríamos desreferencia el puntero con el unario * operador, así:

x = *p;

el tipo de expresión *p es intpor lo que la declaración de la variable puntero p es

int *p;

En este caso, aPointer es un puntero a un puntero a char; si queremos llegar al valor del carácter al que apunta actualmente, tendríamos que desreferenciarlo dos veces:

c = **aPointer;

Entonces, siguiendo la lógica anterior, la declaración de la variable de puntero aPointer es

char **aPointer;

porque el tipo de expresión **aPointer es char.

¿Por qué alguna vez tendrías un puntero a un puntero? Aparece en varios contextos:

  • Desea una función para modificar un valor de puntero; un ejemplo es el strtol función de biblioteca, cuyo prototipo (a partir de C99) es
    long strtol(const char * restrict str, char ** restrict ptr, int base);  
    

    El segundo argumento es un puntero a un puntero a char; cuando usted llama strtolpasa la dirección de un puntero a char como segundo argumento y, después de la llamada, apuntará al primer carácter de la cadena que no se convirtió.

  • Recuerde que, en la mayoría de los contextos, una expresión de tipo “arreglo de N elementos de T” se convierte implícitamente al tipo “puntero a T”, y su valor es la dirección del primer elemento del arreglo. Si “T” es “puntero a carácter”, entonces una expresión de tipo “matriz de elementos N de puntero a carácter” se convertirá en “puntero a puntero a carácter”. Por ejemplo:
    
        void foo(char **arr)
        {
          size_t i = 0;
          for (i = 0; arr[i] != NULL; i++)
            printf("%s\n", arr[i]);
        }
    
        void bar(void)
        {
          char *ptrs[N] = {"foo", "bar", "bletch", NULL};
          foo(ptrs); // ptrs decays from char *[N] to char **
        }
    
    

  • Desea asignar dinámicamente una matriz multidimensional:
    
    #define ROWS ...
    #define COLS ...
    ...
    char **arr = malloc(sizeof *arr * ROWS);
    if (arr)
    {
      size_t i;
      for (i = 0; i < ROWS; i++)
      {
        arr[i] = malloc(sizeof *arr[i] * COLS);
        if (arr[i])
        {
          size_t j;
          for (j = 0; j < COLS; j++)
          {
            arr[i][j] = ...;
          }
        }
      }
    }
    

Esto significa que aPointer apunta a un puntero char.

Entonces

aPointer: pointer to char pointer

*aPointer :pointer to char

**aPointer: char

Un ejemplo de su uso es crear una matriz dinámica de cadenas c

char **aPointer = (char**) malloc(num_strings);

aPointer te da un charque se puede utilizar para representar una cadena terminada en cero.

*aPointer = (char*)malloc( string_len + 1); //aPointer[0]
*(aPointer + 1) = (char*)malloc( string_len + 1); //aPointer[1]

Este es un puntero a un puntero a char.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad