C语言错误:‘Called error is not a function or function pointer’排查
解决函数积分程序中的函数指针错误问题
兄弟,你遇到的错误根源其实是把函数调用和函数指针传递搞混了,咱们一步步拆解问题,然后给你修正方案:
问题分析
首先看你main函数里switch的错误行:
integrate((&pf)(x,y));- 你这里的写法是试图调用
pf指向的函数(还用了未初始化的x,y当参数,这本身就有问题),然后把函数返回的float值传给integrate。但integrate需要的是一个函数指针,不是具体的数值,所以会报“参数类型不兼容”的错误。 - 而且
(&pf)完全没必要,pf本身就是函数指针变量,直接用它就行。
- 你这里的写法是试图调用
其次,
integrate函数的参数定义虽然C语言会隐式把float pf(float x,float y)转换成函数指针,但写成明确的函数指针类型会更清晰,避免后续混淆:void integrate(float (*pf)(float, float))
修正步骤
1. 修正main函数的switch调用
把所有case里的integrate((&pf)(x,y));改成integrate(pf);,直接传递函数指针变量即可。
2. 明确integrate函数的参数类型
把integrate的参数定义从float pf(float x,float y)改成float (*pf)(float, float),让代码意图更明确。
3. 额外小问题修正
- 你在
integrate里定义的float x[i],y[j];是变长数组(VLA),如果你的编译器不支持C99标准,可能会报错。我改成了动态分配内存,避免兼容性问题。 - 循环终止条件里用了
abs,这是整数的绝对值函数,应该换成fabs用于浮点数比较。 - main里的
x,y变量是未初始化的,修正后已经不需要了,直接删掉。
修正后的完整代码
main.c
#include <stdio.h> #include <math.h> #include <stdlib.h> // 用于malloc/free #include "integrand.h" #define M 64 #define N 64 #define dif 0.01 #define max 8 // 明确函数指针参数类型 void integrate(float (*pf)(float, float)){ int i,j,k=0,l=1; float a,b,c,d,dx,dy,dA,r=0,r_old; float *x, *y; // 动态数组指针 printf("Enter the integration bounds a,b,c,d separated by commas: \n\n"); scanf("%f,%f,%f,%f",&a,&b,&c,&d); do{ r_old = r; dx = (b - a)/(l*M); dy = (d - c)/(l*N); dA = dx * dy; // 动态分配内存 x = malloc(sizeof(float) * (l*M - 1)); y = malloc(sizeof(float) * (l*N - 1)); if(!x || !y){ printf("Memory allocation failed!\n"); return; } for(i=0;i<(l*M)-1;i++){ x[i] = a + (i + 0.5)*dx; } for(j=0;j<(l*N)-1;j++){ y[j] = c + (j + 0.5)*dy; } for(i=0;i<(l*M)-1;i++){ for(j=0;j<(l*N)-1;j++){ r += ((*pf)(x[i],y[j]))*dA; } } // 释放动态分配的内存 free(x); free(y); k++; l*=2; }while(k<max || fabs(r-r_old)<=dif*fabs(r)); // 用fabs处理浮点数绝对值 printf("Integral = %f\n",r); return; } int main(void) { int q; float (*pf)(float,float); // 函数指针变量 printf("Choose an integrand:\n\n (1) f_1(x,y) = x^3 + 3y^2*x + 7x^2*y + 10 \n\n (2) f_2(x,y) = cos(0.1*x^5 + y^2) - sin(y*x)^5 + log(|x-y|+1) + 2 \n\n (3) f_3(x,y) = sin(x^2+y^2) + exp(-50*(x^2+y^2))\n\n (4) f_4(x,y) = f_3(f_1(x,y),f_2(x,y))\n\n (5) QUIT \n\n"); do{ scanf("%d",&q); switch(q){ case 1: pf = f_1; integrate(pf); break; case 2: pf = f_2; integrate(pf); break; case 3: pf = f_3; integrate(pf); break; case 4: pf = f_4; integrate(pf); break; case 5: break; default: printf("Invalid choice, try again!\n"); } }while(q!=5); return 0; }
integrand.c
#include <math.h> #include <stdio.h> // 用于fabs float f_1(float x, float y){ return (pow(x,3) + 3*pow(y,2)*x + 7*pow(x,2)*y + 10); } float f_2(float x, float y){ return (cos(0.1*pow(x,5)+pow(y,2)) - pow(sin(y*x),5) + log(fabs(x-y)+1) + 2); } float f_3(float x, float y){ return (sin(pow(x,2)+pow(y,2)) + exp(-50*(pow(x,2)+pow(y,2)))); } float f_4(float x, float y){ return (f_3(f_1(x,y),f_2(x,y))); }
integrand.h
#ifndef INTEGRAND_H #define INTEGRAND_H extern float f_1(float x, float y); extern float f_2(float x, float y); extern float f_3(float x, float y); extern float f_4(float x, float y); #endif // INTEGRAND_H
编译运行提示
编译的时候记得链接数学库,比如用gcc:
gcc main.c integrand.c -o integral -lm
然后运行./integral即可。
内容的提问来源于stack exchange,提问作者pavus
相关产品推荐
相关产品推荐

