使用预处理程序指令在C中定义泛型函数

时间:2012-10-12 16:35:46

标签: c function generics c-preprocessor preprocessor-directive

我刚从C#来到C,并且正在寻找一种方法来定义C#中的泛型函数。我遇到了this post,但是当我尝试编译它时,我得到了一堆错误(“n'未声明(不在函数中)”,“array”之前的语法错误“等等) 这是我的代码:

#include<conio.h>
#include<stdlib.h>

#define MAKE_PRINTEACH(TYPE)\
void printeach_##TYPE (TYPE[n] array, int n, void(*f)(TYPE)){\
  int i;\
  for(i = 0; i < n; i++) {\
    f(array[i]);\
  }\
}

MAKE_PRINTEACH(int)
MAKE_PRINTEACH(float)

void printInt(int x)
{
     printf("got %d\n",x);
}

void printFloat(float x)
{
     printf("got %f\n",x);
}

int main()
{
    int[5] ia = {34,61,3,6,76};
    float[6] fa = {2.4,0.5,55.2,22.0,6.76,3.14159265};

    printeach_int(ia, 5, printInt);
    printeach_float(fa,6,printFloat);

    getch();
}

我在这里做错了什么? 如果有所作为,我正在使用DevC ++。

2 个答案:

答案 0 :(得分:2)

正确的版本看起来像这样

#define MAKE_PRINTEACH(TYPE)                                     \
void printeach_##TYPE (size_t n, TYPE array[n], void(*f)(TYPE)){ \
  for(size_t i = 0; i < n; i++) {                                \
    f(array[i]);                                                 \
  }                                                              \
}

总结您的版本出了什么问题:

  • n必须在使用之前声明
  • 数组边界位于标识符
  • 之后
  • 数组大小的语义正确类型,例如size_t
  • C,因为C99还有for循环的局部变量。

答案 1 :(得分:0)

你可以尝试这种变化:

#define MAKE_PRINTEACH(TYPE)\
void printeach_##TYPE (TYPE * array, int n, void(*f)(TYPE)){\
  int i;\
  for(i = 0; i < n; i++) {\
    f(array[i]);\
  }\
}

TYPE[n] array意味着编译器支持VLA(可变长度数组),我不知道你的编译器是否支持。

<击>

对于gcc,添加命令行选项-std=c99会使原始代码编译。

<强>更新 通过Jens的评论应用更正。

我建议的解决方案是简单地将指针传递给数组的变量(如OP中提出的那样)。这样做是将数组传递给函数的方式。它们通过引用传递。

此外,Jens还提到了其他一些警告/错误。正如:

1 conio.h不是标准C包含,stdio.h适合此处

2通过将数组的大小添加到变量名称而不是类型来声明数组。它必须是:int ia[5]而不是int[5] ia

3 main()返回int,OP不会返回任何内容。

4 getch()的原型缺失。有人可能希望包含curses.h