#define ROWS 5 #define COLS 10 int multi[ROWS][COLS];permite acceder a los elementos del array multi mediante:
multi[row][col]o mediante:
*(*(multi + row) + col)Para entenderlo mejor, cambiemos
*(multi + row)por X como en:
*(X + col)Ahora vemos que X es como un puntero porque la expresión es desreferenciada y sabemos que col es un entero. Aquí estamos utilizando "aritmética de punteros", y al tratarse de un array de enteros, la dirección donde apunta (por ej. el valor de) X + col + 1 debe ser mayor que la dirección X + col por una diferencia de sizeof(int).
Ya sabemos como se guarda en memoria un array de dos dimensiones, y por tanto podemos determinar que en la expresión multi + row anterior, multi + row + 1 debe incrementarse por el valor necesario para "apuntar" a la siguiente línea, que en este caso es COLS * sizeof(int).
Esto quiere decir que para la evaluación correcta en tiempo de ejecución de la expresión *(*(multi + row) + col) el compilador debe generar el código teniendo en cuenta el valor de COLS (la segunda dimensión). Tanto la versión con punteros como la versión con arrays multi[row][col] son equivalentes.
Por tanto, para evaluar la expresión dada, se necesitan 5 valores:
void set_value(int m_array[][COLS]) { int row, col; for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) { m_array[row][col] = 1; } } }Y para llamar a esta función, podemos utilizar:
set_value(multi);Ahora, dentro de la función hemos utilizado los valores de ROWS y COLS definidos al principio con #define ROWS 5 y #define COLS 10 para establecer los límites de los bucles for. Para el compilador estas definiciones son constantes. Tanto row como col son variables locales. La definición formal de los parámetros permiten al compilador determinar las características del valor del puntero que será pasado en tiempo de ejecución. Realmente no necesitamos la primera dimensión, y como veremos después, hay momentos donde es preferible no definirlo dentro de la definición de parámetros (por hábito o por consistencia, yo no lo he utilizado aquí). Ahora, la segunda dimensión debe utilizarse como vemos en la expresión del parámetro. La razón es que lo necesitamos en la evaluación de m_array[row][col] como hemos visto. Como el parámetro define el tipo de dato (en este caso int), y las variables automáticas (row y col) se definen dentro de la función para los bucles for, con un único parámetro sólo puede pasarse un valor. En este caso, éste parámetro es el valor de multi como vemos en la llamada a la función, que es la dirección del primer elemento, a menudo también llamado como un puntero a un array. Por tanto, la única forma que tenemos de indicar la segunda dimensión al compilador es incluirlo explícitamente en la definición del parámetro.
De hecho, generalmente todas las dimensiones superiores a una son necesarias en arrays multidimensionales. Esto es: si hablamos de 3 dimensiones, la dimensión 2 y 3 deben especificarse en la definición de parámetros.