[英]how to use void pointer as function return type In C
所以我计划写一个函数来返回一个随机数组元素。 该函数接受两个参数 - 一个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;
}
您可以通过这种方式编写完美的通用函数,但是:
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
进行算术运算,其增量为提供的size参数的1个字节乘以:
result = (char*)array + (rand()%(length-1)) * size;
^ ^
然后,您可以使用randomNum(array, sizeof(*array), 9)
调用randomNum randomNum(array, sizeof(*array), 9)
但是,您仍需要在解除引用之前强制转换函数的返回值。
printf("%d\n", *(int*)randomNum(array,sizeof(*array),9));
该方法存在许多问题:
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)
你的问题(导致错误的那个)是: *randomNum(array,9)
请记住,randomNum的返回类型是void *
,您可以取消引用它。 因此表达无效。 这对编译器没有多大意义,它会发出错误。
现在,我不太清楚为什么你声明randomNum
返回void*
,你可能只是将它声明为int
。 您有效地将数组值转换为void *
,这将指向某个开头的内存 - 一个无效的位置。 如果你要将指针强制转换为int*
,那么你的程序会出现段错误。
您不能在程序中取消引用像*randomNum(array,9)
这样的void
指针。 在使用void
指针执行任何操作之前,您必须先将其void
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.