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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20016508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:17:39  来源:igfitidea点击:

how to use void pointer as function return type In C

cfunctionvoid-pointers

提问by Hyman Zhu

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. It should return a void pointer. 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. 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;
}

采纳答案by tab

You can write a perfectly fine generic function this way, but:

您可以通过这种方式编写完美的泛型函数,但是:

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

This is dereferencing the void pointer arraywhile also attempting to store it into a pointer result. What you want to store is the address at that offset:

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

    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)==1as an extension). 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. In a generic function operating on void pointers like this one you'll need to explicitly pass the size of the type.

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

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

Now perform the calculation by casting arrayto a char pointer, which forces arithmetic on arrayto occur in increments of 1 byte times the provided size parameter:

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

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

You can then call randomNum with 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));

回答by Arkku

There are a number of problems with the approach:

该方法存在许多问题:

1) Since the argument arrayis of type void *, your plan of indexing it based on lengthwill not work—for indexing to work, the length of each element in your array needs to be known as well. 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.

1) 由于参数array的类型为void *,您基于它的索引计划length将不起作用 - 要使索引起作用,还需要知道数组中每个元素的长度。您似乎正在尝试创建一个适用于任何类型数组的通用函数,但老实说,为不同类型的数组创建一个单独的函数更简单。

(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). This cannot be done; you need to cast the pointer to an appropriate type first, i.e., *((int *)randomNum(array, 9)), but as I said above, the whole approach with randomNumdealing in void pointers is problematic, so just change the whole thing to:

2) 当您执行*randomNum(array, 9). 这是做不到的;您需要首先将指针转换为适当的类型,即 ,*((int *)randomNum(array, 9))但正如我上面所说的,randomNum处理 void 指针的整个方法是有问题的,因此只需将整个内容更改为:

int *randomNumInt(int *array, size_t length)

回答by Norw?

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. The expression is therefore void. That does not make much sense to the compiler, and it issues an error.

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

Now, I am not quite sure whyyou declared randomNumto return void*, you might instead just have declared it int. You effectively convert an array value to a void *, which would point somewhere to the beginning og memory - an invalid location. If you were to cast the pointer to int*, your program would segfault.

现在,我不太确定你为什么声明randomNumreturn void*,你可能只是声明了 it int。您有效地将数组值转换为 a void *,它会指向起始 og 内存的某个位置 - 一个无效的位置。如果您将指针int*强制转换为,您的程序将出现段错误。

回答by haccks

You can't dereference a voidpointer like *randomNum(array,9)in your program. You should have to cast it before doing anything with voidpointer.

您不能void*randomNum(array,9)在程序中那样取消引用指针。在对void指针执行任何操作之前,您应该必须对其进行转换。