Ответ Павла показывает, как выполнить рекурсию. Однако функция, которая принимает только два аргумента (число циклов и максимальное значение), не имеет достаточного контекста для фактической печати чисел, как в вашем примере. Для этого вам придется отслеживать некоторую дополнительную информацию. Одним из способов сделать это является следующее:
void _print_loop(int *values, int width, int cur_col, int max) {
if (cur_col == width) {
for (int i = 0; i < width; i++) {
printf("%d%c", values[i], (i < width - 1) ? ' ' : '\n');
}
} else {
for (int i = 0; i < max; i++) {
values[cur_col] = i;
_print_loop(values, width, cur_col + 1, max);
}
}
}
void print_loop(int width, int max) {
int values[width];
memset(values, 0, width * sizeof(int));
_print_loop(values, width, 0, max);
}
Теперь print_loop(3, 2)
ведет себя как ожидалось.
Edit: на самом деле, один может написать функцию с двумя аргументами, чтобы сделать это, используя static
переменные, которые инициализируются при получении положительного аргумента width
, После этой стадии инициализации функция выполняет свою рекурсию, используя отрицательные значения. Очевидно, что полученный код ужасен, но я все равно выложу его для полноты:
void print_loop(int width, int max) {
static int max_width;
static int *values;
if (width > 0) {
max_width = width;
if ((values = calloc(width, sizeof(int))) == NULL) {
perror("calloc");
exit(EXIT_FAILURE);
}
print_loop(-width, max);
free(values);
}
else if (width == 0) {
for (int i = 0; i < max_width; i++) {
printf("%d%c", values[i], (i < max_width - 1) ? ' ' : '\n');
}
}
else {
for (int i = 0; i < max; i++) {
values[-width - 1] = i;
print_loop(width + 1, max);
}
}
}