2015-11-19 3 views
0

Предположим, у меня есть функция, которая принимает эти параметры.Вызов функционального указателя (синтаксиса)

int create(Ptr * p,void * (*insert)(void *, void *)) { 

//return something later 
} 

И структура:

typedef struct { 
void ** ptr; 
void * (*insert)(void *, void *)); 
}Ptr; 

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

Как бы я мог вызвать функцию create здесь?

Я знаю, что могу сделать что-то вдоль линий этого для первого параметра:

// в отдельном файле .c

Ptr * pt; 
pt = malloc(sizeof(Ptr)); 

create(pt,....what to put here)? 

Если бы я хотел, чтобы передать указатель структуры в качестве аргумента , и целое число, которое нужно вставить вторые (опять же они оба являются указателями void, потому что это общая сборка).

+0

Я думаю, что дизайн является неправильным. Вы должны определить функцию 'insert' и не должны передавать ее в качестве аргумента функции' create' (так как я полагаю, вам не нужно иметь отдельную функцию 'insert' для каждого узла в дереве). – CristiFati

ответ

1

Внутри этой функции, вы можете написать любой из:

insert(vp1, vp2); 

или:

(*insert)(vp1, vp2); 

где я предполагаю:

void *vp1 = …; 
void *vp2 = …; 

Вторая форма, которая была необходимо до стандарта C89/C90; вы найдете таких старых, как я, до сих пор предпочитаю это. Первый стандарт, так как была опубликована первая версия стандарта, но вы должны посмотреть на список аргументов функции, чтобы найти, что insert является указателем на функцию вместо имени функции. Вот почему я все еще предпочитаю старые обозначения.

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

extern void *insert_int(void *vp1, void *vp2); 

if (create(pt, insert_int) != 0) 
    …handle error… 
+0

Спасибо, также я не уверен, что бы я сделал с этими аргументами, когда-то перешел в create? Мне сказали сохранить их адрес, так как эта функция используется только для инициализации дерева. – TopKek

+0

Есть элемент «Я не знаю, что вы хотите с ними делать». Мне непонятно, что указано для вашей функции 'create()', потому что это то, что она должна делать. Не имея перед собой всей домашней работы, я не могу сказать вам, что вы должны делать. Есть много способов написания кода - некоторые из них хороши, многие из них плохие, почти все они нашли где-то на SO. Я не знаю, что вы планируете делать с членом 'void ** ptr;' вашей структуры. Я бы пробежал милю от этого. Может быть, вы просто скопируете аргумент 'insert' над членом' insert'? –

+0

Это тем более, что я не копировал весь код, чтобы уменьшить избыточность между прочим. Таким образом, параметры функции создания не полностью представлены, и ни одно из них не является полем структур. – TopKek

0

согласно определению создать ...

void* mine(void* x, void* y) 
{ 
    return NULL 
} 

create(pt, mine); 

и создать будет

int create(Ptr * p,void * (*insert)(void *, void *)) { 
    p->insert = insert; 
} 

Я бы с ума сходил ч функция, чтобы сделать вызов, а

void* ptr_insert(Ptr* p, void* a, void* b) 
{ 
    if(p!=NULL && p->insert != NULL) return p->insert(a,b); 
    return NULL; 
} 
0

Некоторые компилируемый пример использования:

typedef struct { 
    void ** ptr; 
    void * (*insert)(void *, void *); 
} Ptr; 
int create(Ptr * p,void * (*insert)(void *, void *)); 

void* Insert(void*, void*); 

void fun(){ 
    Ptr ptr; 
    Ptr * pt = &ptr; 

    //Function name decays to its addresss 
    create(pt, &Insert); 
    create(pt, Insert); //the same thing 

    //Declare a pointer 
    void* (*ins)(void*, void*); 
    //Assing to it 
    ins = &Insert; 
    //Same thing 
    ins = Insert; 

    //Invocation via pointer 
    void* ret = (*ins)(pt, pt); 

    //Same thing 
    ret = ins(pt, pt); 

    //Passs the pointer 
    create(pt, ins); 
} 
Смежные вопросы