2017-09-11 13 views
-1

にvoid *型の変数引数リストを渡すために、私は関数にvoid *型の要素の可変引数リストを通過しようとしていますC.C言語:どのように機能

  1. 私はこれをどのように行うのですか?

  2. リストのアイテム数を計算するにはどうすればよいですか?

  3. どのようにしてvar-argsリストをループし、各void *アイテム をvoid *アイテムをパラメータとする別の関数に渡しますか?

これは私がやったことですが、動作しません。

void AddValues(List* data, void* args, ...) { 

int len = sizeof (args)/sizeof (*args); 


for(int i=0;i<len;i++){ processItem(args[0]); } 

} 

void processItem(void* item){ 

} 
+2

ます。http:// EN .cppreference.com/w/c/variadic – Rafael

+1

あなたはそのように長さを計算することはできません。 'sizeof(args)/ sizeof(* args)' = 'sizeof(void *)/ sizeof(void)'しかし、voidはサイズがありません。 varargsリストを取る関数は、他のいくつかのソースからサイズを決定できる必要があります: - 別のパラメータ(printfは書式文字列中の%の数を使用します)または特殊な値(void *ポインタはすべて、 1つはNULLです)したがって、最初のパラメータはサイズでなければならないか、最後のvoid *は特別なセンチネル値を持つ必要があります。 –

+1

@gbenroscience 'void *'パラメータはvar-argsの '...'と全く関係ありません。あなたは 'void *'を尊重することはできません。もしコンパイラが関わっている限り、それはちょうど 'void'へのポインタなので、何かに何かが指されているかをあなたに伝えません。 –

答えて

2

どのように私は、リスト内の項目の数を計算するのですか?

できません。それは提供されなければなりません。

どのようにループVAR-引数リストを通って、そのパラメータとしてのvoid *アイテムを取る別の関数にそれぞれのボイドにアイテムを渡すのですか?*

Variadic Functionsに記載されているように、

#include <stdarg.h> 

void AddValues(int count, ...) { 
    va_list args; 
    va_start(args, count); 

    for(int i=count; i--;) 
     processItem(va_arg(args, void*)); 

    va_end(args); 
} 

使用例:

void* p1 = ...; 
void* p2 = ...; 
void* p3 = ...; 
void* p4 = ...; 

AddValues(4, p1, p2, p3, p4); 

これは処理内容によって異なりますが、可変パラメータの代わりに配列を使用しているはずです。

void AddValues(int count, const void** args) { 
    for(int i=count; i--;) 
     processItem(*(args++)); 
} 

使用例:

#define C_ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0])) 

void* ptrs[4]; 
ptrs[0] = ...; 
ptrs[1] = ...; 
ptrs[2] = ...; 
ptrs[3] = ...; 

AddValues(C_ARRAY_LEN(ptrs), ptrs); 

または(ポインタがNULLできない場合):

void AddValues(const void** args) { 
    while (*args != NULL) 
     processItem(*(args++)); 
} 

使用例:

void* ptrs[5]; 
ptrs[0] = ...; 
ptrs[1] = ...; 
ptrs[2] = ...; 
ptrs[3] = ...; 
ptrs[4] = NULL; 

AddValues(ptrs); 
+0

va_argとva_endは組み込み関数ですか? – gbenroscience

+1

@gbenroscience標準ライブラリ関数。あなたが得るようにビルトインに近い。標準リビジョンの標準リビジョンに若干の変更があるかもしれませんが、Cは50年のレガシーコードでの爆発を避けるために変更されているので保守的です。 – user4581301

+0

はい、私はそれを見つけました。ありがとう – gbenroscience

関連する問題