Вот версия, которая работает, но теоретически недействительна (см. Ниже) C90 и C ++ 98:
#include <stdio.h>
static void print(int *arr, size_t s1, size_t s2)
{
size_t i, j;
printf("\n");
for(i = 0; i < s1; i++) {
for(j = 0; j < s2; j++) {
printf("%d, ", arr[i * s2 + j]);
}
}
printf("\n");
}
int main(void) {
int a[4][4] = {{0}};
print(a[0], 4, 4);
return 0;
}
Версия C ++ с использованием шаблонов (адаптировано из Ответ Notinlist ) может выглядеть следующим образом:
#include <iostream>
#include <cstring>
using namespace std;
template <size_t N, size_t M>
struct IntMatrix
{
int data[N][M];
IntMatrix() { memset(data, 0, sizeof data); }
};
template <size_t N, size_t M>
ostream& operator<<(ostream& out, const IntMatrix<N,M>& m)
{
out << "\n";
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
out << m.data[i][j] << ", ";
}
}
out << "\n";
return out;
}
int main()
{
IntMatrix<4,4> a;
cout << a;
return 0;
}
В качестве альтернативы, вы можете использовать вложенные контейнеры STL - т.е. vector< vector<int> >
- вместо простого массива.
С C99 вы можете сделать
static void print(size_t s1, size_t s2, int arr[s1][s2]) {
printf("\n");
for(size_t i = 0; i < s1; i++) {
for(size_t j = 0; j < s2; j++) {
printf("%d, ", arr[i][j]);
}
}
printf("\n");
}
и назовите его
print(4, 4, a);
Как указал в комментариях Роберт, первый фрагмент фактически содержит неопределенное поведение. Тем не менее, если предположить, что арифметика указателей всегда будет приводить к указателю, даже когда задействовано неопределенное поведение (и не разрушит ваш компьютер), возможен только один возможный результат из-за других ограничений в стандарте, т.е. стандарт оставляет что-то излишне неопределенное.
Насколько я могу сказать, подставив
print(a[0], 4, 4);
с
union m2f { int multi[4][4]; int flat[16]; } *foo = (union m2f *)&a;
print(foo->flat, 4, 4);
сделает его законным C.