Puntero a Puntero con argv

Basado en mi entendimiento de puntero a puntero a una matriz de caracteres,

% ./pointer one two argv +----+ +----+ | . | ---> | . | ---> "./pointer\0" +----+ +----+ | . | ---> "one\0" +----+ | . | ---> "two\0" +----+ 

Desde el código:

 int main(int argc, char **argv) { printf("Value of argv[1]: %s", argv[1]); } 

Mi pregunta es: ¿Por qué es aceptable argv [1]? ¿Por qué no es algo como (* argv) [1]?

Mis pasos de comprensión:

  1. Tome argv, desérelo.
  2. Debe devolver la dirección de la matriz de punteros a caracteres.
  3. Uso de aritmética de punteros para acceder a elementos de la matriz.

Es más conveniente pensar en [] como un operador de punteros en lugar de matrices; se usa con ambos, pero dado que los arreglos se descomponen a los punteros, la indexación de los arreglos aún tiene sentido si se ve de esta manera. Así que esencialmente compensa, a continuación, desreferencias, un puntero.

Así que con argv[1] , lo que realmente tienes es *(argv + 1) expresado con una syntax más conveniente. Esto le da la segunda char * en el bloque de memoria apuntado por argv , ya que char * es el tipo argv apunta a, y [1] compensa argv por sizeof(char *) bytes y luego hace referencia al resultado.

(*argv)[1] desreferiría argv primero con * para obtener el primer puntero a char , luego lo compensará con 1 * sizeof(char) bytes, luego dereferencias de que para obtener un char . Esto da el segundo carácter en la primera cadena del grupo de cadenas señaladas por argv , que obviamente no es lo mismo que argv[1] .

Así que piense en una variable de matriz indexada como un puntero que está siendo operado por un operador de “compensar y luego desreferenciar un puntero”

Debido a que argv es un puntero a puntero a char , se sigue que argv[1] es un puntero a char . El formato print() %s espera un puntero al argumento char e imprime la matriz de caracteres terminada en nulo a la que apunta el argumento. Como argv[1] no es un puntero nulo, no hay problema.

(*argv)[1] también es válido C, pero (*argv) es equivalente a argv[0] y es un puntero a char , por lo que (*argv)[1] es el segundo carácter de argv[0] , que es / en tu ejemplo.

Al indexar un puntero como una matriz, se hace una referencia explícita a él. p[0] es *p , p[1] es *(p + 1) , etc.