Одиночный указатель, указывающий на две разные таблицы структуры const (таблицы поиска) в c - PullRequest
0 голосов
/ 12 декабря 2011

У меня есть две разные структуры и две таблицы поиска const, как показано ниже

typedef const struct 
{
    unsigned int  num;
    unsigned char name[100];
    unsigned int value1;
    unsigned int value2;
    unsigned int value3;
}st_Table1;

typedef const struct
{
    unsigned int  num;
    unsigned char name[100];
}st_Table2;

st_Table1 stTable1[] =
{
    { 1, "Name1", 12, 13, 14 },
    { 2, "Name2", 22, 23, 24 },
    { 3, "Name3", 32, 33, 34 },
    { 4, "Name4", 42, 43, 44 }
};



st_Table2 stTable2[] =
    { 1, "India1" },
    { 2, "India2" },
    { 3, "India3" }
};

Возможно ли иметь единственный указатель, который может указывать на таблицы поиска stTable1 и stTable2?

Когда мне нужно принять решение о выборе любой из двух таблиц, мы можем назначить адрес таблицы (любой из).

Но после этого я хотел использовать один указательв оставшемся коде.

Пожалуйста, ответьте для любой логики ... подсказка ... подсказка

Арвинд

Ответы [ 5 ]

0 голосов
/ 13 декабря 2011

Вы можете получить тот же эффект, что и приведения, которые другие предложили с союзом.

union table_ptr {
   st_Table1*table1;
   st_Table2*table2;
} my_table_ptr;

и просто назначьте / получите доступ к нужному члену.

0 голосов
/ 12 декабря 2011

Это невозможно.Указатель должен знать свой собственный диапазон для правильного чтения и записи во время выполнения, иначе вы ничего не можете с этим поделать.Если вы не знаете, является ли это table1 или table2, как вы можете написать код для его чтения?(какой тип value в value = *pointer;?) С другой стороны, если вы знаете, что это таблица1 / таблица2, почему бы не использовать указатель определенного типа?

ИЛИ (еслиВы настаиваете)

Просто используйте st_Table1 как st_Table2 и принимайте трату памяти (3 * sizeof (без знака int) для каждой записи).Это не будет большой тратой, если у вас не будет миллиардов записей.Вы не хотите хранить миллиарды записей данных по структуре C.

ИЛИ (ну, вы ненавидите отходы)

typedef struct
{
    int num;
    char name[100];
    int *value;
}st_table;

хорошо, у вас есть унифицированныйструктурировать сейчас.Выделите value во время выполнения, если вам это нужно (value = (int *)malloc(3 * sizeof(int));).Не забудьте проверить NULL, прежде чем читать value.

0 голосов
/ 12 декабря 2011

Вы можете создать пустой указатель:

void * ptr;

Как и любой другой указатель, он может указывать на любой адрес памяти, но не указывает, какой тип данных там хранится, поэтому вы можете разыменовать его, но вам придется зависеть от ваших собственных знаний структур для доступа к различным элементам и т. д. Если у вас есть какой-то другой флаг, указывающий, на какой тип записи он указывает, вы можете привести его обратно к требуемому типу указателя.

Учитывая, что обе ваши структуры имеют общую почву, вам лучше использовать первую и принять небольшие накладные расходы на память для случаев, когда вам нужны только num и name. Я ненавижу раздувание программного обеспечения и потерянную память, но вы говорите о дополнительных 12 байтах (на большинстве платформ) для записей, в которых value1-3 не нужны, поэтому, если мы не говорим о миллиардах записей, скорее всего, дополнительный код необходим для сделка с большим количеством будет занимать больше памяти, чем потраченное впустую пространство.

Другим вариантом может быть объединение, когда вы теряете 12 байтов из name для записей второго типа, так что все записи занимают одинаковое количество места, хотя, конечно, заполнение компилятора может иметь значение на некоторых платформах.

0 голосов
/ 12 декабря 2011

Возможно, вы захотите следовать шаблону, аналогичному семейству структур sockaddr. В этой настройке все структуры должны иметь одинаковый размер и одинаковую начальную компоновку, например:

typedef const struct
{
    unsigned int  num;
    unsigned char name[100];
    char buffer_[sizeof(unsigned int) * 3];
} st_TableBase;

typedef const struct 
{
    unsigned int  num;
    unsigned char name[100];
    unsigned int value1;
    unsigned int value2;
    unsigned int value3;
} st_Table1;

typedef const struct
{
    unsigned int  num;
    unsigned char name[100];
    char buffer_[sizeof(unsigned int) * 3];
} st_Table2;

При такой структуре вы обычно поддерживаете указатель типа st_TableBase. С помощью этого указателя вы сможете напрямую получить доступ к элементам num или name, поскольку все типы имеют согласованную начальную компоновку. Если вам нужно получить доступ к дополнительным полям, вы можете привести st_TableBase к одному из «производных» типов.

Для получения дополнительной информации о sockaddr структурах см. http://www.retran.com/beej/sockaddr_inman.html.

0 голосов
/ 12 декабря 2011

хорошо, вы можете создать структуру

typedef struct _tableChoice 
{
  st_Table1* table1;
  st_Table2* table2;

} tableChoice_t,*p_tableChoice_t;

, затем вы можете передать аргумент типа p_tableChoice_t, пока вам не понадобится специальный доступ к одной из таблиц.Если вам нужно решить во время выполнения, какой указатель использовать, вам нужно иметь оба указателя в точке принятия решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...