创建一个接受不同数据类型参数的C函数

我对C编程语言比较陌生,我正在试图弄清楚如何创建一个可以接受不同类型数据作为参数的函数。 该函数应该计算并返回字符或整数数组中的元素数。 我已经有两个单独的函数可以做到这一点,但我真的希望能够为这两个任务使用一个函数。 有没有办法在C中这样做?

提前致谢!

C中没有标准函数重载(也没有模板),但你可能会看到“类似printf”的函数(或可变函数 ),也许它们可以做你需要的。 如果他们允许灵活的参数列表。

这里有一个示例,它采用可变大小的整数数组。

也许你可以有一个函数签名,例如void iterate(const char* format, ...); 您通过以下方式使用:

 iterate("char", some_char_array); // for char arrays/strings 

要么

 iterate("int", some_int_array); // for integer arrays 

Aniket虽然提出了一个很好的观点,但你如何计算整数数组中的元素? 如果你传递一个int数组作为参数,你需要传递大小,这会破坏计算数组中元素的目的(正如你已经知道的那样,即大小)。

我假设你不知道大小但是你在数组中有一个终结符值(例如-1)。

考虑到上述假设,我已经快速入侵了一些你所需要的东西。

 #include  #include  #include  int iterate(const char* format, ...) { va_list ap; va_start(ap, format); if (strcmp(format, "char") == 0) { char* array = va_arg(ap, char*); return strlen(array); } else if (strcmp(format, "int") == 0) { int j = -1; int* int_array = va_arg(ap, int*); while (int_array[++j] != -1) ; return j; } return 0; } int main() { printf("%d\n", iterate("char", "abcdef")); int arr[] = {5, 4, 3, 2, 1, 0, -1}; printf("%d\n", iterate("int", arr)); return 0; } 

这打印:

 $ ./a.out 6 6 

在任何一种情况下,您都需要某种类型推理系统来告诉C编译器调用哪个函数。 这意味着,您需要事先了解您可能作为参数发送到您的“超级function”的数组类型。

C中没有“自动类型推理”,可以让您在运行时反映数据类型。 更好的是,您可能必须编写自己的运行时环境才能实现此目的。

这是一个有点琐碎的hackish方式:

 #include  size_t GetLengthOfArray(size_t sizeOfOneElementInArray, size_t sizeOfTheArrayInBytes) { return sizeOfTheArrayInBytes/sizeOfOneElementInArray; } int main(int argc, char *argv[]) { char cArr[10] = {'A','B','C','D','E','F','G','H','I','J'}; int iArr[5] = {10,20,30,40,50}; printf("%d is the length of cArr\n%d is the length of iArr",GetLengthOfArray(sizeof(cArr[0]),sizeof(cArr)), GetLengthOfArray(sizeof(iArr[0]),sizeof(iArr))); return 0; } 

所以,我们假设你的两个函数叫做sizeof_char_arraysizeof_int_array

在C11中,有一个名为“generics选择”的新function,它可以让你用一个相对简单的宏做你想做的事情:

 #define sizeof_array(X) \ _Generic (*(X), \ char: sizeof_char_array, \ default: sizeof_int_array) (X) 

(我甚至没有C11实现来测试这个,所以需要注意!)

在C11之前,有时使用常规命名函数的宏来完成。 您可以根据宏参数提示定义一个将调用一个函数或另一个函数的宏:

 #define sizeof_array(xtype, x) sizeof_ ## xtype ##_array(x) int a[] = { 1, 2, 3, 4, -1 }; char b[] = "abc"; sizeof_array(int, a); /* macro expands to sizeof_int_array(a) */ sizeof_array(char, b); /* macro expands to sizeof_char_array(b) */ 

如果输入参数确实是一个数组,则可以使用宏直接计算其大小:

 #define ARRAY_SZ(x) (sizeof(x)/((void *)x == &x ? sizeof(x[0]) : 0)) 

对于数组,以下表达式为true:

 (void *)arr == &arr 

因为数组的地址在内存中的位置与其第一个元素的地址相同。

因此,宏计算: sizeof(arr)/sizeof(arr[0]) 。 由于sizeof运算符报告其参数的大小(以字节为单位),因此计算的表达式将导致数组中的元素数。 但是,如果您使用ARRAY_SZ来计算长度,则ARRAY_SZ宏将导致大小至少比搜索到的ARRAY_SZ遍历数组的长度大一个。

在参数不是数组的情况下,表达式导致除以0exception。

答案很简单。 您确实需要一个function来执行此任务。 试试这段代码

 #define len(array) sizeof(array)/sizeof(array[0]) 

就是这样。

你应该让你的函数参数采用void *类型。 这样,您可以传入不同类型的数据,并将其类型转换为您想要的数据。 但是,您需要注意,因为无法保证正确“猜测” void*指向的类型。