C - 在可变函数中将多个函数地址作为参数传递
C - Pass multiple function addresses as parameters in a variadic function
我正在尝试编写一个函数,它将采用前 n 个整数和可变数量的函数,并构建一个 table,其第一列中的数字为 "i",并且 "function(i)"在其他人中。
但是我似乎无法将我的函数地址传递给 table 生成器,因为我遇到了访问冲突错误。我做错了什么?
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
typedef float(*f)(float);
// Some examples of f-type functions.
float square(float x) { return x*x; };
float root(float x) { return sqrt(x); };
float timesPi(float x) { return x * 3.14; };
// Display a table with first colon being the numbers from 1 to n,
// then the other columns to be f(i)
void table(unsigned int n, unsigned int nr_functions, ...)
{
va_list func;
va_start(func, nr_functions);
for (float i = 1; i <= n; i += 1)
{
printf("\n%6.0f |", i);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
// Main function
int main()
{
table(5, 3, &square, &root, ×Pi);
system("pause");
return 0;
}
对于上面的例子
table(5, 3, &square, &root, ×Pi);
我想回去
1 | 1.000 | 3.140 |
2 | 1.141 | 6.280 |
3 | 1.732 | 9.420 |
4 | 2.000 | 12.560 |
5 | 2.236 | 15.700 |
您需要重用参数列表的变量部分,这意味着您需要在正确的位置使用 va_start()
和 va_end()
— 在外循环内:
void table(unsigned int n, unsigned int nr_functions, ...)
{
for (unsigned int i = 1; i <= n; i++)
{
va_list func;
printf("\n%6.0f |", (double)i);
va_start(func, nr_functions);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
否则,除了在循环内调用 va_end()
之外,您将离开列表的末尾,导致天知道会造成什么损害。
请注意,循环应该使用整数运算——对 printf()
进行相应的更改——在这里我转换了值,但将格式更改为 %6d
也很合理(可能更好,事实上)。
使用这个函数,我得到了输出:
1 | 1.000 | 1.000 | 3.140 |
2 | 4.000 | 1.414 | 6.280 |
3 | 9.000 | 1.732 | 9.420 |
4 |16.000 | 2.000 |12.560 |
5 |25.000 | 2.236 |15.700 |
我正在尝试编写一个函数,它将采用前 n 个整数和可变数量的函数,并构建一个 table,其第一列中的数字为 "i",并且 "function(i)"在其他人中。
但是我似乎无法将我的函数地址传递给 table 生成器,因为我遇到了访问冲突错误。我做错了什么?
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
typedef float(*f)(float);
// Some examples of f-type functions.
float square(float x) { return x*x; };
float root(float x) { return sqrt(x); };
float timesPi(float x) { return x * 3.14; };
// Display a table with first colon being the numbers from 1 to n,
// then the other columns to be f(i)
void table(unsigned int n, unsigned int nr_functions, ...)
{
va_list func;
va_start(func, nr_functions);
for (float i = 1; i <= n; i += 1)
{
printf("\n%6.0f |", i);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
// Main function
int main()
{
table(5, 3, &square, &root, ×Pi);
system("pause");
return 0;
}
对于上面的例子
table(5, 3, &square, &root, ×Pi);
我想回去
1 | 1.000 | 3.140 |
2 | 1.141 | 6.280 |
3 | 1.732 | 9.420 |
4 | 2.000 | 12.560 |
5 | 2.236 | 15.700 |
您需要重用参数列表的变量部分,这意味着您需要在正确的位置使用 va_start()
和 va_end()
— 在外循环内:
void table(unsigned int n, unsigned int nr_functions, ...)
{
for (unsigned int i = 1; i <= n; i++)
{
va_list func;
printf("\n%6.0f |", (double)i);
va_start(func, nr_functions);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
否则,除了在循环内调用 va_end()
之外,您将离开列表的末尾,导致天知道会造成什么损害。
请注意,循环应该使用整数运算——对 printf()
进行相应的更改——在这里我转换了值,但将格式更改为 %6d
也很合理(可能更好,事实上)。
使用这个函数,我得到了输出:
1 | 1.000 | 1.000 | 3.140 |
2 | 4.000 | 1.414 | 6.280 |
3 | 9.000 | 1.732 | 9.420 |
4 |16.000 | 2.000 |12.560 |
5 |25.000 | 2.236 |15.700 |