2

任意のメモリブロックへのvoidポインタ型とブロックバイトサイズの2つの引数を取る関数を書きたかったのです。ブロックに書き込まれるデータの構造体タイプを知っているので、関数は含まれている値を出力する必要があります。

ただし、最初は、私が提案したコードは機能しませんでした。

#define RECORD struct record
struct record {
      char nam[32];
      double val;
};

void xprint (void *p, long j)
{
    j /= sizeof(RECORD);
    RECORD r;

    while(j--){
        r = *((RECORD *)p++);
        printf("\n..%s.., ..%lf..\n",r.nam, r.val);
    }
    return;
}

そこで、主にコードのインクリメント部分で、いくつかの変更を思いつきました。

void print (void *p, long j)
{
    j /= sizeof(RECORD);
    RECORD r = *((RECORD *)p);

    while(j--){
        printf("\n%s,\t%8.2lf\n",r.nam, r.val);
        r = *(++(RECORD *)p);
    }
    return;
}

今ではそれは仕事をしましたが、それでもコードはそれほどコンパクトに見えません。

いくつかの検査の後、私は問題が一列に r = *((RECORD *)p++);並んでいることに気づきました。接尾辞のインクリメントに関しては、pはタイプキャストされなくなったため、pは1バイトだけインクリメントされるようです。

xprint関数を書き直して、接尾辞演算子を引き続き使用できるようにすることはできますが、型キャストされたポインターに適用できますか?

4

1 に答える 1

3

をすぐに変換してvoid *から、そのポインタを関数の残りの部分に使用します。RECORD *

void print (const void *p, size_t size)
{
    const RECORD *r = p;
    size_t count = size / sizeof(*r);

    while (count--) {
        printf("\n%s,\t%8.2lf\n", r->nam, r->val);
        ++r;
    }
}

また、変数名の改善や。の追加など、いくつかのスタイル上の変更を行いましconstた。


ちなみに、Clement Reyが言うように、defineよりもtypedefを使用する方が良いでしょう。

typedef struct record record_t;

typedefを構造体定義と組み合わせることもできます。

typedef struct {
    char nam[32];
    double val;
} record_t;
于 2012-12-22T20:52:01.260 に答える