如何使用void指针作为函数返回类型在C中

时间:2013-11-16 08:43:51

标签: c function void-pointers

所以我计划写一个函数来返回一个随机数组元素。功能接受两个 parameters - 一个void指针数组和数组长度。它应该返回一个void指针。 我们的想法是采用给定的数组,它以void指针数组的形式出现,该函数将返回数组的随机元素。 我的问题是,我需要做什么来返回指针,我需要对“结果”做什么,所以我可以这样返回它?在病房之后我需要做什么才能再次访问它? 感谢

这是我所做的,但我得到了:

 "25: error: invalid use of void expression"

警告如:

" warning: pointer of type ‘void *’ used in arithmetic"

我的代码:

#include<stdlib.h>
#include<stdio.h>
#include<time.h>
void *randomNum(void * array, int length)
{
    void * result;  
    result=array[rand()%(length-1)];
    return result;
}    
int main()
{
int i;
srand(13);
int array[9]={1,5,6,85,132,65463,1354,5863,134};

for (i=0;i<9; i++)
{
    printf("%d\n",*randomNum(array,9));
}



return 0;
}

4 个答案:

答案 0 :(得分:4)

你可以用这种方式编写一个完美的通用函数,但是:

    result = array[rand()%(length-1)];

这是取消引用void指针array,同时也尝试将其存储到指针result中。您要存储的是该偏移处的地址:

    result = array + rand()%(length-1);

但是,您也无法对void指针执行此类算法,因为底层类型的大小未知(某些编译器允许sizeof(void)==1作为扩展)。对于非void数组,给定元素消耗的字节数,以及在对地址进行算术运算时增加的字节数,在类型中进行编码。在像这样的void指针上运行的泛型函数中,你需要显式传递类型的大小。

void *randomNum(void * array, size_t size, size_t length)

现在通过将array强制转换为char指针来执行计算,这会强制array上的算术以1 x字节乘以提供的大小参数的增量发生:

    result = (char*)array + (rand()%(length-1)) * size;
                   ^                            ^

然后,您可以使用randomNum(array, sizeof(*array), 9)

调用randomNum

但是,在解除引用之前,仍需要转换函数的返回值。

    printf("%d\n", *(int*)randomNum(array,sizeof(*array),9));

答案 1 :(得分:1)

该方法存在许多问题:

1)由于参数array的类型为void *,因此基于length对其进行索引的计划将无效 - 索引工作,您的每个元素的长度数组也需要知道。您似乎正在尝试创建一个适用于任何类型数组的泛型函数,但老实说,为不同类型的数组创建单独的函数更简单。

(要了解这是有问题的原因,请记住array[index]等同于*(array + index);通过索引void *您正在应用指针算法,然后解除引用 void指针。默想一下。)

2)执行*randomNum(array, 9)时,您正在取消引用void指针。这是不可能做到的;你需要首先将指针强制转换为适当的类型,即*((int *)randomNum(array, 9)),但正如我上面所说,使用randomNum处理void指针的整个方法是有问题的,所以只需将整个内容更改为:

int *randomNumInt(int *array, size_t length)

答案 2 :(得分:0)

您的问题(导致错误的问题)是:*randomNum(array,9)

请记住,randomNum的返回类型为void *,您可以取消引用它。因此表达无效。这对编译器没有多大意义,它会发出错误。

现在,我不太确定为什么你宣布randomNum返回void*,你可能只是声明它int。您有效地将数组值转换为void *,这将指向某个开头的内存 - 一个无效的位置。如果您要将指针强制转换为int*,那么您的程序将会出现段错误。

答案 3 :(得分:0)

您无法在程序中取消引用void指针*randomNum(array,9)。在使用void指针执行任何操作之前,您必须先将其强制转换。