Solución:
Como recién está aprendiendo C, le recomiendo que realmente intente comprender el diferencias entre matrices y punteros primero en lugar de la común cosas.
En el área de parámetros y matrices, hay algunas reglas confusas que deben aclararse antes de continuar. Primero, lo que declara en una lista de parámetros se trata de manera especial. Hay situaciones en las que las cosas no tienen sentido como parámetro de función en C.Estos son
- Funciones como parámetros
- Matrices como parámetros
Matrices como parámetros
El segundo tal vez no esté claro de inmediato. Pero queda claro cuando considera que el tamaño de una dimensión de matriz es parte del tipo en C (y una matriz cuyo tamaño de dimensión no se proporciona tiene un tipo incompleto). Entonces, si crea una función que toma un arreglo por valor (recibe una copia), ¡entonces podría hacerlo solo para un tamaño! Además, las matrices pueden volverse grandes y C intenta ser lo más rápido posible.
En C, por estas razones, valores de matriz no existen. Si desea obtener el valor de una matriz, lo que obtiene en su lugar es un puntero al primer elemento de esa matriz. Y aquí ya está la solución. En lugar de dibujar un parámetro de matriz no válido por adelantado, un compilador de C transformar el tipo del parámetro respectivo para ser un puntero. Recuerda esto, es muy importante. El parámetro no será una matriz, sino que será un puntero al tipo de elemento respectivo.
Ahora, si intenta pasar una matriz, lo que se pasa en su lugar es un puntero al primer elemento de la matriz.
Excursión: funciones como parámetros
Para completar, y porque creo que esto lo ayudará a comprender mejor el asunto, veamos cuál es el estado de las cosas cuando intenta tener una función como parámetro. De hecho, primero no tendrá ningún sentido. ¿Cómo puede un parámetro ser una función? ¡Eh, queremos una variable en ese lugar, por supuesto! Entonces, lo que hace el compilador cuando eso sucede es, nuevamente, transformar la función en un puntero de función. En su lugar, intentar pasar una función pasará un puntero a esa función respectiva. Entonces, lo siguiente es lo mismo (análogo al ejemplo de matriz):
void f(void g(void));
void f(void (*g)(void));
Tenga en cuenta que los paréntesis alrededor *g
es necesario. De lo contrario, especificaría una función que regresara void*
, en lugar de un puntero a una función que devuelve void
.
Volver a matrices
Ahora, dije al principio que las matrices pueden tener un tipo incompleto, lo que sucede si aún no le das un tamaño. Como ya pensamos que un parámetro de matriz no existe, sino que cualquier parámetro de matriz es un puntero, el tamaño de la matriz no importa. Eso significa que el compilador traducirá todo lo siguiente, y todos son lo mismo:
int main(int c, char **argv);
int main(int c, char *argv[]);
int main(int c, char *argv[1]);
int main(int c, char *argv[42]);
Por supuesto, no tiene mucho sentido poder ponerle cualquier tamaño, y simplemente se tira. Por esa razón, a C99 se le ocurrió un nuevo significado para esos números y permite que aparezcan otras cosas entre paréntesis:
// says: argv is a non-null pointer pointing to at least 5 char*'s
// allows CPU to pre-load some memory.
int main(int c, char *argv[static 5]);
// says: argv is a constant pointer pointing to a char*
int main(int c, char *argv[const]);
// says the same as the previous one
int main(int c, char ** const argv);
Las dos últimas líneas dicen que no podrá cambiar “argv” dentro de la función; se ha convertido en un puntero constante. Sin embargo, solo unos pocos compiladores de C admiten esas características de C99. Pero estas características dejan en claro que la “matriz” en realidad no es una. Es un puntero.
Una palabra de advertencia
Tenga en cuenta que todo lo que dije anteriormente es cierto solo cuando tiene una matriz como un parámetro de una función. Si trabaja con matrices locales, una matriz no será un puntero. Va a comportarse como un puntero, porque como se explicó anteriormente, una matriz se convertirá en un puntero cuando se lea su valor. Pero no debe confundirse con punteros.
Un ejemplo clásico es el siguiente:
char c[10];
char **c = &c; // does not work.
typedef char array[10];
array *pc = &c; // *does* work.
// same without typedef. Parens needed, because [...] has
// higher precedence than '*'. Analogous to the function example above.
char (*array)[10] = &c;
Podrías usar cualquiera de los dos. Son completamente equivalentes. Vea los comentarios de litb y su respuesta.
Realmente depende de cómo quieras usarlo (y podrías usar cualquiera de los dos en cualquier caso):
// echo-with-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char **argv)
{
while (--argc > 0)
{
printf("%s ", *++argv);
}
printf("n");
return 0;
}
// echo-without-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++)
{
printf("%s ", argv[i]);
}
printf("n");
return 0;
}
En cuanto a cuál es más común, no importa. Cualquier programador de C experimentado que lea su código verá ambos como intercambiables (en las condiciones adecuadas). Al igual que un hablante de inglés experimentado lee “they are” y “they are” con la misma facilidad.
Más importante es que aprenda a leerlos y reconozca cuán similares son. Leerá más código del que escribe y deberá sentirse igualmente cómodo con ambos.
Puede utilizar cualquiera de las dos formas, ya que en C las matrices y los punteros son intercambiables en las listas de parámetros de función. Consulte http://en.wikipedia.org/wiki/C_(programming_language)#Array-pointer_interchangeability.