2011-10-03 44 views
18

Con base en mi comprensión de puntero a puntero a un array de caracteres,puntero a puntero con argv

% ./pointer one two 

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

A partir del código:

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

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

mi entendimiento pasos:

  1. Take argv, eliminar la referencia.
  2. Debe devolver la dirección de la matriz de punteros a los caracteres.
  3. Usando aritmética de puntero para acceder a los elementos de la matriz.
+3

+1 para el diagrama. :) – Mysticial

Respuesta

14

Es más conveniente pensar en [] como operador de punteros en lugar de matrices; se usa con ambos, pero dado que las matrices decaen a indicadores, la indexación de matrices aún tiene sentido si se mira de esta manera. Entonces esencialmente compensa, luego desreferencia, un puntero.

Así que con argv[1], lo que realmente tiene es *(argv + 1) expresado con una sintaxis más conveniente. Esto le da el segundo 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 elimina el resultado.

(*argv)[1] sería eliminar la referencia argv primero con * para conseguir el primer puntero a char, entonces compensado por que 1 * sizeof(char) bytes, a continuación, elimina referencias que para conseguir un char. Esto le da al segundo personaje en la primera cadena del grupo de cadenas apuntadas por argv, que obviamente no es lo mismo que argv[1].

Por lo tanto, piense en una variable de matriz indexada como un puntero operado por un operador "offset y luego referencia un puntero".

+0

Sí, tuve la confusión de por qué no necesitábamos eliminar el argumento argv, primero, pero resulta que olvidé que es igual a * (argv + n), donde n es el índice del índice. –

10

Debido argv es un puntero a puntero a char, se deduce 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 ningún problema.

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

4

La indexación de un puntero como una matriz implícitamente la desreferencia. p[0] es *p, p[1] es *(p + 1), etc.