2016-03-19 17 views
0

Ich versuche, ein albernes kleines Programm zu schreiben, und ich habe in eine Wand gerannt. Der betreffende Code ist hier:Ich habe Probleme mit Arrays von Funktionszeigern in C

double(*operf[NOPERS])() = {addf,subf,mulf,divf} 

Was ich auch als

double(*operf[NOPERS])(double,double) = {addf,subf,mulf,divf} 

Wenn ich das Programm in Haupt laufen, mit printf("%f\n", (*operf[0])(2,3)); gemacht habe, habe ich das erwartete Ergebnis erhalten (5), aber wenn Ich rufe es von einem anderen Ort an, ich bekomme ein Gobletygook. Ich weiß, dass das in C möglich ist und ich weiß nicht, was ich falsch mache. Ich habe mir alle anderen Antworten ernsthaft angesehen und sie scheinen genau das zu tun, was ich mache.

EDIT: Hier ist der Code in Frage. Ich wollte Sie nicht alle im Code ertränken, also ging ich irgendwie den umgekehrten Weg, haha.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
// #include <math.h> 

#define SE(X,Y) (strcmp(X,Y)==0) 

#define STACKSIZE 1024 
double snums[STACKSIZE]; 
int snums_ctr=0; 
int sopers[STACKSIZE]; 
int sopers_ctr=0; 

#define Push(STACK, DATA) STACK[STACK##_ctr++]=DATA 
#define Peek(STACK) STACK[STACK##_ctr-1] 
#define Pop(STACK) STACK[--STACK##_ctr] 

#define ABF(NYM,DEF) double NYM (a,b){ return DEF ; } 
ABF(addf,a+b); 
ABF(subf,a-b); 
ABF(mulf,a*b); 
ABF(divf,a/b); 
//ABF(pwrf,pow(a,b)); 

int indexOf(char**ss,char*s) { 
    int i=0; 
    while(*ss){ 
     if(SE(*ss,s)) { 
      return i; 
     } 
     i++;ss=&ss[1]; 
    } 
    return -1; 
} 

#define NOPERS 5 

int operp[NOPERS] = {1,1,2,2,3}; 
int operprec[NOPERS] = {0,0,0,0,1}; 
char* opers[NOPERS+1] = {"+","-","*","/","**"}; 
char* cs(char* s) { 
    int n=strlen(s); 
    char*r=malloc(n+1); 
    memcpy(r,s,n+1); 
    return r; 
} 

char* gs(int n) { 
    char c = getchar(); 
    char*r; 
    if(c=='\n'){ 
     c=0; 
     r=malloc(n+1); 
    } 
    else{ 
     r=gs(n+1); 
    } 
    r[n]=c; 
    return r; 
} 
typedef double(*oper_f)(); 

void rpn(oper_f* operf) { 
    printf("Entering RPN mode...\n"); 
    while(1) { 
     char* raw = gs(0); 
     int idx = indexOf(opers, raw); 
     if(idx != -1) { 
      double b = Pop(snums); 
      double a = Pop(snums); 
      double c = (*operf[idx])(b,a); 

      printf("%f %s %f = %f %f\n", a,raw,b,(float)(double)c, addf(2,2)); 
      Push(snums, c); 
     } 
     else { 
      Push(snums, atof(raw)); 
     } 
     free(raw); 
    } 
} 


int main() { 
// operf[4] = &pwrf; 
    oper_f operf[NOPERS] = {&addf,&subf,&mulf,&divf,NULL}; 
    printf("%f\n", (*operf[0])(2,3)); 
    printf("MODE? "); 
    char* mode = gs(0); 
    if(SE(mode,"rpn")||1) { 
     rpn(operf); 
    } 
    free(mode); 
} 
+2

Ohne eine [mcve] ist es schwer, irgendeine Hilfe anzubieten. –

+1

Könnten Sie den Code veröffentlichen oder zumindest erklären, wo Sie das Array von Zeigern deklarieren und wie es an die Funktion übergeben wird, die es aufruft? Es ist schwer, ohne einen minimalen Kontext zu helfen. –

+1

Alle Warnungen zur Kompilierzeit? – dasblinkenlight

Antwort

0

Beispiel für Array von funcs:

int f() { 
    return 1; 
} 

int g() { 
    return 2; 
} 

typedef int (*PFUNC)(); 

int main() { 
    PFUNC pf[2] = {&f, &g}; 
    pf[0](); // return 1 
} 
+0

Ich habe es gerade versucht. Aus irgendeinem Grund hat es überhaupt nicht funktioniert. Wenn es hilft, wenn ich versuche, das Array außerhalb von Main zu initialisieren, bekomme ich einen Fehler "nicht berechenbar bei Ladezeit", aber das sollte es nicht beeinflussen, wenn ich in main initialisiere. –

+0

Was meinst du mit "hat nicht funktioniert"? Hat es nicht kompiliert? Was ist dein System und Compiler? – rlib

+0

Linux Mint 17,3, GCC, Standard-Zeug. Die Ausgabe, die ich bekam, war '2.000000 + 3.000000 = 20655140.000000' bei einem Beispiellauf. –

0

Die Art und Weise, dass ich dies normalerweise tun ist:

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

typedef float (*math_op)(float, float); 

float addf(float f1, float f2) { return (f1 + f2);} 
float multf(float f1, float f2) { return (f1 * f2);} 
float divf(float f1, float f2) { return (f2 != 0 ? f1/f2 : NAN);} 
float subf(float f1, float f2) { return (f1 - f2);} 

int main(void) 
{ 
    math_op opsf[] = {addf, multf, divf, subf}; 

    printf("sum of 1.0 and 3.5 is %f\n", opsf[0](1.0, 3.5)); 

    return 0; 
} 

Der obige Code kompiliert sauber auf Windows 7 mit gcc-4.8.3 Verwenden der Befehlszeile gcc -std=c99 -pedantic -Wall temp.c -o temp. Und geben Sie die folgende Ausgabe:

Q:\>gcc -std=c99 -pedantic -Wall temp.c -o temp 
Q:\>temp.exe 
sum of 1.0 and 3.5 is 4.500000 
Q:\> 

Wenn Sie immer noch Probleme haben, geben Sie bitte das System und Compiler Sie verwenden, sowie eine Kopie des Codes.

1

Okay, ich habe es herausgefunden. Es war ein wirklich dummer Fehler. Ich tippte:

#define ABF(NYM,DEF) double NYM (a,b){ return DEF ; } 

Wenn ich

eingegeben haben sollte
#define ABF(NYM,DEF) double NYM (double a,double b){ return DEF ; } 

Hinzufügen std=99 wie vorgeschlagen hat mir geholfen, dieses Problem zu diagnostizieren. Ich denke, ich brauche Schlaf.

+1

Gut zu wissen, dass Sie es reparieren konnten !! –

Verwandte Themen