您可以通过构造一些数据来充当迭代器并将其视为被迭代的单个事物来实现此目的。该数据将为您希望迭代的每个维度包含一个单独的计数器,并且它将由自身迭代每个维度的函数进行初始化、测试和递增。这是一个使用简单数组作为计数器的示例。
#include <string.h>
// Initialize counters to their start values.
static void InitializeCounters(long N, long *Counters, const long *Starts)
{
memcpy(Counters, Starts, N * sizeof *Counters);
}
// Return 1 if there are more values to iterate, 0 otherwise.
static int MoreToIterate(long N, long *Counters, const long *Ends)
{
return Counters[0] < Ends[0];
}
// Increment the counters, lexicographic (dictionary/odometer) style.
static void IncrementCounters(long N, long *Counters, const long *Starts,
const long *Ends)
{
/* Increment each dimension (except the first will be special). If it
rolls over its end, reset it to its start and go on the next dimension.
If it does not roll over, stop there.
*/
for (long i = N-1; 0 < i; --i)
if (++Counters[i] < Ends[i])
return;
else
Counters[i] = Starts[i];
/* For dimension zero, do not reset it, so MoreToIterate can see it
finished.
*/
++Counters[0];
}
#include <stdio.h>
#include <stdlib.h>
static void _Noreturn Usage(char *argv[])
{
fprintf(stderr, "Usage: %s <N>\n", argv[0]);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
if (argc != 2)
Usage(argv);
char *end;
long N = strtol(argv[1], &end, 0);
if (*end != '\0')
Usage(argv);
if (N < 0)
Usage(argv);
long *Counters = malloc(N * sizeof *Counters);
long *Starts = malloc(N * sizeof *Starts);
long *Ends = malloc(N * sizeof *Ends);
if (!Counters || !Starts || !Ends)
{
fprintf(stderr, "Error, unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
// Initialize start and end values as desired.
for (long i = 0; i < N; ++i)
{
Starts[i] = 0;
Ends[i] = i+1;
}
for ( InitializeCounters(N, Counters, Starts);
MoreToIterate(N, Counters, Ends);
IncrementCounters(N, Counters, Starts, Ends))
{
for (long i = 0; i < N; ++i)
printf("%ld ", Counters[i]);
printf("\n");
}
free(Ends);
free(Starts);
free(Counters);
}
使用参数“3”执行时的示例输出为:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2