2017-04-05 11 views
1

値取得:メンバーに基づく構造体は、私は巨大な構造体配列を持っていると私はメンバーの値に基づいて、構造体のポインタを取得するためにさまざまな機能を作成し

typedef struct { 
    uint32_t a; 
    uint32_t b; 
    uint32_t c; 
    uint32_t d; 
} test_t; 

test_t test[10]; // Initialized somewhere else 

static test_t* __get_struct_by_a(uint_32_t a) { 
    for (uint32_t i = 0; i < 10; i++) { 
     if (test[i].a == a) 
      return &test[i]; 
    } 
    return NULL; 
} 

static test_t* __get_struct_by_b(uint_32_t b) { 
    ... 
} 

を代わりにCでこれに対処する簡単な方法はありますすべてのメンバーの参照機能を作成しますか?

答えて

0

以下は、最初に一致する構造体メンバを取得(検索)するための一般的な関数を記述する1つの方法です。

私はあなたがループインデックス用のハードコードされた値を使用しないようにTEST_SIZEのために必要があるかもしれないいくつかの#includeディレクティブ、および一般的な固定配列サイズ#defineを追加し、あなたのサンプルコードと一致しておくことを試みました。

#include <stddef.h> 
#include <stdio.h> 
#include <string.h> 

typedef struct { 
    uint32_t a; 
    uint32_t b; 
    uint32_t c; 
    uint32_t d; 
} test_t; 

test_t test[10]; // Initialized somewhere else 
#define TEST_SIZE (sizeof(test)/sizeof(test[0])) 

static test_t* __get_struct_by_offset(const void* value_ptr, const size_t offset, const size_t field_size) 
{ 
    for (uint32_t i = 0; i < TEST_SIZE; i++) 
    { 
     if (0 == memcmp(value_ptr, ((unsigned char*)&test[i])+offset, field_size)) 
     { 
      return &test[i]; 
     } 
    } 
    return NULL; 
} 

あなたはこのようにそれを使用します。

uint32_t a_value_to_find = 5; /* example field "a" value to find */ 
    uint32_t b_value_to_find = 10; /* example field "b" value to find */ 
    test_t* test_ptr; 

    /* find specified value for field "a" */ 
    test_ptr = __get_struct_by_offset(&a_value_to_find, offsetof(test_t, a), sizeof(a_value_to_find)); 

    /* find specified value for field "b" */ 
    test_ptr = __get_struct_by_offset(&b_value_to_find, offsetof(test_t, b), sizeof(b_value_to_find)); 

これは、指定されたoffset*value_ptrとフィールドのデータ型が同一であるので、同じサイズの(field_sizeことを確認するために、あなたの責任です)。

簡略化のために、これらの呼び出しの略語としていくつかのマクロを記述することができます。例: "a" および "b" の

#define GET_A(value) __get_struct_by_offset(&value, offsetof(test_t, a), sizeof(value)) 
#define GET_B(value) __get_struct_by_offset(&value, offsetof(test_t, b), sizeof(value)) 

クエリは、その後に単純化されています

/* find specified value for field "a" */ 
    test_ptr = GET_A(a_value_to_find); 

    /* find specified value for field "b" */ 
    test_ptr = GET_B(b_value_to_find); 
+0

おかげフィ​​ルこれはかなりきちんとしたソリューションです! –

関連する問題