在 C 中返回一个 void 指针作为函数参数

Returning a void pointer as a function parameter in C

我有一个 returns 数组 Data 的函数。数组的类型是 intfloat。我想使用 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