【问题标题】:Why function pointer isn't seen as point to function?为什么函数指针不被视为指向函数?
【发布时间】:2019-08-27 17:03:40
【问题描述】:

无法通过函数指针访问函数。

我正在编写一个基于美国和欧盟标准输入(身体质量指数计算器)的程序。 我的观点是使用一个函数“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;
}

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

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

【问题讨论】:

  • 欢迎来到 Stack Overflow。请edit您的问题包含整个错误消息。还要指出是哪一行导致了错误。
  • 最后,制作您的代码示例,以便我们可以编译它并得到相同的错误。特别是,添加main() 和所有必要的变量声明。
  • float (*calcMethod)(float , float) = &amp;calcEU; } 变量在} 之后停止存在。
  • 您在两个不同的 if 块内声明和初始化两个不同的 calcMethod 变量。当您在显示的代码中调用它时,这两个声明都不在范围内。如果您声明一个 calcMethod 变量(在第一个 if 语句之上)并在每个 if 语句中分配给设计值,那么它应该可以工作。
  • 与您的主要问题无关,但是:如果您想要来自用户的 2 个字母的响应,请不要声明一个大小为 2 的数组来保存它,甚至更多重要的是,永远不要使用gets() 阅读它! (1) 保存长度为 2 的字符串所需的大小是 3。 (2) 使用刚好大到足以容纳预期字符串的数组容易出错且毫无意义,因为它不会阻止用户尝试键入更长的东西。 (3) gets 函数具有病态危险,已从 C 语言标准中删除,不应使用。

标签: c function function-pointers


【解决方案1】:

问题在于你声明了float *calcMethod;——一个指向浮点数的指针,而不是一个指向函数的指针。然后你在你的内部块中将它重新声明为一个函数指针,但这只是在那些块中——你试图调用它的地方就是你试图调用浮点指针。

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

float (*calcMethod)(float, float);

那么当你决定使用哪个时,不要重新声明它,只需分配它:

calcMethod = calcUS;

calcMethod = calcEU;

你也不需要* 来通过指针调用——你可以直接使用

BMIndex = calcMethod(massRow , heightColumn);

【讨论】:

  • 谢谢,帮了大忙。
【解决方案2】:

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

如果您只将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;
}

【讨论】:

    【解决方案3】:

    主要问题是您在嵌套块中声明了不同的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);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多