2014-01-10 2 views
0

У меня есть что-то вроде этогоВозможно ли изменение типа указателя во время выполнения? (C программирования)

void my_very_large_function(void){ 
    struct A *sA; 
    < a lot of references to *sA structure in many many lines > 
} 

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

void my_very_large_function(int type){ 
    struct A *sA; 
    struct B *sB; 
    if(type == 0) // I dont want this because there are too many references 
     <use *sA> 
    else 
     <use *sB> 
} 

Есть ли способ установить тип указателя в начале функции?

Использование указателей void не является удовлетворительным, потому что мне придется бросать каждый раз, когда я его использую, а также нужно будет проверить аргумент, чтобы решить, как отличать (от A или до B).

void my_very_large_function(int type){ 
    struct A *sA; 
    struct B *sB; 
    void *ptr; 
    if(type == 0) 
     ptr = (struct A *) *sA; // is there a way in C to make this cast permanent? I think not 
    else 
     ptr = (struct B *) *sB; 
    < now use just ptr > 
} 

Я думаю, что я мог бы использовать союз, если одна структура будет вложено в начале другого, но структуры не похожи

+1

Если структуры не похожи, как это вообще будет работать в первую очередь? Или вы имеете в виду, что у вас есть одноименные поля, только в разных местах? – tabstop

+0

Пожалуйста, объясните гораздо больше, что делает 'my_very_large_function', и * почему это так велико !!!! Разве вы не можете разбить его на более мелкие (возможно, встроенные) функции? Что такое «struct A» и «struct B» конкретно? Какая связь между ними ??? Покажите гораздо больше кода, пожалуйста! –

+0

Возможно, какое-то использование 'void *'? – zoska

ответ

0

В C это не представляется возможным. В C++ вы можете сделать это с помощью шаблонов, все равно будет беспорядок. Причина, по которой это невозможно в C, состоит в том, что во время компиляции должны быть известны все смещения структурных элементов .

Пример:

struct A { 
    int a; 
    int b; 
}; 

struct B { 
    int b; 
    int a; 
}; 

несовместимы быть обменены, даже если вы можете скомпилировать функцию либо. Ваш единственный способ собрать две функции по одному для каждого типа:

void my_very_large_function_A(); 
void my_very_large_function_B(); 

void my_very_large_function(int type){ 
    if(type == 0) 
     my_very_large_function_A(); 
    else 
     my_very_large_function_B(); 
} 

Вы можете сделать это полуавтоматическое с макросов препроцессора:

my_very_large_function.c:

#ifdef structtype 
void NAME(my_very_large_function, structtype)() { 
    struct structtype *my_struct; 
    // whatever it does 
} 
#endif 

main.c:

#define PASTER(x,y) x ## _ ## y 
#define EVALUATOR(x,y) PASTER(x,y) 
#define NAME(fun, type) EVALUATOR(fun, type) 

#define structtype A 
#include <my_very_large_function.c> 
#define structtype B 
#include <my_very_large_function.c> 


void my_very_large_function(int type){ 
    if(type == 0) 
     my_very_large_function_A(); 
    else 
     my_very_large_function_B(); 
} 
+0

Это то, что я делаю, разделить на две разные функции. спасибо Сергею за ответ, очень полный и полезный (я не могу голосовать, так как пока у меня недостаточно репутации!). – kernival

+0

@ user206551, вы можете, конечно, принять ответ на свой вопрос. – vonbrand

Смежные вопросы