Передача многомерного массива переменной величины

Я пытаюсь понять, что такое "лучшая практика" (или действительно любая практика) для передачи многомерного массива в функцию из c. Разумеется, это зависит от приложения, поэтому рассмотрим возможность записи функции для печати двумерного массива переменной величины. В частности, меня интересует, как написать функцию printArry(__, int a, int b) в следующем коде. Я опустил первый параметр, поскольку я не совсем уверен, что это должно быть.

void printArry(_____, int a, int b){
/* what goes here? */
}


int main(int argc, char** argv){

int a1=5;
int b1=6;
int a2=7;
int a2=8;

int arry1[a1][b1];
int arry2[a2][b2];

/* set values in arrays */

printArry(arry1, a1, b1);
printArry(arry2, a2, b2);

}

Ответ 1

Самый простой способ (для C99 и позже)

void printArry(int a, int b, int arr[a][b]){
    /* what goes here? */
}

Но есть и другие способы

void printArry(int a, int b, int arr[][b]){
    /* what goes here? */
}

или же

void printArry(int a, int b, int (*arr)[b]){
    /* what goes here? */
}

Компилятор настроит первые два на третий синтаксис. Итак, семантически все три идентичны.

И немного сбивает с толку, который будет работать только как прототип функции:

void printArry(int a, int b, int arr[*][*]);

Ответ 2

На самом деле это не ответ, а расширенный комментарий к вопросу о комментариях OP. "Хорошо, вы можете передать массив, не зная количества строк с этим, но тогда как вы узнаете, когда прекратить печать строк?"

Ответ: как правило, вы не можете, не передавая размер массива тоже. Посмотрите на этот 1-D пример, который разбивает размер массива.

#include <stdio.h>

int procarr(int array[16], int index)
{
   return array[index];
}

int main (void)
{
    int arr[16] = {0};
    printf("%d\n", procarr(arr, 100));
    return 0;
}

Выход программы (хотя все элементы инициализированы до 0):

768

Это было поведение undefined, и не было предупреждения о компиляторе. C не обеспечивает защиту от переполнения массива, за исключением инициализаторов определения массива (хотя такие инициализаторы могут определять длину массива). Вы также должны передать размер массива, как в

#include <stdio.h>

int procarr(int array[16], size_t index, size_t size)
{
    if (index < size)
        return array[index];
    return -1;                  // or other action / flag
}

int main (void)
{
    int arr[16] = {0};
    printf("%d\n", procarr(arr, 100, sizeof arr / sizeof arr[0]));
    return 0;
}

Выход программы:

-1