2017-08-19 9 views
0

私はその型を知らない数値配列を集計する関数を書く必要があります。 関数は、配列のサイズと各変数のサイズを受け取ることができます。 私は空ポインタを使うべきだと言われましたが、どうやってそれをするのか分かりません。 私はマクロを使用できません。感謝! ありがとう!未知の型から数値配列の合計を返す関数を書く方法は?

+2

'float'と' int'が同じサイズのとき、私はその状態では区別できないと思います。 – BLUEPIXY

+0

'float'と' int'は異なる表現をしています。あなたはどれがサイズからだけであるかを知ることはできません。 –

+2

厄介な解決策:*複数の*関数を書く。これは[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)ですか? Cは "ジェネリック"をあまりサポートしておらず、マクロで使用できるもの(一般的な選択)のみです。タイプ情報がコンパイルされたCプログラムに存在しないため、**はサポートできません。 –

答えて

2

練習全体が正直言ってばかげている。

あなたはqsort()とほぼ同様のインタフェースを持っている機能を使用する必要があるだろう:

void calculate_sum(const void *ptr, 
        const size_t size, 
        const size_t num, 
        void  *sum, 
        void  (*sum_func)(void *, const void *)) 
{ 
    size_t i; 
    for (i = 0; i < num; i++) 
     sum_func(sum, (void *)((char *)ptr + size * i)); 
} 

呼び出し側がまだ

void sum_int(void *acc, const void *val) 
{ 
    *(int *)acc += *(const int *)val; 
} 

void sum_float(void *acc, const void *val) 
{ 
    *(float *)acc += *(const float *)val; 
} 

はのは、言ってみましょうと言う、種類ごとに加算機能が必要になります呼び出し元には2つの配列があります。たとえば、

合計を計算するにはeは、インターフェイスがqsort()のようなもののためにうまく機能することを

float fsum; 
double dsum; 

fsum = 0.0f; 
calculate_sum(fdata, sizeof fdata[0], 50, &fsum, sum_float); 

dsum = 0.0; 
calculate_sum(ddata, sizeof ddata[0], 40, &dsum, sum_double); 

する必要があります - sが呼び出し側が三番目のパラメータを渡すことができることから恩恵を受けるでもqsort()」、void *は、比較関数にpasedが。私の意見では、この種のインターフェースではソート・エクササイズが非常にうまく動作します。特に、ある種の小さなstructで使用すると効果的です。

ここでは、エクササイズが学習者を間違った方向に向けると考えています。これは、算術演算の正しいインタフェースではありません。それは、過度に複雑で遅い、雇用のセキュリティのために設計されたエンタープライズコードを生成します。読み込み不能、保守可能、良いコード。

私の意見では、合計のような算術的なものは、には、専用機能が必要です。それはあなたが多くのコードをコピーして貼り付けなければならないというわけではありません。ここではプリプロセッサを使うことができます。関数定義に

#include <stdlib.h> /* For size_t type */ 

#define DEFINE_SUM_FUNC(type, funcname)    \ 
    type funcname (const type *data, size_t count) \ 
    {            \ 
     const type *ends = data + count;   \ 
     type   sum = 0;      \ 
     while (data < ends)       \ 
      sum += *(data++);      \ 
     return sum;         \ 
    } 

DEFINE_SUM_FUNC(float, float_sum); 
DEFINE_SUM_FUNC(double, double_sum); 
DEFINE_SUM_FUNC(short, short_sum); 
DEFINE_SUM_FUNC(int,  int_sum); 
DEFINE_SUM_FUNC(long,  long_sum); 

#define array_sum(array, count) _Generic((array)[0],    \ 
    float: float_sum((const float *)(array), (size_t)(count)), \ 
    double: double_sum((const double *)(array), (size_t)(count)), \ 
    short: short_sum((const short *)(array), (size_t)(count)), \ 
     int: int_sum((const int *)(array), (size_t)(count)), \ 
     long: long_sum((const long *)(array), (size_t)(count)) ) 

DEFINE_SUM_FUNC(type, funcname)マクロ評価されます。

はの一つは、C11 _Genericセマンティクスを使用して加算を実装する方法を見てみましょう。この関数は配列要素の合計を計算します。 (この実装は、ポインタのアプローチを使用しています。)

を今、あなたは以前と同じ二つの配列を持っている場合、float fdata[50];double ddata[40];は、あなただけの

fsum = array_sum(fdata, 50); 
dsum = array_sum(ddata, 40); 

注意を呼び出すことができる配列とポインタの両方のためのarray_sum()作品。つまり、float *fdata;、またはconst double *ddata;があった場合、上記の2行は正常に動作します。前-C11コードで

、自分でマクロarray_sum()をドロップし、タイプ固有の関数を呼び出すことができます。

fsum = float_sum(fdata, 50); 
dsum = double_sum(ddata, 40); 

(GCCは、1つのarray_sum()マクロを構築するために使用できる拡張、__builtin_types_compatible_p()を提供してい_Generic()がなくても)

関連する問題