2016-07-04 18 views
1

私はCの初心者でリンクリストを試しています.Githubレポが見つかりました。作成関数は次のように書かれている:voidポインター引数を持つ関数を使用する

Node* ListCreate(void* data) { 
    Node *head = malloc(sizeof(Node)); 
    if (head != NULL) { 
     head->next = NULL; 
     head->data = data; 
    } 
    return head; 
} 

私はintvoid*を変更することにより、それを使用することができましたし、その後mainでやって:

Node *root = ListCreate(5); 

をしかし、私は、ボイドポインタについて少し読み、 C++テンプレートのようなジェネリック型として使えるように思えますが、どのように動作するかを理解することができれば便利です。私はいくつかのことを試みたが、私は仕事にそれを得るために持っている最も近いエラーではありませんが、1つの警告:

incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'

私はここでステップ足りませんか?私は最初に関数定義に何かを追加する必要があるように感じましたが、私はそれを書いた人が自分がやっていることを知っていて、ちょうどmainで正しく使用しなかったと仮定しています。だから私はこの関数に引数を渡すはずの別の方法はありますか?

+1

ひとつの関数が異なる型のデータを扱う場合(特にそれらの異なる型のデータにポインタを渡すのが合理的な場合)にvoidポインタを使用することがありますが、それを避けるために。 'qsort()'や 'bsearch()'のような関数はvoidポインタを渡すので、voidポインターを受け入れる関数を用意していますが、渡されたポインターを正しい(期待される)型に変換します。明示的なキャストなしで整数型からポインタに変換することはできません。浮動小数点型から変換することはできません。 –

+1

私はリンクリストのデータをint、float、またはcharに設定できるようにしようとしていました。これはC++よりもC言語では難しいのですか? – Austin

+1

OK;リストのデータ型は何ですか? 'int'値や' int *'値を格納していますか?'int *'の扱いはリストコードでは簡単ですが、リストコードを使用するコードでは難しくなります。ポインタをポイントするために別々の 'int'変数を持たなければならないので、リストに格納することができますポインタとそれが指している値の両方を持っているのでスペースが無駄になります)。 'float'のために同上。 'char'と言うと、単一の文字(ハード)や文字列(別名' char * '、比較的簡単)を意味しますか? –

答えて

0

数値リテラル(またはキャスト?)をラップする必要があると思います。このよう

void *BOX_VAR;//Not require if use GCC extension 
#define BOX(type, value) ((*(type *)(BOX_VAR=malloc(sizeof(type))) = value), BOX_VAR) 
#define UNBOX(type, value) (*(type *)(value)) 

Node *list = ListCreate(BOX(int, 5)); 
int v = UNBOX(int, list->data); 
printf("%d\n", v); 
1

はコメントで他の人が述べたように、種類ごとに異なるリストを作成する方が適しています。

しかし、同じ関数定義を使用する場合は、データのポインタ(intまたはchar)を渡して、void *としてキャストしてください。

/* main: start */ 
int main(void) 
{ 
    Node *list_head; /* Points to first element in list */ 
    Node *node_tmp; /* Just a temporary pointer */ 

    int *pint; 
    char *pchar; 

    /* create an empty list */ 
    list_head = NULL; 

    /* Note that there is no error checking done for 
    * malloc, which is not good 
    */ 

    /* Create a node which points to int */ 
    pint = malloc(sizeof(int)); 
    *pint = 10; 
    node_tmp = ListCreate((void *) pint); 
    /* Add this node to list */ 
    list_head = add(node_tmp, list_head); 

    /* Create a node which points to char */ 
    pchar = malloc(sizeof(char)); 
    *pchar = 'c'; 
    node_tmp = ListCreate((void *) pchar); 
    /* Add this node to list */ 
    list_head = add(node_tmp, list_head); 

    /* print total number of nodes in list */ 
    print_tot_nodes(list_head); 
    return 0; 
} 

コードaddと簡潔にするためですommited print_tot_nodesため。

が異なるデータ型を指している場合、print_tot_nodesまたはaddのような関数はあまり問題になりません。しかし、最小の要素を持つノードへのポインタを返すNode *smallest(Node *head)のような関数を実装する必要がある場合、複雑になることがあります。

したがって、さまざまな種類の異なるリストを使用する方が簡単です。しかしcast実際のポインタをvoid *に変更すると、にはが必要です。元の投稿と同じ機能定義を使用することができます。

関連する問題