在 C 中返回一个 void 指针作为函数参数
Returning a void pointer as a function parameter in C
我有一个 returns 数组 Data
的函数。数组的类型是 int
或 float
。我想使用 void
指针。如果 outputType
为 0,则 Data
将指向整数数组,否则它将指向浮点数组。
是否可以在 C 中执行此操作?
void getData(void *Data , uint8_t outputType)
{
...
int16_t acc[3]={0,0,0};
...
acc[0] = (int16_t) ((data[1]*256+data[0]));
acc[1] = (int16_t) ((data[3]*256+data[2]));
acc[2] = (int16_t) ((data[5]*256+data[4]));
Data = acc;
}
在主要代码中:
int16_t output[3];
getData(output, 0);
你可以这样做:
void getData(void *Data , uint8_t outputType) {
if (outputType == 0) {
int16_t* data = Data;
/* fill int16_t data here - eg. : */
data[0] = 42;
}
else {
float* data = Data;
/* fill float data here - eg. : */
data[0] = 42.0f;
}
}
假设您将其称为:
int16_t output[3];
getData(output, 0);
或:
float output[3];
getData(output, 1);
请特别注意不要超出数组的范围。
说明
任何指向对象类型的指针都可以转换为 void*
并再次返回原始类型,生成的指针将与原始指针进行比较。
这可用于(如在本例中)实现适用于任何指针类型的通用函数(参考,例如 What does void* mean and how to use it?)。
但有一个警告:void*
不能被取消引用(也不能对其执行指针运算),因此必须在取消引用之前将其转换回原始指针类型。 outputType
参数准确说明原始指针类型是什么,因此函数可以执行正确的转换。
之后,函数可以像处理原始指针一样处理转换后的指针。如果原始指针指向一个数组,那么转换后的指针也可以用来访问该数组的所有项。
很有可能做你想做的事,但不是你想做的那样。如果你想像你做的那样预先分配缓冲区,那很好,你只需要传入指针本身。然后你的问题开始了。
首先,三个 int16_t
不足以容纳相同数量的 float
元素(每个元素通常为 4 个字节)。您需要确保传入的缓冲区足够大以容纳输出。
其次,赋值Data = acc;
只是复制指针的值,而不是它包含的数据。为此,您必须使用 memcpy(Data, acc, 3 * sizeof(uint16_t));
、memmove(Data, acc, 3 * sizeof(uint16_t));
或类似的东西。更简单地说,您可以直接将值存储在 Data
缓冲区中,而不是首先弄乱 acc
。
我有一个 returns 数组 Data
的函数。数组的类型是 int
或 float
。我想使用 void
指针。如果 outputType
为 0,则 Data
将指向整数数组,否则它将指向浮点数组。
是否可以在 C 中执行此操作?
void getData(void *Data , uint8_t outputType)
{
...
int16_t acc[3]={0,0,0};
...
acc[0] = (int16_t) ((data[1]*256+data[0]));
acc[1] = (int16_t) ((data[3]*256+data[2]));
acc[2] = (int16_t) ((data[5]*256+data[4]));
Data = acc;
}
在主要代码中:
int16_t output[3];
getData(output, 0);
你可以这样做:
void getData(void *Data , uint8_t outputType) {
if (outputType == 0) {
int16_t* data = Data;
/* fill int16_t data here - eg. : */
data[0] = 42;
}
else {
float* data = Data;
/* fill float data here - eg. : */
data[0] = 42.0f;
}
}
假设您将其称为:
int16_t output[3];
getData(output, 0);
或:
float output[3];
getData(output, 1);
请特别注意不要超出数组的范围。
说明
任何指向对象类型的指针都可以转换为 void*
并再次返回原始类型,生成的指针将与原始指针进行比较。
这可用于(如在本例中)实现适用于任何指针类型的通用函数(参考,例如 What does void* mean and how to use it?)。
但有一个警告:void*
不能被取消引用(也不能对其执行指针运算),因此必须在取消引用之前将其转换回原始指针类型。 outputType
参数准确说明原始指针类型是什么,因此函数可以执行正确的转换。
之后,函数可以像处理原始指针一样处理转换后的指针。如果原始指针指向一个数组,那么转换后的指针也可以用来访问该数组的所有项。
很有可能做你想做的事,但不是你想做的那样。如果你想像你做的那样预先分配缓冲区,那很好,你只需要传入指针本身。然后你的问题开始了。
首先,三个 int16_t
不足以容纳相同数量的 float
元素(每个元素通常为 4 个字节)。您需要确保传入的缓冲区足够大以容纳输出。
其次,赋值Data = acc;
只是复制指针的值,而不是它包含的数据。为此,您必须使用 memcpy(Data, acc, 3 * sizeof(uint16_t));
、memmove(Data, acc, 3 * sizeof(uint16_t));
或类似的东西。更简单地说,您可以直接将值存储在 Data
缓冲区中,而不是首先弄乱 acc
。