問題文にある解き方の説明が理解されていないようなので
例を挙げて解説します。
この問題は, n重のfor文を書くことができれば簡単に解決できるのだが,
nが可変なため,n重のfor文ということはあり得ない。
n が 3 の場合、次のように 3重の for文で簡単に解決できます。
コード:
#include <stdio.h>
int main(void)
{
int n = 3, a[8];
for (a[0] = 1; a[0] <= n; a[0]++)
for (a[1] = 1; a[1] <= n; a[1]++)
for (a[2] = 1; a[2] <= n; a[2]++)
for (int i = 0; i < n; i++)
printf("%d%c", a[i], i == n-1 ? '\n' : ' ');
}
n が 4 になると、a[3] の for文を追加しなければなりません。
実行中に決まる n に従ってコードを実行時に変更することはできません。
(できる言語(Lispなど?)もありますが)
そこで再帰呼び出しの出番である。再帰関数には,
左から何番目の数を担当するかを表す引数を渡す。
コード:
#include <stdio.h>
int n, a[8];
void func(int i)
{
if (i < n)
for (a[i] = 1; a[i] <= n; a[i]++)
func(i + 1);
else
for (i = 0; i < n; i++)
printf("%d%c", a[i], i < n-1 ? ' ' : '\n');
}
int main(void)
{
n = 3;
func(0);
}
このコードは次の説明にも合致します。
関数の中で値を生成する部分にはfor文を一つだけ書いて
(プリント用にもう一つfor文が必要),
担当する位置に置いてある数を順に変えていく。
そして,このfor文の中で再帰呼び出しをすることがポイントである。
再帰呼び出しがn段になれば,n重のfor文と同じことになる。
for文で決めた数をすぐに出力することはできないので,
出力1行分の値を保存する配列が必要である。
大域的に(関数の外で)宣言すること。
この配列の添字には,再帰関数の引数を使う。
再帰の途中ではプリントしない。
再帰せずにreturnする時に1行文をプリントする。