ошибка компиляции, указатель на функцию - PullRequest
0 голосов
/ 28 августа 2018

У меня есть простая программа, подобная этой:

#include<stdio.h>

void add(int *nb)
{
    *nb += 1;
}

int f(int nb, void (*add)(int *))
{
    if (nb < 5)
        f(nb, add(&nb));
    return (nb);
}

int main() {
    int b = 5;
    int a = f(b, add);
    printf("%d\n", a);
}

Я хочу вызывать f рекурсивно, пока nb не станет больше или равно 5, но когда я компилирую программу, компилятор gcc покажет что-то вроде этого:

error: passing 'void' to parameter of incompatible type 'void (*)(int *)'

Может кто-нибудь помочь мне, пожалуйста?

Ответы [ 4 ]

0 голосов
/ 28 августа 2018

Как указал Кристиан в комментариях, проблема в рекурсивной линии вызова:

 f(nb, add(&nb));

Если я правильно понимаю, вы пытаетесь увеличить nb, используя функцию, которую вы получаете в качестве указателя; однако здесь вы сначала передаете nb без изменений (и как значение, а не по ссылке), а затем вызываете функцию добавления.

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

Кроме того, если nb <5, вам необходимо вернуть рекурсивный вызов. </p>

Правильная процедура будет:

#include<stdio.h>

void add(int *nb)
{
    *nb += 1;
}

int f(int nb, void (*add)(int *))
{
    if (nb < 5) {
        add(&nb);
        return f(nb, add);
    }
    return (nb);
}

int main() {
    int b = 1;
    int a = f(b, add);
    printf("%d\n", a);
}

Похоже, вы пытаетесь использовать ленивый анализ, но у C его нет!

0 голосов
/ 28 августа 2018

Передача add(&nb) в качестве аргумента передает возвращаемое значение из add с аргументом &nb. Сигнатура функции для f требует указатель функции, который можно передать как:

f(nb, add)

Кроме того, даже если вы действительно пытались передать возвращаемое значение add, это было бы неопределенным поведением, поскольку оно имеет тип void.

0 голосов
/ 28 августа 2018

Строка f(nb, add(&nb)); не имеет смысла. Вам нужно вызвать функцию где-нибудь, но не в той же строке, где вы передаете указатель функции, рекурсивно.

В целом программа не имеет особого смысла. Понятия не имею, что вы пытаетесь сделать, возможно, что-то похожее на это?

#include<stdio.h>

void add(int *nb)
{
    *nb += 1;
}

void f(int* nb, void (*add)(int *))
{
    add(nb);

    if (*nb < 5)
    {
        f(nb, add);
    }
}

int main() {
    int a = 5;
    f(&a, add);
    printf("%d\n", a);
}

Напечатает 6, так как add вызывается один раз. Имя add в качестве параметра функции для f также сильно сбивает с толку, поэтому лучше придумать другое имя для него.

0 голосов
/ 28 августа 2018

Я не совсем уверен относительно того, что вы пытаетесь сделать со своей функцией, но я попытался сделать то, что, по-вашему, вы пытаетесь сделать:

#include<stdio.h>

void add(int *nb)
{
    *nb += 1;
}

int f(int nb, void (*function)(int *))
{
    function(&nb);
    if (nb < 5)
        f(nb, function);
    return (nb);
}

int main() {
    int b = 5;
    int a = f(b, add);
    printf("%d\n", a);
}

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

То, что вы делали, передавало результат add(&nb) в функцию f в качестве аргумента (эта функция является пустым, поэтому она ничего не возвращает) вместо передачи указателя на функцию.

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