在 C 中,对 void* 变量进行数学运算的最有效方法是什么
In C, what is the most efficient way to do math on a void* variable
假设我有这样一个函数:
void myfunc(void* x, void* y){
for(i=0; i<n;i++)
y[i] = x[i]+1;
}
我的目标是获取向量 x
,做一些数学运算并将其存储在 y
中。在这种情况下,我知道 x
将作为 int
s.
的数组分配内存
我知道我们不能直接在 x
上做数学运算,因为它被转换为 void,但我很好奇绕过这个拦截器的最有效方法。我目前的方法是 memcpy
x 到 int*
温度,做我的数学,然后 memcpy
到 y
。显然,这不是一个具有多个 memcpy
的特别有效的过程。我确信有更好的方法,我只是对 C 内存分配规则了解不够,无法弄清楚。
如果您知道指针指向 int
的数组,您可以转换为该类型:
void myfunc(void* x, void* y){
int *a = x;
int *b = y;
for(i=0; i<n;i++)
b[i] = a[i]+1;
}
你可以避开memcpy
。如果您希望使用整数或字节或任何其他类型,则只需进行适当的转换,例如 x
和 y
引用 int
:[=19= 的数组]
void myfunc(void* x, void* y){
int *xp = x;
int *yp = y;
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
yp[i] = xp[i] + 1;
}
在这种情况下,您根本不需要将它们作为 void *
传递:
void myfunc(int* x, int* y){
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
y[i] = x[i] + 1;
}
一般来说,void *
只有在你不关心你指向的对象的大小和类型,或者你需要根据不同sizes/types做泛型操作时才有用在运行时已知(仍然,总是有适当的转换)。
如果你想允许不同的类型,那么你可以这样做:
enum Type { INT, FLOAT, /* ... */ };
void myfunc(void* x, void* y, size_t n, enum Type t) {
switch (t) {
case INT: {
int *xi = x;
int *yi = y;
for(size_t i = 0; i < n; i++)
yi[i] = xi[i] + 1;
break;
}
case FLOAT: {
float *xf = x;
float *yf = y;
for(size_t i = 0; i < n; i++)
yf[i] = xf[i] + 1;
break;
}
// case ...: {
// ...
// }
}
}
请注意 这在 C 中并不是很好的做法。如果你能够在编译时知道类型,那么无论如何只定义不同的函数以不同的类型作为参数,这将是最快的选择。
假设我有这样一个函数:
void myfunc(void* x, void* y){
for(i=0; i<n;i++)
y[i] = x[i]+1;
}
我的目标是获取向量 x
,做一些数学运算并将其存储在 y
中。在这种情况下,我知道 x
将作为 int
s.
我知道我们不能直接在 x
上做数学运算,因为它被转换为 void,但我很好奇绕过这个拦截器的最有效方法。我目前的方法是 memcpy
x 到 int*
温度,做我的数学,然后 memcpy
到 y
。显然,这不是一个具有多个 memcpy
的特别有效的过程。我确信有更好的方法,我只是对 C 内存分配规则了解不够,无法弄清楚。
如果您知道指针指向 int
的数组,您可以转换为该类型:
void myfunc(void* x, void* y){
int *a = x;
int *b = y;
for(i=0; i<n;i++)
b[i] = a[i]+1;
}
你可以避开memcpy
。如果您希望使用整数或字节或任何其他类型,则只需进行适当的转换,例如 x
和 y
引用 int
:[=19= 的数组]
void myfunc(void* x, void* y){
int *xp = x;
int *yp = y;
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
yp[i] = xp[i] + 1;
}
在这种情况下,您根本不需要将它们作为 void *
传递:
void myfunc(int* x, int* y){
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
y[i] = x[i] + 1;
}
一般来说,void *
只有在你不关心你指向的对象的大小和类型,或者你需要根据不同sizes/types做泛型操作时才有用在运行时已知(仍然,总是有适当的转换)。
如果你想允许不同的类型,那么你可以这样做:
enum Type { INT, FLOAT, /* ... */ };
void myfunc(void* x, void* y, size_t n, enum Type t) {
switch (t) {
case INT: {
int *xi = x;
int *yi = y;
for(size_t i = 0; i < n; i++)
yi[i] = xi[i] + 1;
break;
}
case FLOAT: {
float *xf = x;
float *yf = y;
for(size_t i = 0; i < n; i++)
yf[i] = xf[i] + 1;
break;
}
// case ...: {
// ...
// }
}
}
请注意 这在 C 中并不是很好的做法。如果你能够在编译时知道类型,那么无论如何只定义不同的函数以不同的类型作为参数,这将是最快的选择。