Thread: Help with a small problem (beginner)

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Help with a small problem (beginner)

    Hello,

    I just recently started to learn C and i have a small question.
    I wanted to use Flags to send to a function, but so far i havent been able to get them to work.

    I have created a small command program in VS 2008. The only thing it prints out is Red, what am i missing?

    Code:
    #include "stdafx.h"
    
    #define RED		0001
    #define BLUE		0010
    #define GREEN		0011
    #define BLACK		0000
    #define YELLOW		0100
    
    void PrintData(char);
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int res;
    
    	PrintData(RED | BLUE);
    
    
    	scanf("%d", &res);
    	return 0;
    }
    
    void PrintData(char mask)
    {
    	if ((RED & mask) == 1)
    		printf("Red is used.\n");
    	if ((BLUE & mask) == 1)
    		printf("Blue is used.\n");
    	if ((GREEN & mask) == 1)
    		printf("Green is used.\n");
    	if ((BLACK & mask) == 1)
    		printf("Black is used.\n");
    	if ((YELLOW & mask) == 1)
    		printf("Yellow is used.\n");
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    	(RED & mask)
    What is that supposed to result in?
    And what about
    Code:
    	(BLUE & mask)
    Do you really want Yellow to be the value 64 decimal, or do you believe that your colour selections are in BINARY and you actually got 4 decimal?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I just recently started to learn C and i have a small question.
    This is the C++ programming forum. Shall I move this thread to the C programming forum?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    This is the C++ programming forum. Shall I move this thread to the C programming forum?
    -Yes

    Do you really want Yellow to be the value 64 decimal, or do you believe that your colour selections are in BINARY and you actually got 4 decimal?
    -I want to make it into binary or hex, so the Decimal value would be 4.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by piffo View Post
    -Yes


    -I want to make it into binary or hex, so the Decimal value would be 4.
    In which case you can use one of the following:
    Code:
    #define YELLOW 4
    #define YELLOW (1 << 2)
    #define YELLOW 04
    #define YELLOW 0x04
    What you have with
    Code:
    #define YELLOW 0100
    is an octal number - base 8 - so you get 1 * 8 * 8 = 64 decimal.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    Quote Originally Posted by matsp View Post
    In which case you can use one of the following:
    Code:
    #define YELLOW 4
    #define YELLOW (1 << 2)
    #define YELLOW 04
    #define YELLOW 0x04
    What you have with
    Code:
    #define YELLOW 0100
    is an octal number - base 8 - so you get 1 * 8 * 8 = 64 decimal.

    --
    Mats
    But i still cant manage to compare it against the defined variables and use it as flags

    Code:
    #define RED			0x01
    #define BLUE		0x02
    #define GREEN		0x03
    #define BLACK		0x00
    #define YELLOW		0x05
    
    void PrintData(char);
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int res;
    
    	PrintData(RED | BLUE);
    
    
    	scanf("%d", &res);
    	return 0;
    }
    
    void PrintData(char mask)
    {
    	if ((RED & mask) == 1)
    		printf("Red is used.\n");
    	if ((BLUE & mask) == 1)
    		printf("Blue is used.\n");
    	if ((GREEN & mask) == 1)
    		printf("Green is used.\n");
    	if ((BLACK & mask) == 1)
    		printf("Black is used.\n");
    	if ((YELLOW & mask) == 1)
    		printf("Yellow is used.\n");
    }
    I want to check using binary, ex. 00000101. Then i have red declared as Decimal 1, if it excists inside the binary stirng, i want it to print, red is used. Then it should check if the 2nd digit in the binary string is used, if so, print Blue is used. etc.

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Code:
    if ((RED & mask) == 1)
    if ((BLUE & mask) == 1)
    if ((GREEN & mask) == 1)
    if ((BLACK & mask) == 1)
    if ((YELLOW & mask) == 1)
    Only two of those comparisons will ever possibly evaluate to true: RED and GREEN. If you pass RED into the function, I'll bet it prints RED and GREEN. You need to reconsider your comparison strategy there (after you fix the accidental octal notation you used).

    What you are doing (in binary):
    Code:
        0001 (red)
    OR  0010 (blue)
        ----
        0011 (green)
    
    so 'mask' == 0011
    
        0011 (mask)
    AND 0011 (green)
        ----
        0011
    
    so (GREEN & mask) == 0011
    
    What are you comparing it against....??

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Your binary values, when used in the context you are describing, needs to have unique bit combinations, such as:
    Code:
    #define RED   0x01
    #define GREEN 0x02
    #define BLUE  0x04
    As it stands, your GREEN & RED != 0.

    And to use that in the way you do now, you can either use:
    Code:
    if (val & BLUE)
    or
    Code:
    if (!!(val & BLUE) == 1)
    The if(!!x == 1) is a simple way of writing ((x != 0) == 1).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    Quote Originally Posted by arpsmack View Post
    Code:
    if ((RED & mask) == 1)
    if ((BLUE & mask) == 1)
    if ((GREEN & mask) == 1)
    if ((BLACK & mask) == 1)
    if ((YELLOW & mask) == 1)
    Only two of those comparisons will ever possibly evaluate to true: RED and GREEN. If you pass RED into the function, I'll bet it prints RED and GREEN. You need to reconsider your comparison strategy there (after you fix the accidental octal notation you used).

    What you are doing (in binary):
    Code:
        0001 (red)
    OR  0010 (blue)
        ----
        0011 (green)
    
    so 'mask' == 0011
    
        0011 (mask)
    AND 0011 (green)
        ----
        0011
    
    so (GREEN & mask) == 0011
    
    What are you comparing it against....??
    Ahh i see what you mean. What i tried to accomplish was, when using your code:
    Code:
    PrintData(RED | BLUE);
    This would return  "0011"
    
    
        0011 (flag)
    &  0001 (red)
        ----
        0001
    
    or ((flag & RED) == 1)
    To see if the red bit in the flag is set to 1
    
    simliar with
    
        0011 (flag)
    &  0010 (blue)
        ----
        0010
    
    or ((flag & BLUE) == 1)
    To see if the blue bit in the flag is set to 1

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You may benefit from doing this:
    Code:
    #define PRINT(x, y) printf(#x " ((&#37;d) & " #y " (%d) == 1) = %d\n", x, y, x & y, (x & y) == 1)
    PRINT(RED|BLUE, BLUE);
    PRINT(RED, RED);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    Quote Originally Posted by matsp View Post
    You may benefit from doing this:
    Code:
    #define PRINT(x, y) printf(#x " ((%d) & " #y " (%d) == 1) = %d\n", x, y, x & y, (x & y) == 1)
    PRINT(RED|BLUE, BLUE);
    PRINT(RED, RED);
    --
    Mats
    Problem is, it dosent solve what i am trying to accomplish.
    It dosent matter to me if the decimal value is 3 or 5, i am only after if the bit in that location is turned on or off.

    0101
    what i want to check is, if bit "1" is set to 1, print Red is used. If bit "2" is set to 1, print Blue is used. If bit "3" is set to 1, print Green is used. If bit "4" is set to 1, print Yellow is used.

    So from the above binary string i would get the following output:
    Red is used.
    Green is used.

    That way, i can send in alot of constants to the program and i only have to have one parameter that accepts it. So instead of writing a function:

    void func1 (bool RED, bool BLUE, bool GREEN etc);

    i can write:

    void func1 (char colorstouse);

    Then just call it with the flags that i need:

    func1(RED | BLUE | GREEN | YELLOW);

    instead of

    func1(true, false, true, false, false etc);

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by piffo View Post
    Problem is, it dosent solve what i am trying to accomplish.
    It dosent matter to me if the decimal value is 3 or 5, i am only after if the bit in that location is turned on or off.

    0101
    what i want to check is, if bit "1" is set to 1, print Red is used. If bit "2" is set to 1, print Blue is used. If bit "3" is set to 1, print Green is used. If bit "4" is set to 1, print Yellow is used.

    So from the above binary string i would get the following output:
    Red is used.
    Green is used.

    That way, i can send in alot of constants to the program and i only have to have one parameter that accepts it. So instead of writing a function:

    void func1 (bool RED, bool BLUE, bool GREEN etc);

    i can write:

    void func1 (char colorstouse);

    Then just call it with the flags that i need:

    func1(RED | BLUE | GREEN | YELLOW);

    instead of

    func1(true, false, true, false, false etc);
    You can't test that the result of the & equals one, since it might equal two, or four, or eight, or whichever bit you're looking at. You just need to test that it's nonzero: if (colorstouse & RED). And if you plan to do that, you need to make sure that there are no overlaps in the bits, which is why you use powers-of-two.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You are trying to use the individual bits of a parameter to determine what the information passed is.
    But you must also know then, that we're working on a binary level, not octal or decimal or hexdecimal.
    You should know that the binary OR operator adds together bits and that the binary AND operator selects out bits.
    For example: 0000 1111 | 1111 0000 = 1111 1111
    0000 1111 & 0000 1000 = 0000 1000
    0000 1111 & 0001 0000 = 0000 0000

    Since we can't directly write numbers in binary format, you have to convert them to decimal or hexdecimal. Use a calculator for that (Windows calc supports this in scientific mode).
    I quickly find out that:
    0000 0001 = 0x1
    0000 0010 = 0x2
    0000 0100 = 0x4
    0000 1000 = 0x8
    0001 0000 = 0x10
    0010 0000 = 0x20
    0100 0000 = 0x40
    1000 0000 = 0x80

    If, for whatever reason, you cannot figure out how to do it from this information, then you need to re-read how binary operators works.

    You may also want to use an enum if you only need ONE flag at a time.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And in post #8, I _DID_ suggest a solution to that problem (in fact two different solutions). Perhaps re-reading that post, and asking further questions if unclear, is a good idea.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 03-09-2006, 12:06 PM
  2. Small Problem in C, Please Help.
    By DoctorFu in forum C Programming
    Replies: 6
    Last Post: 10-31-2005, 03:06 PM
  3. Small program big problem :-(
    By Fibre Optic in forum C++ Programming
    Replies: 4
    Last Post: 09-20-2005, 08:53 AM
  4. Need Big Solution For Small Problem
    By GrNxxDaY in forum C++ Programming
    Replies: 8
    Last Post: 08-01-2002, 03:23 AM