为什么不能将函数指针视为指向函数的指针?

时间:2019-08-27 17:03:40

标签: c function function-pointers

无法通过函数指针进入函数。

我正在编写一个程序,该程序基于用于美国和欧盟标准的输入(身体质量指数计算器)。 我的观点是使用一个函数“ calcMethod”来计算BMIndex,但是尝试将其他函数的指针分配给该函数,则会导致错误“被称为对象不是函数或函数指针”。任何帮助表示赞赏。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

float calcEU(float inputMass, float inputHeight)
{
    float BMIndexF;
    BMIndexF = inputMass / (inputHeight * inputHeight);
    return BMIndexF;
}

float calcUS(float inputMass, float inputHeight)
{
    float BMIndexF;
    BMIndexF = 703 * inputMass / (inputHeight * inputHeight);
    return BMIndexF;
}

int main()
{
    float BMIndex , inputMass , inputHeight;
    float heightColumn, massRow;
    float *calcMethod ;
    int Mod = 0;
    int countRow , countColumn;
    char unitStandard[2] , metricUnitH[2] , metricUnitM[2];

    printf("Your measure units? EU (kg, m) or US (lb, in) \n");
    gets(unitStandard);

    if(strcmp(unitStandard, "EU") == 0)
    {
        Mod = 1;
        strcpy(metricUnitH, "me");
        strcpy(metricUnitM, "kg");
        float (*calcMethod)(float , float) = &calcEU;
    }
        else if (strcmp(unitStandard, "US") == 0)
        {
            Mod = -1;
            strcpy(metricUnitH, "in");
            strcpy(metricUnitM, "lb");
            float (*calcMethod)(float , float) = &calcUS;
        }
            else
            {
                printf("Wrong Input");
                exit(-1);
            }

    printf("Introduce your body mass:\n");
    scanf("%f", &inputMass);

    printf("Introduce your height:\n");
    scanf("%f", &inputHeight);

    printf("\n");

    for(countRow = 0; countRow <= 5; countRow++)
    {
        for(countColumn = 0; countColumn <= 5; countColumn++)
        {
            heightColumn = inputHeight - 0.1 * (3 - countRow);
            massRow = inputMass - 1 * (3 - countColumn);

            if(countRow == 0 && countColumn == 0)  printf("H / M|");
            if(countRow == 0 && countColumn != 0)  printf("%.0f%s |", massRow , metricUnitM);
            if(countColumn == 0 && countRow != 0)  printf("%.1f%s |", heightColumn , metricUnitH);

            if(countRow != 0 && countColumn !=0)
            {
                //this line causes error
                BMIndex = (*calcMethod)(massRow , heightColumn);
                printf("%.2f |", BMIndex);
            }



        }

        printf("\n");
    }


    return 0;
}

注释行导致错误:被调用对象不是函数或函数指针

期望它不会引发错误并按预期工作。

3 个答案:

答案 0 :(得分:2)

问题是您声明了float *calcMethod;-指向浮点数的指针,而不是指向函数的指针。然后,您可以在内部块中将其重新声明为函数指针,但这仅是在这些块中-您尝试在其中调用它是在尝试调用浮点指针。

解决方法是首先将其声明为函数指针:

float (*calcMethod)(float, float);

然后,当您决定使用哪个时,不要重新声明它,只需分配它即可:

calcMethod = calcUS;

calcMethod = calcEU;

您也不需要*来通过指针进行调用-您只需使用

BMIndex = calcMethod(massRow , heightColumn);

答案 1 :(得分:1)

您在calcMethod函数中有三个main()变量。第一个是一个指向float变量的指针(显然不是函数指针)。另外两个是函数指针,但是它们仅存在于其代码块之内。

如果仅将calcMethod定义为一个函数指针,则无论代码中是否存在其他错误,都可以使用。

这是三个变化:

