简体   繁体   English

你如何在C中使用void指针?

[英]How do you use the void pointer in C?

Here are a couple of function declarations that I'm having trouble understanding how to complete. 这里有几个函数声明,我无法理解如何完成。 I've scanned the web to see what a void pointer is, and I understand that it must be cast to something to be useful (because it just points to some memory block), but I don't see how that helps in completing these declarations. 我已经扫描了网络以查看无效指针是什么,我理解它必须被转换为有用的东西(因为它只指向一些内存块),但我不知道这有助于完成这些声明。

/* type of comparison function that specifies a unique order.
   Returns 1 if pointer1 should come before,
   0 if equal to, or -1 if after pointer2. */
typedef int (*compare_function) (const void* pointer1, const void* pointer2);

/* get the data object */
void* get_obj(const void* item_pointer);

There are more functions like this, but I think if I understand how to do these two I should be in good shape. 有更多这样的功能,但我想如果我理解如何做这两个我应该保持良好状态。 For example, for the second function, how do we cast the item_pointer to anything appropriate that should be returned? 例如,对于第二个函数,我们如何将item_pointer转换为应该返回的任何适当的东西?

void * usually means that you are only interested in the address of the data regardless of its type, some of the reasons: void *通常意味着您只对数据的地址感兴趣,无论其类型如何,其中一些原因如下:

  • the internal representation of the data this void * pointing to is hidden, you are not supposed to access the data directly, information hiding , your function 2 is properly an example of this case. 这个void *指向的数据的内部表示是隐藏的,你不应该直接访问数据, 信息隐藏 ,你的功能2恰恰就是这种情况的一个例子。

  • the type is known by some function in the call chain, like with qsort and most functions that pass arguments to other functions. 这个类型在调用链中的某个函数中是已知的,就像qsort和大多数将参数传递给其他函数的函数一样。

  • the type is not required because the data the pointer is pointing to will be handled as different type, like with memcpy which may handle the data as bytes, unsigned char * . 该类型不是必需的,因为指针指向的数据将被处理为不同的类型,例如memcpy可以将数据作为字节处理, unsigned char *

Sorting in C with quicksort uses void pointers so that we can sort any data in arrays. 使用quicksort在C中排序使用void指针,以便我们可以对数组中的任何数据进行排序。 The sort function must return -1, +1, or 0 if the parameter b is before, after or the same as parameter a 如果参数b在参数a之前,之后或相同,则sort函数必须返回-1,+ 1或0

#include <stdio.h>
#include <stdlib.h>

int sort_order( const void *, const void *);

int main(void)
{
  int i;
  char alfa[6] = { ’C’, ’E’, ’A’, ’D’, ’F’, ’B’ }; 
  qsort( (char*)alfa, 6, sizeof(char), sort_order); 
  for (i=0 ; i<5 ; i++)  // now in order?
     printf("\nchar %d = %c",i, alfa[i]);
  printf("\n");
  system("PAUSE");
  return 0;
}

int sort_order( const void* a, const void* b)
{
  if      ( *((char*)a) < *((char*)b) )     return -1 ;
  else if ( *((char*)a) > *((char*)b) )     return  1 ;
  else                                      return  0 ;
}

Then you can sort your own datatypes: 然后您可以对自己的数据类型进行排序:

typedef struct {   float left;   float right;} ears;
typedef struct{  char name[13];  int weight;  ears eararea;} monkey;    

monkey* Index[4];

for(i=0;i<4;i++)   
    Index[i]= (monkey* )malloc(sizeof(monkey));     

qsort((void* ) Index, 4, sizeof(monkey* ), sort_order);

// Sorted by weight    
int sort_order( const void* a, const void* b) {   
    if((**((monkey** )a)).weight < (**((monkey** )b)).weight) return -1 ;   
    else if ((**((monkey** )a)).weight > (**((monkey** )b)).weight ) return  1 ;
    else return  0 ;
}

Complete program 完整的计划

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    float left;
    float right;
} ears;

typedef struct {
    char name[13];
    int weight;
    ears eararea;
} monkey;

int sort_monkeys( const void *, const void *);

