Thread: argument testing

  1. #1
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463

    argument testing

    Code:
    struct person{/*struct*/};
    struct bullet{/*struct*/};
    
    bullet fire_bullet(person);
    
    bullet fire_bullet(gunner)
    {
     if(gunner=="player") {do stuff};
     /*function*/
    }
    
    main()
    {
     person player;
     bullet attack;
    
     attack=fire_bullet(player);
     return 0;
    }
    I have a struct for players, and a struct for bullets, and a function for firing bullets. I want to do something different if it is the player firing the bullet as opposed to an enemy. Would it be a legal test to see if the gunner argument equaled "player"?

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Why not just use a flag?
    Code:
    struct person {
      /* Blah blah */
      int npc; /* 1=nonplayer character, 0=player */
    };
    That way you don't have to work with strings.

    >if(gunner=="player") {do stuff};
    You can't compare strings like this. Well, you can...but it doesn't work like you think it does.
    My best code is written with the delete key.

  3. #3
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    you can't tease me like that! How does it really work?

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >How does it really work?
    When used in an expression, the name of an array is treated as a pointer to the first item in the array. A string literal is really a pointer to char. What does the following print?
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      char a[] = "Test";
    
      printf ( "%p\n", (void *)a );
      printf ( "%p\n", (void *)"Test" );
    
      return 0;
    }
    Not two equal addresses if that's what you were going to say. The chances of that are slim and none, and I'd lean more toward none if I were a betting girl.

    Anyway, using the above knowledge, what will the following print (feel free to ignore the warning about logical comparison with a string literal if you get one):
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      char a[] = "Test";
    
      if ( a == "Test" )
        printf ( "Equal?!\n" );
    
      return 0;
    }
    What you would expect is that the contents of a is compared lexographically with the contents of "Test". Of course, if you hang around C programmers, this tendency goes away with time. What really happens is that two addresses that are highly unlikely to be the same are compared.

    Now, since we C programmers are kewler () than everyone else, we use a sneaky method of weeding out the pretenders by making string comparison illogical unless you already know C or something similar:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( void )
    {
      char a[] = "Test";
    
      if ( strcmp ( a, "Test" ) == 0 )
        printf ( "Equal!\n" );
    
      return 0;
    }
    My best code is written with the delete key.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > Not two equal addresses if that's what you were going to say. The chances of that are slim and none
    Always none - they're two different objects, so they really need to be in two different places


    But
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      char *a = "Test";
    
      if ( a == "Test" )
        printf ( "Equal?!\n" );
    
      return 0;
    }
    could well produce equality for a different reason than you might expect
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    might that be because a only points to "T" because of only being a single char pointer, then the string literal it's being compared to also has "T" for its first element?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > might that be because a only points to "T" because of only being a single char pointer,
    No, you've just described
    if ( *a == *"Test" )

    Which would also be true if you wrote
    if ( *a == *"Trouble" )


    But
    if ( a == "Trouble" )
    would always be false
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    After a little time with my K&R book (maybe I should get to reading throuh it) I think I've come up with a closer explanation. Is it because they are both string constants that it will cause equality? And since at the time of testing the "Test" constant would already be on the symbol table, would it cause the second "Test" to go to that constant, and give it the same pointer value as *a?

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    It depends on the compiler. A smart one might see that the same literal was used in two places and instead create a single one to store in the initialized area of the executable. But I would think that most compilers won't go to so much trouble. The point is, you'd be comparing pointers - not array contents.

    But back to the original question. You should use something like Prelude suggested - it's faster than string comarison anyway.
    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;
    }

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Is it because they are both string constants that it will cause equality?

    No.

    >> ...and give it the same pointer value as *a?

    No, what Salem was trying to point out is that given:

    const char * a = "Test", * b = "Trouble";

    *a == *b because dereferencing either yields the letter 'T'.
    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;
    }

  11. #11
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    That's what I had meant, but I didn't say it right. Homework on the weekends turns Draco into a bad programmer

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. member as default argument
    By MarkZWEERS in forum C++ Programming
    Replies: 2
    Last Post: 03-23-2009, 08:09 AM
  2. template argument
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 03-12-2008, 03:01 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Testing if an argument is a directory
    By kahad in forum C Programming
    Replies: 5
    Last Post: 11-08-2006, 04:06 PM
  5. Nested loop frustration
    By caroundw5h in forum C Programming
    Replies: 14
    Last Post: 03-15-2004, 09:45 PM