int main()
{
    float BMIndex , inputMass , inputHeight;
    float heightColumn, massRow;
    float (*calcMethod)(float , float); // ****** CHANGE #1 HERE
    int Mod = 0;
    int countRow , countColumn;
    char unitStandard[2] , metricUnitH[2] , metricUnitM[2];

    printf("Your measure units? EU (kg, m) or US (lb, in) \n");
    gets(unitStandard);

    if(strcmp(unitStandard, "EU") == 0)
    {
        Mod = 1;
        strcpy(metricUnitH, "me");
        strcpy(metricUnitM, "kg");
        calcMethod = &calcEU; // ****** CHANGE #2 HERE
    }
        else if (strcmp(unitStandard, "US") == 0)
        {
            Mod = -1;
            strcpy(metricUnitH, "in");
            strcpy(metricUnitM, "lb");
            calcMethod = calcUS; // ****** CHANGE #3 HERE
        }
            else
            {
                printf("Wrong Input");
                exit(-1);
            }

    printf("Introduce your body mass:\n");
    scanf("%f", &inputMass);

    printf("Introduce your height:\n");
    scanf("%f", &inputHeight);

    printf("\n");

    for(countRow = 0; countRow <= 5; countRow++)
    {
        for(countColumn = 0; countColumn <= 5; countColumn++)
        {
            heightColumn = inputHeight - 0.1 * (3 - countRow);
            massRow = inputMass - 1 * (3 - countColumn);

            if(countRow == 0 && countColumn == 0)  printf("H / M|");
            if(countRow == 0 && countColumn != 0)  printf("%.0f%s |", massRow , metricUnitM);
            if(countColumn == 0 && countRow != 0)  printf("%.1f%s |", heightColumn , metricUnitH);

            if(countRow != 0 && countColumn !=0)
            {
                BMIndex = (*calcMethod)(massRow , heightColumn);
                printf("%.2f |", BMIndex);
            }
        }
        printf("\n");
    }

    return 0;
}

答案 2 :(得分:0)

主要问题是您在嵌套块中声明了不同的calcMethod变量,并更改了错误的变量。另外,您尝试调用的外部calcMethod变量甚至都不是函数指针:

float *calcMethod ;

//assigning the pointer to function
//this subprogram is nested in main
if(Mod == 1) //Mod is just a variable
    {
        strcpy(metricUnitH, "me");
        strcpy(metricUnitM, "kg");

        // N.B. This is a different calcMethod variable!
        float (*calcMethod)(float , float) = &calcEU;
    } // N.B. calcMethod variable in previous block no longer exists!

if(Mod == -1)
    {
        strcpy(metricUnitH, "in");
        strcpy(metricUnitM, "lb");

        // N.B. This is a different calcMethod variable!
        float (*calcMethod)(float , float) = &calcUS;
    } // N.B. calcMethod variable in previous block no longer exists!

//the calcMethod is called
//this is nested in 2 for(s) and an if

// N.B. the calcMethod variable in this block is uninitialized, and
// it is not even a function pointer (it is a pointer to float) so
// this will not even compile....
BMIndex = (*calcMethod)(massRow , heightColumn);

解决方案是将外部calcMethod变量声明为函数指针,并更改内部块以将其分配给外部块的calcMethod变量,而不是声明一个新变量:

float (*calcMethod)(float, float) = calcUS;  // default to "US"

//assigning the pointer to function
//this subprogram is nested in main
if(Mod == 1) //Mod is just a variable
    {
        strcpy(metricUnitH, "me");
        strcpy(metricUnitM, "kg");
        calcMethod = calcEU;
    }
if(Mod == -1)
    {
        strcpy(metricUnitH, "in");
        strcpy(metricUnitM, "lb");
        calcMethod = calcUS;
    }

//the calcMethod is called
//this is nested in 2 for(s) and an if
BMIndex = (*calcMethod)(massRow , heightColumn);

calcMethod语句之一未设置的情况下,我将calcUS初始化为if。或者,您可以将其初始化为NULL并在调用calcMethod之前检查是否为错误情况:

float (*calcMethod)(float, float) = NULL; // default to not set

// ...

if (calcMethod == NULL)
    {
        /* ERROR: calcMethod hasn't been set. */
        /* DO SOMETHING! */
    }
else
    {
        BMIndex = (*calcMethod)(massRow , heightColumn);
    }