2015-08-27 3 views
1

Мне было предложено создать код, который будет переупорядочить 3 введенных целых числа в порядке возрастания/убывания с помощью указателей.Возврат указателя на ошибки функции

Мне нужно использовать функцию order(), чтобы вернуть указатель на любую функцию ascending3() или descending(), в зависимости от того, какое значение вводится «e».

Я продолжаю получать ошибку в строке, указанной в функции readInts(), и не знаю, как ее исправить.

ОШИБКИ

lvalue required as unary ‘&’ operand" -- The error for `ptr = &(order(e))` 

warning: assignment makes pointer from integer without a cast -- The error for `ptr=order(e)` 

Pointer код

void readInts(){ 

int *a,*b,*c; 
char e; 
int (*ptr1)(int*,int*,int*); 
int result; 

    printf("Enter Integer 1:"); 
    scanf("%d", a); 
    printf("Enter Integer 2:"); 
    scanf("%d", b); 
    printf("Enter Integer 3:"); 
    scanf("%d", c); 
    printf("Enter either A or D:"); 
    scanf(" %c", &e); 

    ptr1 = &(order(e));  /*ERROR HERE*/ 
    result = (*ptr1)(a,b,c); 

    printf("%d %d %d", a, b, c); 
    } 

Функции

int ascending3(int* x, int* y, int* z) 
{ 

/*removed sorting code for the sake of shortening the question*/ 

*x=smallest; 
*y=middle; 
*z=largest; 

} 

int descending(int* x, int* y, int* z) 
{ 
int swap; 

ascending3(x,y,z); 

swap=*x; 
*x=*z; 
*z=swap; 
} 

int (*order(char e))(int*x ,int*y,int*z) 
{ 

if(e=='a') 
{ 
    return ascending3; 
} 
else if(e =='d') 
{ 
    return descending; 
} 
return; 
} 
+0

Вы определяете или объявляете 'порядок' перед' readInts'? – Barmar

+1

Это должно быть 'ptr1 = order (e)', но функция 'order' должна быть объявлена ​​до того, как вы ее используете в' readInts'. – Barmar

+0

... и 'result = (* ptr1) (a, b, c);' должен быть просто 'result = ptr1 (a, b, c);'. – alk

ответ

0

функция не может возвращать п соборование. По этой причине вы не можете применить оператор address of (&) к результату вашей функции (для получения адреса). Но функция может возвращать указатель на функцию.

Имя функции в C (с префиксом или без оператора &) всегда задается как адрес функции, это указатель на эту функцию.

Правильный код:

int ascending3(int *x, int *y, int *z); 
int descending(int *x, int *y, int *z); 

typedef int (*fn)(int *x, int *y, int *z); 

fn order(char e) 
{ 

    if (e == 'a') 
    { 
     return ascending3; 
    } 
    else if (e == 'd') 
    { 
     return descending; 
    } 
    return NULL; 
} 

void readInts(void) 
{ 

    int *a, *b, *c; 
    char e; 
    fn ptr1; 
    int result; 

    printf("Enter Integer 1:"); 
    scanf("%d", a); 
    printf("Enter Integer 2:"); 
    scanf("%d", b); 
    printf("Enter Integer 3:"); 
    scanf("%d", c); 
    printf("Enter either A or D:"); 
    scanf(" %c", &e); 

    ptr1 = order(e); 
    result = (*ptr1) (a, b, c); 

    printf("%p %p %p", a, b, c); 
} 

Где я использовал typedef объявить тип нашей функции указателя (а также 2 прототипы функций заказа).

Если вы хотите иметь звездочку, чтобы лучше показать указатель характер нашего типа, вы можете определить fn как функции (а не указатель на функцию):

typedef int (fn)(int *x, int *y, int *z); 

Таким образом, вы можете использовать звездочку обозначения:

typedef int fn(int *x, int *y, int *z); 

fn *order(char e) 
{ 

    if (e == 'a') 
    { 
     return ascending3; 
    } 
    else if (e == 'd') 
    { 
     return descending; 
    } 
    return NULL; 
} 

void readInts(void) 
{ 

    int *a, *b, *c; 
    char e; 
    fn *ptr1; 
    int result; 

    printf("Enter Integer 1:"); 
    scanf("%d", a); 
    printf("Enter Integer 2:"); 
    scanf("%d", b); 
    printf("Enter Integer 3:"); 
    scanf("%d", c); 
    printf("Enter either A or D:"); 
    scanf(" %c", &e); 

    ptr1 = order(e); 
    result = (*ptr1) (a, b, c); 

    printf("%p %p %p", a, b, c); 
} 
+0

'(fn)' in 'typedef int (fn) (int * x, int * y, int * z);' просто может быть 'fn'. Короткие: круглые скобки вокруг 'fn' бесполезны. – alk

+0

Я чувствую эту формулировку «* Только потому, что вы никогда не сможете вернуть функцию (откуда бы получить адрес) от функции, но вы можете обмениваться указателем на функцию. *« Тихое неясно. – alk

+0

@alk Нет скобок в скобках, из копии/прошлого '(* fn)' и я забыл удалить его. Я исправил ответ и, возможно, сделал его более ясным. –

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