int main(void)
{   monkey* monkeys[4];
    int i;
    for(i=0; i<4; i++) {
        monkeys[i]= (monkey* )malloc(sizeof(monkey));
        monkeys[i]->weight=i*10;
        if (i==2)
            monkeys[i]->weight=1;
    }
    for (i=0 ; i<4; i++)
        printf("\nchar %d = %i",i, monkeys[i]->weight);

    qsort((void* ) monkeys, 4, sizeof(monkey* ), sort_monkeys);

    for (i=0 ; i<4; i++)  // now in order?
        printf("\nmonkey %d = %i",i, monkeys[i]->weight);
    return 0;
}

// Sorted by weight
int sort_monkeys( const void* a, const void* b) {
    if((**((monkey** )a)).weight < (**((monkey** )b)).weight) return -1 ;
    else if ((**((monkey** )a)).weight > (**((monkey** )b)).weight ) return  1 ;
    else return  0 ;
}

Any pointer type may be assigned to a void* , this is useful in cases where a function does not need to know the type, or the type information is conveyed by other means. 任何指针类型都可以分配给void* ,这在函数不需要知道类型或者通过其他方式传递类型信息的情况下很有用。 This allows you to write just one function to deal with any pointer type rather than a separate function for each data type. 这允许您只编写一个函数来处理任何指针类型,而不是每个数据类型的单独函数。

While you cannot dereference a void* you can cast it to any type and dereference it - the semantics of that - ie whether it is meaningful, depends on the code and is not enforced byte compiler. 虽然你不能取消引用void*你可以把它转换为任何类型并取消引用它 - 它的语义 - 即它是否有意义,取决于代码而不是强制字节编译器。

Frequently a generic function is not interested in the content of some block of data, just its address and often its size. 通用函数通常对某些数据块的内容不感兴趣,只是它的地址和通常它的大小。

As a simple example: 举个简单的例子:

void memcopy( void* to, void* from, int length )
{
    char* source = (char*)from ;
    char* dest = (char*)to ;
    int i ;

    for( i = 0; i < lengt; i++ )
    {
        dest[i] = source[i] ;
    }
}

int main()
{
    typedef struct
    {
        int x ;
        int y ;

    } tItem

    tItem AllItems[256] = {0} ;
    tItem AllItemsCopy[256] ;

    memcopy( AllItemsCopy, AllItems, sizeof(AllItems) ) ;
}

See that memcopy() does not need to know what a tItem is in order to copy an array of them, it only needs to know the addresses and the size on the array in bytes. 看到memcopy()不需要知道tItem是什么来复制它们的数组,它只需要知道数组中的地址和大小(以字节为单位)。 It casts the void* pointer arguments to reinterpret the data as a char array to perform a byte-by-byte copy. 它会转换void* pointer参数,将数据重新解释为char数组,以执行逐字节复制。 To do that it does not need to know the internal semantics of tItem or any other data object passed to it. 要做到这一点,它不需要知道传递给它的tItem或任何其他数据对象的内部语义。

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

相关问题 您不能对空指针使用指针算术,那么空指针数组如何工作? - You can't use pointer arithmetic on void pointers, so how do arrays of void pointers work? 如何使用空指针生成2D动态数组? - How do you use a void pointer to generate 2D dynamic Array? 您如何在C ++中的对象中使用“ this”指针? - How do you use the “this” pointer in C++ in objects? 为什么要在此代码中使用void指针? - Why would you use a void pointer in this code? 你如何退出C ++中的void函数? - How do you exit from a void function in C++? 如何在 C++ 中的 void 内设置全局 int? - How do you set a global int inside of a void in C++? 如何使用C ++智能指针复制变化的指针? - How do you replicate a changing pointer with C++ smart pointer? 如何声明带有void *指针的C ++原型,以便它可以采用任何指针类型? - How do I declare a C++ prototype with a void * pointer so that it can take any pointer type? 如何通过函数的空指针参数传递int值并将其转换回int值? - How do you pass an int value through a void pointer paramater of a function and convert it back to an int value? 如何使用 JIT 编译从捕获的 lambda 生成 C 指针回调? - How do you use JIT compilation to produce a C pointer callback from a captured lambda?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM