время выполнения определяет тип для C - PullRequest
4 голосов
/ 15 января 2010

Если тип переменной должен быть определен как среда выполнения в C, но имя переменной фиксировано и задано, есть ли способ повторно использовать код, который включает переменную?

На самом деле я спрашиваю о ситуации с аналогом C тип определения времени выполнения для C ++ .

Если возможно, приведите несколько примеров.

Ответы [ 2 ]

7 голосов
/ 15 января 2010

Язык C не имеет объектно-ориентированных функций, которые позволяют задать вопрос о типе объекта во время выполнения в C ++.

Обычно вы реализуете универсальность в C путем приведения к и из void*. Пример: функция C qsort .

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

1 голос
/ 29 мая 2012

Одна стандартная методика - предоставить быструю переменную типа информации в качестве параметра. и включите это, и передайте все данные по ссылке. внутри функции мы восстанавливаем значение с явным приведением. Тип void * не проверяется компилятором, поэтому существует опасность отправки типа, который не обрабатывается функцией (ошибка сегментации, повреждение данных или неизвестный результат поведения). Для начала настройте перечисление нужных вам типов:

В этом случае я использую соглашение TYPE_FUNCTION для представления функции, возвращающей тип.

Директива enum выбирает последовательные целые числа от 0, или вы можете назначить каждому перечислению свое собственное значение типа int.

typedef enum D_types { 
ANINT, // don't use actual system type names
AFLOAT, 
ADOUBLE, 
ASTRING, 
MY_STRUCT=100, 
MY_STRUCT2=200 
VOID_FUNCTION=1000,   
INT_FUNCTION = 2000,
STRUCT_FUNCTION=3000 
} DATATYPE; 

/*  an f_int is a function pointer to a function */
typedef int (*f_int)(int, void* ); 

В своем определении функции вы отправляете как данные по ссылке, так и тип и приведите его к правильному типу перед использованием:

int myfunction ( DATATYPE dt, void* data,  )
{ 
  int an_int = 0;
  int * ip;  // typed pointers for casting of the void pointer data 
  double * dp;
  char * sp;
  struct My_struct * msp;
  struct My_struct_2 * ms2p;
  f_int  fp;  
  ...

  switch  (dt){
    case ANINT:
       ip = (int*) data; // only pointers can be assigned void pointer values. 
       int i = *ip       // dereference of typed pointer, no dereferencing void pointers.
       ...
       break;
    case ADOUBLE:
       dp = (double*) data;
       double d = *dp;
       ...
       break;
    case ASTRING:
       char * s = strdup( (char*) data);   // cast to char pointer allowed (pointer->pointer)
       ...
       break;
     case MY_STRUCT:
       msp = ( struct My_Struct *) data;  
       char* ms_name = msp->name;   // if my_struct has a name string ...
       float dollarvalue = msp->dvalue; 
       ...
     case INT_FUNCTION:
       fp = (f_int)data;
       an_int = fp( ANINT, 5); 
    }
return an_int;
}

Как вы можете догадаться, это игра со спичками на фабрике фейерверков, и не поощряется как постоянная практика.

в вашем коде вы бы назвали это так:

double pi =3.14159; 
int g = myfunction( ADOUBLE, &pi  ); // pass by reference, not value   

int j = myfunction (ASTRING , "HEY NOW" );  //C strings pass by ref normally



f_int myfunc = myfunction;   // a function pointer (ref to the functions address )

int r = myfunction ( INT_FUNCTION, myfunc );  /* function as a parameter ... */

за исключением одноразовой функции Рекомендуется использовать функции Varargs http://www.eskimo.com/~scs/cclass/int/sx11b.html

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