用于替换嵌套for循环的宏

Ste*_*611 2 c macros c-preprocessor variadic-macros

我发现这个宏#define TIMES(x) for(int i1=0;i1<x;i1++)非常实用,可以缩短代码文本.但是当我有嵌套循环时,我不知道如何编写这样的宏,甚至我不知道是否可能.这个想法如下.是否可以编写此代码

for(int i1=0;i1<5;i1++)
    for(int i2=0;i2<3;i2++)
        for (int i3=0;i3<7;i3++)
        /* many nested `for` loops */
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)

TIMES(5) TIMES(3) TIMES(7) ....
{
    /* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)

用一种"递归"宏来检测所有TIMES并通过for循环替换它们与i1,i2,i3,... i'n'循环计数器?

Lun*_*din 6

这是非常糟糕的做法,不要这样做.其他C程序员完全了解for循环,但他们完全忘记了你的私有秘密宏语言.此外,类似功能的宏类型安全性较差,只能作为最后的手段使用.

正确的解决方案不是使用宏,而是使用函数.如果您希望使用正确的泛型编程,可以按如下方式编写:

typedef void callback_t (int data);

void traverse (size_t n, int data[n], callback_t* callback)
{
  for(size_t i=0; i<n; i++)
  {
    callback(data[i]);
  }
}
Run Code Online (Sandbox Code Playgroud)

callback调用者提供的函数指针在哪里,其中包含实际的功能.类似于宏中的循环体.

完整示例:

#include <stdio.h>

typedef void callback_t (int data);

void traverse (size_t n, int data[n], callback_t* callback)
{
  for(size_t i=0; i<n; i++)
  {
    callback(data[i]);
  }
}


void print (int i)
{
  printf("%d ", i);
}

int main (void)
{
  int array [5] = {1, 2, 3, 4, 5};

  traverse(5, array, print);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

在上面的例子中,数据类型是int.但由于它是通用编程,您可以进行一些调整并将其交换为任何其他数据类型,例如数组或结构.然后,catch必须通过指针将参数传递给回调,而不是按值传递.例:

#include <stdio.h>

/* Generally it is bad practice to hide arrays behind typedefs like this. 
   Here it just done for illustration of generic programming in C. */
typedef int data_t[3]; 

typedef void callback_t (data_t* data);

void traverse (size_t n, data_t data[n], callback_t* callback)
{
  for(size_t i=0; i<n; i++)
  {
    callback(&data[i]);
  }
}


void print_array (int(*array)[3])
{
  int* ptr = *array;
  printf("{%d %d %d}\n", ptr[0], ptr[1], ptr[2]);
}

int main (void)
{
  int array [2][3] = { {1, 2, 3}, {4, 5, 6} };

  traverse(2, array, print_array);
}
Run Code Online (Sandbox Code Playgroud)