Thread: Possible to create methods for data in structs?

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    35

    Possible to create methods for data in structs?

    Hi there,
    I am rather new to C, and I am having a bit of trouble finding information on this thing that I want to do (damn google is good - but it's a shame that the creator of C didn't know about it when he named the language after a letter of the alphabet!)

    Basically, I have a struct that looks like:

    Code:
    typedef struct {
            constpart * electrons;
            double energy;
            double weight ;
            double potential;
            double kinetic;
            char dead;
    } diffuser;
    and I want to define a method to call on the diffuser object (sorry about this object oriented lingo, I realise that a struct isn't really an object...) that might look like:

    Code:
    void zeroEnergy(void)
    {
            potential = 0.0;
            kinetic = 0.0;
            energy = 0.0;
    }
    is this possible?
    I have been searching around for info, and it does seem like it's do-able. Unfortunately my C book doesn't cover unions, and all the websites I have encountered do lots of things with pre-processor directives (and if anyone could point me to a good book on that topic, and on properly structuring programs by properly allocating the various bits of code between header files and program files then I'd be most grateful) - but the websites give examples that are a little hard to follow and one even included a header that I don't have! (oocp.h or something)...

    Any ideas?

    many thanks in advance
    James


    *edit*
    oh I should probably clarify - RE the title.
    I called this post what I did because I thought it would mean people might understand what I wanted to achieve functionality-wise... i know that structs are not objects and so cannot have 'methods' (i guess)... but I figured people might see the functionality I wanted and tell me the C way of doing it... thanks!
    Last edited by eccles; 12-10-2004 at 11:32 PM.
    VIM + gcc + beer... does life get any better?

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    void zeroEnergy(diffuser *d)
    {
            d->potential = 0.0;
            d->kinetic = 0.0;
            d->energy = 0.0;
    }
    ???

    [edit]unedit
    Last edited by Dave_Sinkula; 12-10-2004 at 11:35 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    well of course I could do that... but... I had hoped that there might be a way to package the function up into the struct as part of its definition, so it could be called like:
    Code:
    diffuser walker;
    walker.zeroEnergy();
    or is this just one of those 'well why don't you just go LIVE in java!' questions?
    VIM + gcc + beer... does life get any better?

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    typedef struct tag_diffuser
    {
       //constpart * electrons;
       double energy;
       double weight ;
       double potential;
       double kinetic;
       char dead;
       void (*foo)(struct tag_diffuser *this);
    } diffuser;
    
    void zeroEnergy(struct tag_diffuser *this)
    {
       this->potential = 0.0;
       this->kinetic = 0.0;
       this->energy = 0.0;
    }
    
    int main(void)
    {
       diffuser diff;
       diff.foo = zeroEnergy;
       diff.foo(&diff);
       return 0;
    }
    ???
    Last edited by Dave_Sinkula; 12-10-2004 at 11:37 PM. Reason: Posted reply instead of previous edit.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    C doesn't support that sort of construct (but C++ does ). just use:

    Code:
    void zeroEnergy(diffuser * this)
    {
            this->potential = 0.0;
            this->kinetic = 0.0;
            this->energy = 0.0;
    }
    [edit]
    beat me to it
    [/edit]
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    ooh thankyou I didn't expect a reply this fast!

    to turn your example around a bit, would this be possible?:
    Code:
    typedef struct tag_diffuser
    {
       //constpart * electrons;
       double energy;
       double weight ;
       double potential;
       double kinetic;
       char dead;
       void (*zeroEnergy)(struct tag_diffuser *this);
    } diffuser;
    
    void ze(struct tag_diffuser *this)
    {
       this->potential = 0.0;
       this->kinetic = 0.0;
       this->energy = 0.0;
    }
    diff.zeroEnergy = ze;
    
    int main(void)
    {
       diffuser diff;
       diff.zeroEnergy(&diff);
       return 0;
    }
    ???

    and do i need to explicity pass a reference to the object or is there another way?
    (I realise that's how you've defined the function, but is there a way to do it that circumvents that requirement?)
    VIM + gcc + beer... does life get any better?

  7. #7
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    C doesn't support that sort of construct (but C++ does )
    ok in that case my next question must be (and as you may have gathered from some of the variable names that this is a scientific computing application, and one that does not scale well with system size (ie number of particles in the molecular system)): are there any performance hits i'd take if i converted it to a C++ application? and would this be the way to go? or is C smaller, faster and sweeter?

    as i understand it, C++ is a superset of C, so would I just be able to use the OOP style stuff where I wanted it but keep the rest of it pretty much just C?

    are there arguments against this type of thing given the nature of the program?
    VIM + gcc + beer... does life get any better?

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    typedef struct tag_diffuser
    {
       void (*foo)(struct tag_diffuser *this);
       //constpart * electrons;
       double energy;
       double weight ;
       double potential;
       double kinetic;
       char dead;
    } diffuser;
    
    void zeroEnergy(struct tag_diffuser *this)
    {
       this->potential = 0.0;
       this->kinetic = 0.0;
       this->energy = 0.0;
    }
    
    int main(void)
    {
       diffuser diff = {zeroEnergy};
       diff.foo(&diff);
       return 0;
    }
    ???

    [edit]

    >and do i need to explicity pass a reference?

    Yes.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    out of interest Dave, why did you comment out 'constpart * electrons' ?
    it's just a pointer to an array of constpart structs...

    something like:
    Code:
    typedef struct {
            evector r;        // another struct that just holds an x,y,z value
            double energy;
             ...
    } constpart;
    VIM + gcc + beer... does life get any better?

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by eccles
    are there any performance hits i'd take if i converted it to a C++ application? and would this be the way to go? or is C smaller, faster and sweeter?
    Maybe, maybe not. *sorry*
    Quote Originally Posted by eccles
    as i understand it, C++ is a superset of C
    In some ways, yes.
    Quote Originally Posted by eccles
    so would I just be able to use the OOP style stuff where I wanted it but keep the rest of it pretty much just C?
    Use the tool that best fits the problem.
    Quote Originally Posted by eccles
    are there arguments against this type of thing given the nature of the program?
    Hmmm. Get correct results first. Optimize second.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by eccles
    out of interest Dave, why did you comment out 'constpart * electrons' ?
    These data definitions were not present. [edit]I like to double-check my posts with a compiler and linter first if I can.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    ahh fair enough (re the commenting out of constpart * electrons)
    I have only found this board in the last few days (mainly because I have only been learning C the last few days/week) - so just as an aside - if you post code in which some components are of unknown lineage (hehe) - is that bad form? because i just assumed that people would not really take any notice of that particular declaration because they'd assume that 'constpart' was another struct... was that a bad assumption? (for future reference when posting)

    <edit>
    ahhh well that makes sense then ( I had posted this before your edit)
    ... so i guess that's probably common form amoungst those who wish to gaurantee the integrity of their information... so would a rule of thumb be to provide either the whole code or at least a self consistent (no references to missing/non-standard code) example so that people can do that?
    </edit>
    Last edited by eccles; 12-10-2004 at 11:58 PM.
    VIM + gcc + beer... does life get any better?

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >if you post code in which some components are of unknown lineage (hehe) - is that bad form?

    It may be overlooked when the real issue is more general. But the best way to the best answer(s) for a specific question is to post the minimal compilable code that demonstrates the problem.
    Last edited by Dave_Sinkula; 12-11-2004 at 12:01 AM. Reason: Made 'answer' 'answer(s)'.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    Registered User
    Join Date
    Dec 2004
    Posts
    35
    ahh cheers, that makes perfect sense.

    so there is no way to fiddle with this to make it work?:

    Code:
    typedef struct {
            double energy1;
            double energy2;
            void zeroEnergy(void)
             {
                    energy1 = 0.0;
                    energy2 = 0.0;
             }
    } diffuser;
    
    int main(void)
    {
            diffuser walker;
            walker.zeroEnergy();
    }
    ?

    <edit>
    the reason I am asking is because I'd rather do:
    Code:
    walker.zeroEnergy();
    than
    Code:
    zeroEnergy( walker );
    but anything that is more complex than the latter means that i'd rather just go with the latter. (and by complex, I mean that by doing the former i'd be simplifying the code - to save me doing
    Code:
    walker.potential = 0.0;
    walker.kinetic = 0.0;
    walker.energy = 0.0;
    so it'd be kinda pointless if my initial attempt to simplify ended up resulting in more complex code than was there originally...

    and it's just for the exact same reasons that one might perfer to say:
    Code:
    car.putKeyInIgnition()
    than
    Code:
    putkeyInIgnition( car );
    it just makes a lot more sense...

    </edit>
    Last edited by eccles; 12-11-2004 at 12:12 AM.
    VIM + gcc + beer... does life get any better?

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >so there is no way to fiddle with this to make it work?:

    In C you could be incredibly versed in the language and mess around with preprocessor directives and file scope variables ("globals") in some way to maybe jerk it into submission.

    Or in C++ you could use what you had.

    [edit]By the way, this
    Code:
       diffuser diff = {zeroEnergy};
    zeroed out those variables.
    Last edited by Dave_Sinkula; 12-11-2004 at 12:12 AM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multidimentional structs + memcpy() == FAIL
    By Viper187 in forum C Programming
    Replies: 8
    Last Post: 06-18-2008, 02:46 AM
  2. Turn Based Stradegy System Methods
    By TylerMoyer in forum Game Programming
    Replies: 2
    Last Post: 07-30-2007, 10:45 PM
  3. How to create a file association program?
    By eShain in forum Windows Programming
    Replies: 1
    Last Post: 03-06-2006, 12:15 PM
  4. Cannot create MDI Client Win
    By JaWiB in forum Windows Programming
    Replies: 1
    Last Post: 10-31-2005, 10:05 PM
  5. Methods for Sorting Structures by Element...
    By Sebastiani in forum C Programming
    Replies: 9
    Last Post: 09-14-2001, 12:59 PM