Question:
functions in structs in C (only C)?
Natan
2011-12-27 18:49:20 UTC
Hello everyone.
I am having a hard time compiling this C code.
Basically what happens is:
-it does compile but when I run it (on Terminal) it prints me:Illegal instruction
-I tried to debug it and on Xcode and when it attempts to execute (*fraction).print() it says: EXC_BAD_ACCESS
-if I delete the (*fraction).print() line everything works fine (same happens if I only delete the next line)
This code drove me crazy for a whole afternoon so a little help would be really appreciated.
Thankyou.



#include
#include "string.h"
#include "stdio.h"

typedef struct
{




int numerator;
int denominator;
void (*print)(); // prints on screen "numerator/denominator"
float (*convertToNum)(); //returns value of numerator/denominator
void (*setNumerator)(int n);
void (*setDenominator)(int d);




} Fraction;

Fraction* allocFraction(Fraction* fraction); //creates an uninitialized fraction
void deleteFraction(Fraction *fraction);





Fraction* allocFraction(Fraction* fraction)
{
void print()
{
int a= 10;
printf("%i/%i", (*fraction).numerator, (*fraction).denominator);
a--;
}


float convertToNum()
{
return (float)(*fraction).numerator/(float)(*fraction).denominator;

}


void setNumerator (int n)
{
(*fraction).numerator= n;

}

void setDenominator (int d)
{
(*fraction).denominator= d;

}




if(fraction== NULL) fraction= (Fraction*) malloc(sizeof(Fraction));


if(fraction)
{
(*fraction).convertToNum= convertToNum;
(*fraction).print= print;
(*fraction).setNumerator= setNumerator;
(*fraction).setDenominator= setDenominator;
}

return fraction;
}


void deleteFraction(Fraction *fraction)
{
free(fraction);
}






int main (int argc, const char * argv[])
{
Fraction *fraction= allocFraction(fraction);
(*fraction).setNumerator(4);
(*fraction).setDenominator(7);
(*fraction).print(); //EXC_BAD_ACCESS on debug. Illegal instruction in Terminal
printf("%f", (*fraction).convertToNum());
(*fraction).print();

deleteFraction(fraction);
return 0;
}
Four answers:
cja
2011-12-28 05:51:26 UTC
It's interesting to try to add some object orientation to C. As you've seen, you don't quite have it set up correctly. See below for the fixes I made to get this to compile and run. I've removed the problematic nested functions, since my compiler doesn't support that, and I don't think it's necessary. I also changed your print function to toStr. I think that's a better design.



#include

#include

#include



#define MAX_FRAC_STR_LEN 64



typedef struct Fraction {

    int numerator;

    int denominator;

    const char *(*toStr)(struct Fraction *this);

    float (*convertToNum)(struct Fraction *this);

    void (*setNumerator)(struct Fraction *this, int n);

    void (*setDenominator)(struct Fraction *this, int d);

} Fraction;



float convertToNum(Fraction *this) {

    return (float)this->numerator/(float)this->denominator;

}



void setNumerator (Fraction *this, int n) {

    this->numerator = n;

}



void setDenominator (Fraction *this, int d) {

    this->denominator = d;

}



const char *toStr(Fraction *this) {

    static char fracStr[MAX_FRAC_STR_LEN];



    sprintf(fracStr, "%i/%i", this->numerator, this->denominator);

    return fracStr;

}



Fraction* allocFraction() {

    Fraction *this = (Fraction*)malloc(sizeof(Fraction));



    assert(this != NULL);

    this->convertToNum = convertToNum;

    this->toStr = toStr;

    this->setNumerator = setNumerator;

    this->setDenominator = setDenominator;

    return this;

}



void deleteFraction(Fraction *fraction) {

    free(fraction);

}



int main (int argc, const char * argv[]) {

    Fraction *fraction = allocFraction();



    (*fraction).setNumerator(fraction, 4);

    (*fraction).setDenominator(fraction, 7);

    printf("%s = %f\n", fraction->toStr(fraction), (*fraction).convertToNum(fraction));

                                           

    deleteFraction(fraction);



    return 0;

}



#if 0



Program output:



4/7 = 0.571429



#endif
Cubbi
2011-12-27 19:51:32 UTC
This part:



Fraction* allocFraction(Fraction* fraction)

{

     void print()

     {



is not C. There are no nested functions in C. If your compiler accepts this program, it's using some other programming language, which looks like some sort of OOP-extended variant of C.



In C, this program would be something like:



#include

#include



typedef struct

{

     int numerator;

     int denominator;

} Fraction;



void print(Fraction *fraction)

{

     if(fraction)

         printf("%i/%i\n", fraction->numerator, fraction->denominator);

}



float convertToNum(Fraction *fraction)

{

     if(fraction)

         return (float)fraction->numerator / fraction->denominator;

     else

         return 0;

}



void setNumerator (Fraction *fraction, int n)

{

     if(fraction)

         fraction->numerator = n;

}



void setDenominator(Fraction *fraction, int d)

{

     if(fraction)

         fraction->denominator = d;

}



Fraction* allocFraction(void)

{

     return malloc(sizeof(Fraction));

}



void deleteFraction(Fraction *fraction)

{

     free(fraction);

}



int main ()

{

     Fraction *fraction = allocFraction();

     setNumerator(fraction, 4);

     setDenominator(fraction, 7);

     print(fraction);

     printf("%f\n", convertToNum(fraction));

     print(fraction);

     deleteFraction(fraction);

}

demo: http://ideone.com/NyHSU
2016-11-15 04:52:26 UTC
contain /* do no longer use "this", it incredibly is a key-word in c++ */ struct try { int it; int (*getIt)(try*); /* additionally won't be able to specify var names here */ }; int Test_getIt(try* self) { return self->it; } int significant() { struct try t; t.getIt = Test_getIt; t.it = a million; printf("%in", t.getIt(&t)); }
2011-12-27 19:51:56 UTC
Are you rebelling against c++?

Are you trying to use nested functions? I had never tried that, and I don't think that should compile.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...