LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Looking for a more effecient way to pass arguments to functions. (https://www.linuxquestions.org/questions/programming-9/looking-for-a-more-effecient-way-to-pass-arguments-to-functions-440055/)

RHLinuxGUY 04-29-2006 01:28 PM

Looking for a more effecient way to pass arguments to functions.
 
Lately my functions for my game have incredibly bloated with parameters, example:

int move_xy(int xM, int yM, int xL, int yL, int *xB, int *yB, int *xBL, int *yBL)

... what would be a more effecient way of sending information to a function?

bulliver 04-29-2006 01:31 PM

Passing a struct?

exvor 04-29-2006 01:35 PM

Quote:

int move_xy(int xM, int yM, int xL, int yL, int *xB, int *yB, int *xBL, int *yBL)
Wow. Thats a spicy meata ball.
:D

sajjadc 04-29-2006 02:03 PM

hey
best way t pass pointersonly
or
struct

RHLinuxGUY 04-29-2006 02:14 PM

Well I used to use all ponters, but I am changing a good hundred more or less lines of code so that I can have all of them function within one, and it doesn't seem apparent to me that I need all pointers passed. Anyways, I'll look into passing some sort of struct (which I believe is a class but instead of everything defaulting to private, it is public, and is somehow different in c++ then in c, correct?).

paulsm4 04-29-2006 02:59 PM

Hi -

1. For your purposes, a "class" with nothing but data, and all public members, is completely equivalent to a struct:
Code:

#include <stdio.h>

struct mystruct {
  char a;
  char b;
};

class myclass {
public:
  char a;
  char b;
};

int
main ()
{
  printf ("sizeof mystruct= %ld, sizeof myclass= %ld\n",
    sizeof (struct mystruct), sizeof (myclass) );
  return 0;
}

Quote:

BUILD:
g++ -Wall -pedantic -o x x.cpp
Quote:

EXECUTE:
sizeof mystruct= 2, sizeof myclass= 2
<= IN THIS CASE, CLASS AND STRUCT ARE IDENTICAL...
2. Stroustrup says the same thing:
Quote:

A struct is simply a class where members are public by default...
- The C++ Programming Language, 2nd Ed; Bjarne Stroustrup, pg 146
3. If you define a member function (something you cannot, of course, do in C), then that function is passed (an "invisible") "this" pointer in the first argument.

BOTTOM LINE:
If you're only passing data, I'd just define a struct and be done with it.

If you're defining methods with respect to that data, I'd define a class.

And if you're going to define a class, then I'd treat it like a class (appropriate constructors, copy constructors; declare the destructor "virtual" if you're going to subclass; getter and setter functions; *NO* public visibility to member data: basically, the whole nine yards).

'Hope that helps .. PSM

Dark_Helmet 04-29-2006 02:59 PM

You could pass a pointer to a union of structs.

To clarify, each of your function parameter lists will be more or less unique to that function. You could, in theory, define a struct for each separate function parameter list. Then, create a union of them. Declare a variable of the union, and set the appropriate fields prior to each call. I can give an example if it's not clear... it's hard to explain.

Or, you could do a hybrid. Most of your functions will need access to a "base" set of variables. Say, for instance, a handle to the screen's context, or the position of an object on a virtual map. You can create a struct containing those "base" variables, create a union of structs for the individual function requirements, and then create a wrapper struct to contain both. Ok, I can't help myself... example:

Code:

typedef struct primary_parameters
{
  int log_file_handle;
  int screen_handle;
  int player_position_x;
  int player_position_y;
} primary_params;

typedef struct firing_paramameters
{
  int shots_fired;
  double angle_fired;
  int enemy_location_x;
  int enemy_location_y;
} firing_params;

typedef struct damage_parameters
{
  int location_hit;
  int amount_of_damage;
} damage_params;

typedef union secondary_parameters
{
  firing_params firing;
  damage_params damage;
}secondary_params;

typedef struct universal_parameters
{
  primary_params  primary;
  secondary_params secondary;
} universal_params;

...

int DetermineHit( universal_params *arguments )
{
  fprintf( arguments->primary.log_file_handle, "Calulating if shot(s) hit...\n" );
  while( arguments->secondary.firing.shots_fired > 0 )
  {
    ...
  }
  ...
}

...

void ApplyDamage( universal_params *arguments )
{
  fprintf( arguments->primary.log_file_handle, "Applying damage...\n" );
  if( arguments->secondary.damage.location_hit > 10 )
  {
    fprintf( arguments->primary.log_file_handle, "Error: invalid hit location!\n" );
    return;
  }
  ...
}

...

int main( int argc, char *argv[] )
{
  universal_params universal_arguments;

  ...

  universal_arguments.primary.log_file_handle = fopen( ... );

  universal_arguments.secondary.firing.shots_fired = 3;
  DetermineHit( &universal_arguments );

  universal_arguments.secondary.damage.location_hit = 4;
  ApplyDamage( &universal_arguments );
}

Because of the nature of a union, you need to explicitly set each secondary variable before you call the function that uses them. Since the memory space among the secondary structs is shared, you can easily run into problems if you call functions back-to-back that depend on different sets of "secondary" variables.

EDIT: Forgot the "_handle" when referencing "log_file_handle"

dmail 04-30-2006 09:21 AM

Quote:

Originally Posted by RHLinuxGUY
Lately my functions for my game have incredibly bloated with parameters, example:

int move_xy(int xM, int yM, int xL, int yL, int *xB, int *yB, int *xBL, int *yBL)

... what would be a more effecient way of sending information to a function?

Well what are the parameters? this func moves an object in the x and y axis but why the 8 params?
If your serious about making games maybe it would be an idea to create vector classes/structs such as
Code:

class Vector_2d
{
Vector_2d(int const x,int const y){m_x = x; m_y = y; }
Vector_2d(Vector_2d const & vec){m_x = vec.x;m_y = vec.y;}
Vector_2d operator=(Vector_2d const & vec)
    {
        m_x = vec.x;m_y = vec.y;
        return *this;
    }
//operator overloads for dot product, angle between etc etc
....
}
thus using the following if all params are needed
int move_xy(Vector_2d const& M,Vector_2d const& L,
            Vector_2d const& B,Vector_2d const& BL)
{
....
}

Sometimes you will find there is a need to pass a large amount of params, so I wouldn't be concerned if they are needed.
For the likes of ...int *xB.... maybe you should protect the data like:
int const * const xB

RHLinuxGUY 04-30-2006 02:23 PM

Quote:

Quote:

Originally Posted by RHLinuxGUY
Lately my functions for my game have incredibly bloated with parameters, example:

int move_xy(int xM, int yM, int xL, int yL, int *xB, int *yB, int *xBL, int *yBL)

... what would be a more effecient way of sending information to a function?
Well what are the parameters? this func moves an object in the x and y axis but why the 8 params?
O yea, I tried doing an x and y parameters, which would have reduced the arguments to only 4, but I had a problem. It worked just fine having just an x and y coordinates being sent to move_xy (it's actually called move_left,right,up,etc in the working version), but at certain points of the map, my character (the one you move) would disapear. I forgot about the map which I was moving my character on, was the same as a times table, or that one where there is 1 through 10 across and 1 through 10 down. At certain points a number (exluding the very most right numbers), multiplied by its x number and its y numbers, are the same as the box one up and the right of its position. So instead of passing just x and y, I also passed lines. The other 4 parameters are just my bad guy location. I'm removing it right now, for it was just temporary. so (int YourGuyX, int YourGuyY, int YourGuyLineX, int YourGuyLineY, int *xBadGuy, int *yBadGuy, int *xBadGuyLine, int *yBadGuyLine)

I learned about constants recently and I have made a note to myself now to use it more often (when needed), so I don't get some mistake such as the one above.

Now I'm off to learn vectors. Thanks everyone!

BTW: If you would like to play with it (please don't send any corrections back to me IF anyone even decides to mess with it), here is a link the most recent working version: http://pntbalg.shackspace.com/GeorgeLair/042606. Just copy everything you see in some folder go into a console and cd into the directory containing these and type make.

sibtay 04-30-2006 03:01 PM

[QUOTE=Dark_Helmet]You could pass a pointer to a union of structs.

Nice solution. But i think the issue here is to reduce the load of parameters being passed.
In your solution you eventually passed a *pointer* to the union, which requires the same resources on the stack if you would've passed a pointer to structure, class, variable etc.

To me the most efficient approach in this scenario is to simply pass a pointer to a container object (union, structure, class, array).

Wim Sturkenboom 05-01-2006 10:52 PM

Quote:

Originally Posted by RHLinuxGUY
Well I used to use all ponters, but I am changing a good hundred more or less lines of code so that I can have all of them function within one, and it doesn't seem apparent to me that I need all pointers passed. Anyways, I'll look into passing some sort of struct (which I believe is a class but instead of everything defaulting to private, it is public, and is somehow different in c++ then in c, correct?).

Using pointers to all variables does indeed not make sense to reduce the load.
However, passing a pointer to a struct (or similar) makes sense. In that case only 4 bytes (8 in 64bit systems) have to be copied to the stack when the function is called. When you use the struct directly, it would still have been the full content that will be copied on the stack.


All times are GMT -5. The time now is 06:15 PM.