簡體   English   中英

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

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

這里有幾個函數聲明,我無法理解如何完成。 我已經掃描了網絡以查看無效指針是什么,我理解它必須被轉換為有用的東西(因為它只指向一些內存塊),但我不知道這有助於完成這些聲明。

/* 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);

有更多這樣的功能,但我想如果我理解如何做這兩個我應該保持良好狀態。 例如,對於第二個函數,我們如何將item_pointer轉換為應該返回的任何適當的東西?

void *通常意味着您只對數據的地址感興趣,無論其類型如何,其中一些原因如下:

  • 這個void *指向的數據的內部表示是隱藏的,你不應該直接訪問數據, 信息隱藏 ,你的功能2恰恰就是這種情況的一個例子。

  • 這個類型在調用鏈中的某個函數中是已知的,就像qsort和大多數將參數傳遞給其他函數的函數一樣。

  • 該類型不是必需的,因為指針指向的數據將被處理為不同的類型,例如memcpy可以將數據作為字節處理, unsigned char *

使用quicksort在C中排序使用void指針,以便我們可以對數組中的任何數據進行排序。 如果參數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 ;
}

然后您可以對自己的數據類型進行排序:

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

完整的計划

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

任何指針類型都可以分配給void* ,這在函數不需要知道類型或者通過其他方式傳遞類型信息的情況下很有用。 這允許您只編寫一個函數來處理任何指針類型,而不是每個數據類型的單獨函數。

雖然你不能取消引用void*你可以把它轉換為任何類型並取消引用它 - 它的語義 - 即它是否有意義,取決於代碼而不是強制字節編譯器。

通用函數通常對某些數據塊的內容不感興趣,只是它的地址和通常它的大小。

舉個簡單的例子:

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

看到memcopy()不需要知道tItem是什么來復制它們的數組,它只需要知道數組中的地址和大小(以字節為單位)。 它會轉換void* pointer參數,將數據重新解釋為char數組,以執行逐字節復制。 要做到這一點,它不需要知道傳遞給它的tItem或任何其他數據對象的內部語義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM