【问题标题】:Returning a void pointer as a function parameter in C在 C 中将 void 指针作为函数参数返回
【发布时间】:2018-09-10 12:21:29
【问题描述】:

我有一个返回数组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);

【问题讨论】:

  • 函数怎么调用?
  • 你需要多一层间接性
  • 你当然不能返回本地数组的地址。当您的函数返回时,该数据将无效。

标签: c pointers void


【解决方案1】:

你可以这样做:

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 参数准确地说明了原始指针类型是什么,因此函数可以执行正确的转换。

之后,函数可以像处理原始指针一样处理转换后的指针。如果原始指针指向一个数组,那么转换后的指针也可以用于访问该数组的所有项。

【讨论】:

  • 代码运行正常!但是,请您描述一下它的机制吗?
【解决方案2】:

很可能做你想做的事,但不是你想要做的那样。如果你想在你做的时候预先分配缓冲区,那很好,你只需要传入指针本身。然后你的问题就开始了。

首先,三个int16_t 不足以容纳相同数量的float 元素(通常每个元素4 个字节)。您需要确保传入的缓冲区足够大以容纳输出。

其次,赋值Data = acc; 只是复制指针的值,而不是它包含的数据。为此,您必须使用memcpy(Data, acc, 3 * sizeof(uint16_t));memmove(Data, acc, 3 * sizeof(uint16_t)); 或类似的东西。更简单地说,您可以直接将值存储在 Data 缓冲区中,而不是一开始就与 acc 混淆。

【讨论】:

    猜你喜欢
    • 2020-06-11
    • 2012-02-26
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2015-04-18
    相关资源
    最近更新 更多