Thread: creating a function with class objects

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    45

    creating a function with class objects

    I'm trying to make a function that involves other functions from classes. What it's ultimately supposed to do is check to see whether or not a hand (arr[]) has a flush. I understand there is probably a better algorithm to do this, but this works fine for what I'm trying to do. My problem is that the function is supposed to increment the float "f" each time it recognizes a flush, but my output always ends up being 0.
    getSuit is a function in a class Card, and arr[] is an array of type Card. I've never written a function using the dot operator so I really have no idea if I even wrote this correctly.

    Code:
    void checkFlush (Card arr[], float f) {
        if (arr[0].getSuit() == arr[1].getSuit() &&    
            arr[0].getSuit() == arr[2].getSuit() &&
            arr[0].getSuit() == arr[3].getSuit() &&
            arr[0].getSuit() == arr[4].getSuit())
            f++;
    }
    Thanks for any feedback!
    -Ryan

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Arguments are passed by value to functions, so changes to them are local to the function (not visible to the caller).

    If you want changes to an argument to be visible to the caller, either pass a reference or a pointer. Then, inside the function, change whatever the pointer points at, or whatever the reference references.


    I fail to see the point of using a float for counting.

    In terms of the algorithm, try using a loop.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Mar 2012
    Posts
    45
    I figured out I was using the wrong type for the function prototype, so now I have this...

    Code:
    void checkFlush (Card::Suit arr[5], int f) {
        if (arr[0] == arr[1] &&    
            arr[0] == arr[2] &&
            arr[0] == arr[3] &&
            arr[0] == arr[4])
            f++;
    }
    I was using a float for counting because later in the program I need to divide by that variable, and dividing by integers is usually inconsistent, isn't it?
    This code works now, but when I use it in main() I have this:

    Code:
    checkFlush (handSuit, flush);
    and flush always ends up not incrementing like it should be. I tried testing to see whether it was incrementing in the function by outputting "f" and that worked, so I'm guessing my problem is outside the function?

    EDIT: Just something else to note, if I use this code in main() (not as a function) and replace "f" with "flush" it works fine...
    Last edited by ryanmcclure4; 09-15-2012 at 12:34 PM.

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You have a fundamental misunderstanding of how arguments are passed to functions. Only the VALUE of flush is passed to checkFlush, i.e., f gets a COPY of flush's value. Changing f in checkFlush therefore won't change flush in main.

    To let a function change the value of a variable in the caller, you can pass it "by reference" by changing the function declaration like this:

    Code:
    void checkFlush (Card::Suit arr[5], int &f)
    The call in main stays the same.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> EDIT: Just something else to note, if I use this code in main() (not as a function) and replace "f" with "flush" it works fine..

    "flush" must be a global variable or something then, there is no other explanation for why that could work.

    You should listen to grumpy. Something like this:

    void checkFlush(Card::Suit arr[5], int &f);

    or

    int checkFlush(Card::Suit arr[5]);

    would work.


    And dividing by integer is very consistent - the result is truncated so that there is no fractional part. If you aren't doing dividing, it doesn't make much of a difference anyway, does it?

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    45
    Thanks guys, void checkFlush(CArd::Suit arr[5], int &f); did the trick. I've been reading up on pointers for the last few hours but I guess it's just not clicking. I learned about them in C and remember they come too easily for me then either...I understand the basics of how they work but always have trouble trying to use them and apply them to my code.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by ryanmcclure4 View Post
    I was using a float for counting because later in the program I need to divide by that variable, and dividing by integers is usually inconsistent, isn't it?
    Dividing by integers is not "inconsistent". It is performed as an integer operation, so the result is an integer, which means rounding. [There are particular cases, with older standards and older compilers, where the result of integer division is undefined, but that is also not "inconsistent").

    So if an integer x has value 2 and integer y has value 3, the operation z=x/y will consistently give the result zero, not 0.66667, even if z is of type float. If you really care about the fractional result, then force the compiler to convert to floating point before doing the division. z = (float)x/y will not perform the rounding.

    But that behaviour is not inconsistency.

    Even if such behaviour is considered a bad thing, using float/double types is not always a good fix, because float/double types are an approximation of real values, not actual real values. Try to represent the fraction 1/5 in a finite number of binary places to see why .... you will find that it cannot be done, in exactly the same way that the fraction 2/3 cannot be represented using a finite number of decimal places (0.66666.... <ad infinitum>)
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    OK, you really have to think about this.

    You have a VOID function that returns a value as a parameter. This is nonsense. The idea of this function is to return a value, so return it:
    Code:
    int checkFlush (Card::Suit arr[5]) 
    {
        int f = 0;
        if (arr[0] == arr[1] &&   
            arr[0] == arr[2] &&
            arr[0] == arr[3] &&
            arr[0] == arr[4])
                f = 1;
        return f;
    }
    This essentially returns 0 or FALSE if the hand is not a flush.
    It returns 1 or TRUE if the hand is a flush.

    When you get to checkPair(), the return value can be the number of pairs found. Keep in mind that three of a kind should not be considered in the pair testing, otherwise you get 3 pairs...
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-24-2011, 06:36 PM
  2. Replies: 3
    Last Post: 07-15-2010, 07:53 PM
  3. Replies: 4
    Last Post: 10-16-2003, 11:26 AM
  4. base class pointer to derived class objects
    By curlious in forum C++ Programming
    Replies: 4
    Last Post: 09-28-2003, 08:39 PM
  5. creating objects
    By Bilo in forum C++ Programming
    Replies: 3
    Last Post: 02-04-2003, 04:37 AM