No se pueden usar calificadores de tipo static
en la porción de tamaño de la declaración de matriz en C89/90. Estas características son específicas de C99.
static
de declaración de matriz indica al compilador que prometes que el número especificado de elementos siempre estará presente en la matriz pasada como argumento real. Esto podría ayudar a los compiladores a generar un código más eficiente. Si infringe su promesa en el código real (es decir, pasa una matriz más pequeña), el comportamiento no está definido. Por ejemplo,
void foo(int a[static 3]) {
...
}
int main() {
int a[4], b[2];
foo(a); /* OK */
foo(b); /* Undefined behavior */
}
El *
en tamaño de la porción de declaración de matriz se usa en sólo declaraciones función prototipo.Indica que la matriz tiene una longitud variable (VLA). Por ejemplo, en la definición de función se puede utilizar un VLA con un tamaño concreto de tiempo de ejecución
void foo(int n, int a[n]) /* `a` is VLA because `n` is not a constant */
{
...
}
Cuando se declara el prototipo se puede hacer lo mismo
void foo(int n, int a[n]); /* `a` is VLA because `n` is not a constant */
pero si no se especifica los nombres de los parámetros (lo cual está bien en el prototipo), no puede usar n
como tamaño de matriz, por supuesto. Sin embargo, si usted todavía tiene que decirle al compilador que la matriz va a ser un VLA, se puede utilizar el *
para ese propósito
void foo(int, int a[*]); /* `a` is VLA because size is `*` */
Tenga en cuenta, que el ejemplo con una matriz 1D no es una buena idea. Incluso si se omite el *
y declara la función anterior como
void foo(int, int a[]);
entonces el código todavía no tendrán ningún problema, ya que en función de tipo de declaraciones de parámetros matriz está implícita sustituido por un tipo de puntero de todos modos. Pero una vez que comienzas a utilizar matrices multidimensionales, el uso adecuado de *
se vuelve importante. Por ejemplo, si la función se define como
void bar(int n, int m[n][n]) { /* 2D VLA */
...
}
el prototipo podría tener el siguiente
void bar(int n, int m[n][n]); /* 2D VLA */
o como
void bar(int, int m[*][*]); /* 2d VLA */
En este último caso, la primera *
se puede omitir (debido al reemplazo de matriz a puntero), pero no al segundo *
.
Supongo que el lugar donde esto realmente importa es cuando haces 'f (int, int, a [*] [*])' o algo por el estilo ... – dmckee
@dmckee: Estaba simplemente agregando eso a mi respuesta :) – AnT
Mucha gente pensando en las mismas líneas por aquí. Grandes mentes y todo eso ... – dmckee