简体   繁体   English

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

[英]how to use void pointer as function return type In C

So I am planing to Write a function to return a random array element. 所以我计划写一个函数来返回一个随机数组元素。 The function accept two parameters—an array of void pointers and the array length. 该函数接受两个参数 - 一个void指针数组和数组长度。 It should return a void pointer. 它应该返回一个void指针。 The idea is to take the given array, which comes in the form of an array of void pointer, the function will return an random element of the the array. 我们的想法是采用给定的数组,它以void指针数组的形式出现,该函数将返回数组的随机元素。 The question I have is, what do I need to do to return a pointer, what do I need to do to the "result" so I can return it like that? 我的问题是,我需要做什么来返回指针,我需要对“结果”做什么,所以我可以这样返回它? After wards what do I need to do to access it again? 在病房之后我需要做什么才能再次访问它? Thanks 谢谢

Here is what I have done, but I'm getting the: 这是我所做的,但我得到了:

 "25: error: invalid use of void expression"

with warnings like: 警告如下:

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

My code: 我的代码:

#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;
}

You can write a perfectly fine generic function this way, but: 您可以通过这种方式编写完美的通用函数,但是:

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

This is dereferencing the void pointer array while also attempting to store it into a pointer result . 这是取消引用void指针array同时也尝试将其存储到指针result What you want to store is the address at that offset: 您要存储的是该偏移处的地址:

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

However, you can't perform arithmetic like this on void pointers either, as the size of the underlying type is not known (some compilers allow sizeof(void)==1 as an extension). 但是,您无法对void指针执行此类算法,因为底层类型的大小未知(某些编译器允许sizeof(void)==1作为扩展名)。 With a non-void array, the number of bytes a given element consumes, and thus the number of bytes to increment by when doing arithmetic on the address, is encoded in the type. 对于非void数组,给定元素消耗的字节数,以及在对地址进行算术运算时增加的字节数,在类型中进行编码。 In a generic function operating on void pointers like this one you'll need to explicitly pass the size of the type. 在像这样的void指针上运行的泛型函数中,你需要显式传递类型的大小。

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

Now perform the calculation by casting array to a char pointer, which forces arithmetic on array to occur in increments of 1 byte times the provided size parameter: 现在通过将array转换为char指针来执行计算,这会强制对array进行算术运算,其增量为提供的size参数的1个字节乘以:

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

You can then call randomNum with randomNum(array, sizeof(*array), 9) 然后,您可以使用randomNum(array, sizeof(*array), 9)调用randomNum randomNum(array, sizeof(*array), 9)

However, you still need to cast the return value of the function before dereferencing it. 但是,您仍需要在解除引用之前强制转换函数的返回值。

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

There are a number of problems with the approach: 该方法存在许多问题:

1) Since the argument array is of type void * , your plan of indexing it based on length will not work—for indexing to work, the length of each element in your array needs to be known as well. 1)由于参数array的类型为void * ,因此根据length对其进行索引的计划将不起作用 - 索引工作,数组中每个元素的长度也需要知道。 You seem to be trying to make a generic function that would work for any type of array, but honestly it's simpler to make a separate function for different types of arrays. 您似乎正在尝试创建一个适用于任何类型数组的泛型函数,但老实说,为不同类型的数组创建单独的函数更简单。

(To see why this is problematic, remember that array[index] is equivalent to *(array + index) ; by indexing the void * you are applying pointer arithmetic to and then dereferencing the void pointer . Meditate on this.) (要了解为什么这是有问题的,请记住, array[index]等效于*(array + index) ;通过索引void *您将指针算法应用于然后取消引用void指针 。请冥想。)

2) You are dereferencing a void pointer when you do *randomNum(array, 9) . 2)当你执行*randomNum(array, 9)时,你正在取消引用一个void指针。 This cannot be done; 这是不可能做到的; you need to cast the pointer to an appropriate type first, ie, *((int *)randomNum(array, 9)) , but as I said above, the whole approach with randomNum dealing in void pointers is problematic, so just change the whole thing to: 你需要首先将指针转换为适当的类型,即*((int *)randomNum(array, 9)) ,但正如我上面所说的,使用randomNum处理void指针的整个方法是有问题的,所以只需更改整件事:

int *randomNumInt(int *array, size_t length)

Your problem (well, the one causing the error) is: *randomNum(array,9) 你的问题(导致错误的那个)是: *randomNum(array,9)

Remember that the return type of randomNum is void * , which you dereference. 请记住,randomNum的返回类型是void * ,您可以取消引用它。 The expression is therefore void. 因此表达无效。 That does not make much sense to the compiler, and it issues an error. 这对编译器没有多大意义,它会发出错误。

Now, I am not quite sure why you declared randomNum to return void* , you might instead just have declared it int . 现在,我不太清楚为什么你声明randomNum返回void* ,你可能只是将它声明为int You effectively convert an array value to a void * , which would point somewhere to the beginning og memory - an invalid location. 您有效地将数组值转换为void * ,这将指向某个开头的内存 - 一个无效的位置。 If you were to cast the pointer to int* , your program would segfault. 如果你要将指针强制转换为int* ,那么你的程序会出现段错误。

You can't dereference a void pointer like *randomNum(array,9) in your program. 您不能在程序中取消引用像*randomNum(array,9)这样的void指针。 You should have to cast it before doing anything with void pointer. 在使用void指针执行任何操作之前,您必须先将其void

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM