2013-12-17 3 views
1

Есть ли способ сделать что-то вроде этого:?Отправлять номер/символ/строку в void * function

void set(void* data, void *value, t_flags type) 
{ 
    if (type & INT) 
     *(int*)data = *(int*)value; 
    if (type & UINT) 
    (...) 
} 

int i; 
set(&i, 42, INT); 

Мои набор функций работает, но я не знаю, как назвать его с номером, символ «», или строку «».

Редактировать: Я забыл последний аргумент, но проблема исходит из аргумента 42.

+2

Вы передаете только две аргументы функции 'set'. – haccks

+1

Попробуйте 'int i = 42;'. –

+2

Хотя в вашей реализации нет ничего принципиально неправильного, вы просто копируете менее мощный «memcpy» - я рекомендую вам использовать это вместо этого. '#define set (data, value) memcpy (data, value, sizeof (value))' –

ответ

3

Несколько вещей. Во-первых, поскольку вы используете void* (что подходит) для value, вам необходимо передать void* в качестве второго аргумента вместо константы. Это будет работать, чтобы скопировать одну переменную в другую, но есть более эффективные способы.

Во-вторых, обратите внимание, что для передачи строки вам нужно передать указатель на указатель char, и char * будет установлен функцией. (Это зависит от вас, является ли это «мягкой копией» или «твердой копией», то есть указывает ли указатель на то же место в памяти или на другую копию той же строки. Вы сказали, что у вас есть set, так что я предполагаю, у вас уже есть это так, как вы хотите.

вы не включили в свой t_flags перечисление, так что я угадал соответствующие значения.

char c = 'c'; 
char* str = "str"; 
int i = 42; 
char c2; 
char* str2; 
char i2; 

set(&c2, &c, CHAR); /* presumably you have a CHAR flag? */ 
set(&str2, &str, CHARPTR); /* presumably you have a CHARPTR flag? */ 
set(&i2, &i, INT); 

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

c2 = c; 
str2 = str; 
i2 = i; 

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

+0

+1: Отличная точка, требующая передачи значений по адресу, а не по значению. –

+0

Я пытаюсь перепроверить вектор из C++ и единственный способ, которым я не мог написать одну функцию для каждого типа, - void *. Я ожидал, что C имеет трюк, чтобы делать то, что я хочу, но, похоже, мне нужно использовать временную переменную. – mantal

+1

В C++ жизнь проще, потому что у вас есть шаблоны. Возможно, но не вполне вероятно, что вы можете сделать то же самое с помощью макросов. Вы искали «c vector»? Я видел по крайней мере два хита, которые могут вам пригодиться - либо учиться, либо использовать (в зависимости от каких-либо ограничений по лицензированию, конечно): http://stackoverflow.com/questions/4694401/how-to- replicate-vector-in-c https://gist.github.com/EmilHernvall/953968 (второй использует указатели void, но кажется немного более развитым, чем ваш образец.) –

0

Может быть, вы хотите:

void set(void* data, void *value, t_flags type) 
{ 
    if (type & INT) 
     *(int*)data = *(int*)value; 
    if (type & UINT) 
     *(unsigned int*)data = *(unsigned int*)value; 
    if (type & STRING) 
     strcpy((char*)data, (char*)value); 
    ... 
} 

int i; 
char string[100] ; 
set(&i, 42, 1<<INT); 
set(string, "Hello world", 1<<STRING) ; 

Но это странно, так или иначе.

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