use of pointers

A

ahso

Hi
I want to rewrite a function as below to not use pointers:

void NewPos(float angle, float speed, float *x, float *y){

angle = (angle-90.0)*0.0174532925199433;

*x = (cos(angle) * speed);
*y = (sin(angle) * speed);

}

I also don't know what this is doing exactly. Any explanations and
also why this needs pointers?
Many thanks
 
M

Marcel Müller

Hi
I want to rewrite a function as below to not use pointers:

void NewPos(float angle, float speed, float *x, float *y){

angle = (angle-90.0)*0.0174532925199433;

*x = (cos(angle) * speed);
*y = (sin(angle) * speed);

}

I also don't know what this is doing exactly. Any explanations and
also why this needs pointers?

Well, it looks like old C code. The pointers are used as reference
parameters in this case. The function in fact returns two values.

The C++ way to do so is
void NewPos(float angle, float speed, float& x, float& y)
Now you pass x and y explicitely as references. Of course, you need to
remove the * before x and y in the function and most probably & where
the function is called.

A even better code might return a structure consisting of x and y.

By the way: the magic number 0.017... is bad programming style, since no
one knows what it is good for. You should write 2*M_PI/360. which is
more clearly a conversion between degrees and radians.


Marcel
 
J

Juha Nieminen

ahso said:
Hi
I want to rewrite a function as below to not use pointers:

void NewPos(float angle, float speed, float *x, float *y){

angle = (angle-90.0)*0.0174532925199433;

*x = (cos(angle) * speed);
*y = (sin(angle) * speed);

}

Since floats are small basic types, it's much, much cleaner (and
equally efficient) to do this:

struct Point { float x, y; };

Point NewPos(float angle, float speed)
{
angle = (angle - 90.0f) * 0.0174532925199433f;
Point p = { std::cos(angle) * speed, std::sin(angle) * speed };
return p;
}

(With C++11 you can skip creating the local variable 'p' and return
the initializer list directly.)
 
V

Victor Bazarov

Since floats are small basic types, it's much, much cleaner (and
equally efficient) to do this:

struct Point { float x, y; };

Point NewPos(float angle, float speed)
{
angle = (angle - 90.0f) * 0.0174532925199433f;
Point p = { std::cos(angle) * speed, std::sin(angle) * speed };
return p;
}

(With C++11 you can skip creating the local variable 'p' and return
the initializer list directly.)

The name 'Point' is misleading IMNSHO and so is the name of the
function. What is returned is a velocity vector, not a position.

And I am not so sure one couldn't just return std::pair<float,float>
since it essentially does the same thing, except that its members are
not called 'x' and 'y'... Why invent another type when a standard one
exists?

V
 
G

glen herrmannsfeldt

(snip, someone wrote)
(snip)
The name 'Point' is misleading IMNSHO and so is the name of the
function. What is returned is a velocity vector, not a position.

I suppose, but you could just consider it a point in velocity space.
And I am not so sure one couldn't just return std::pair<float,float>
since it essentially does the same thing, except that its members are
not called 'x' and 'y'... Why invent another type when a standard one
exists?

But velocity also has x and y components, so Point is fine.

-- glen
 
S

SG

The name 'Point' is misleading IMNSHO

I think it's okay. I don't see the benefit of creating two types (for
points and vectors) with basically the same interface. And since we
already have vector said:
Why invent another type when a standard one exists?

Because even "point" says more than "pair<float,float>" to the human
source code reader.

Cheers!
SG
 
V

Victor Bazarov

(snip, someone wrote)

I suppose, but you could just consider it a point in velocity space.

I could. But somebody who will likely assign a velocity "point" to a
two-dimensional spatial (planar) point, shouldn't. There is no "space"
designation in the type, is there?
But velocity also has x and y components, so Point is fine.

<sigh> It isn't. But I don't see any use of arguing. Not anymore.
Sorry I brought it up.

V
 
G

glen herrmannsfeldt

I could. But somebody who will likely assign a velocity "point" to a
two-dimensional spatial (planar) point, shouldn't. There is no "space"
designation in the type, is there?

I expect that you will find that some people think one way one
some the other. Note that it is unusual (there might be one) for
programming languages to keep track of dimensional units.

Physics has, in addition to velocity space, which might not seem
too strange, momentum space. There are some problems that can easily
be solved if you think of them in momentum space. (Even
relativistically when it isn't mass times velocity anymore.)
<sigh> It isn't. But I don't see any use of arguing. Not anymore.
Sorry I brought it up.

I have thought for some time now, that it is more usual for
physicists to include units in their variables, and for engineers
to factor them out.

In a physics book you will see F=ma.

In an engineering book F(Newtons) = m(kg) * a (m/s**2)

In the latter case, the variable holds the unitless value that,
when the specified unit is applied, has the appropriate value
and dimensions.

Now, with a name like Point, one could ask why it is 2D and
not 3D, or even 4D. You could name the class Vector2D, though.

-- glen
 
G

Geoff

Hi
I want to rewrite a function as below to not use pointers:

void NewPos(float angle, float speed, float *x, float *y){

angle = (angle-90.0)*0.0174532925199433;

*x = (cos(angle) * speed);
*y = (sin(angle) * speed);

}

I also don't know what this is doing exactly. Any explanations and
also why this needs pointers?
Many thanks

It's using pointers because it needs to return more than one value and
since it's old C it was probably the simplest way to do it at the
time.

What is it doing? It's resolving a velocity vector. It's decomposing a
velocity vector of angle angle and scalar speed into its components in
x and y. (polar to Cartesian coordinate conversion)

Presumably, the caller is calling NewPos cyclically and adding the x,y
values to some current_position value to compute a new position based
on the instantaneous speed and angle.
 
G

Guest

On 06.03.2012 11:54, ahso wrote:

By the way: the magic number 0.017... is bad programming style, since no
one knows what it is good for. You should write 2*M_PI/360. which is
more clearly a conversion between degrees and radians.

or even better

inline double degreesToRadians (double d)
{
return d * M_PI / 180.0;
}
 
J

Jorgen Grahn

It's using pointers because it needs to return more than one value and
since it's old C it was probably the simplest way to do it at the
time.

Probably not the /only/ way though -- returning structs has been
possible in C for ~25 years now. I always believed it was expensive,
but I suspect that at some point it became cheaper with popular
compilers.

/Jorgen
 
W

woodbrian77

I think it's okay. I don't see the benefit of creating two types (for
points and vectors) with basically the same interface. And since we


Because even "point" says more than "pair<float,float>" to the human
source code reader.

I'd prefer the point also over a pair. I'm not keen
on the first and second names. One disappoint with
the latest standard is there's still not a good
alternative to std::map.

Brian
Ebenezer Enterprises
http://webEbenezer.net
 
J

Juha Nieminen

or even better

inline double degreesToRadians (double d)
{
return d * M_PI / 180.0;
}

The compiler will most probably not replace "M_PI / 180.0" with its
result at compile time in the above expression, unless you specifically
set optimizations that allow it (eg. -ffast-math). If you want to avoid
the runtime division, do it like this:

return d * (M_PI / 180.0);

Now the compiler is allowed to do the division at compile time.
(OTOH, you should not assume that all compilers will do that when
dealing with floating point...)
 
N

none

Probably not the /only/ way though -- returning structs has been
possible in C for ~25 years now. I always believed it was expensive,
but I suspect that at some point it became cheaper with popular
compilers.

Sounds like old-style C programmer: "I believe it is too expensive".
One really should either test or if the effort of testing is
considered not worth it, use the most readable, most useable and less
bug prone technique. Never use a less readable technique because it
is "believed" to be less CPU expensive.

// common header
struct Point { float x; float y };
Point NewPos(float angle, float speed);

// User code
Point somePoint = NewPos(someAngle, someSpeed);

vs:

// common header
void NewPos(float angle, float speed, float *x, float *y);
// All the rest of the code can refer to the point as a single entity

// user code:
float x = 0;
float y = 0;
NewPos(someAngle, someSpeed, &x, &y);
// all the rest of the code need to handle x and y separately even if
// they are non-sensical separately

The former is much cleaner, the second form should only be used if it
can be demonstrated that the first form is definitely not suitable.

Yannick
 
M

Maarten

Sounds like old-style C programmer: "I believe it is too expensive".
One really should either test or if the effort of testing is
considered not worth it, use the most readable, most useable and less
bug prone technique. Never use a less readable technique because it
is "believed" to be less CPU expensive.

As Donald Knuth once put it: "There is no doubt that the grail
of efficiency leads to abuse. Programmers waste enormous amounts
of time thinking about, or worrying about, the speed of noncritical
parts of their programs, and these attempts at efficiency actually
have a strong negative impact when debugging and maintenance are
considered. We should forget about small efficiencies, say about
97% of the time: premature optimization is the root of all evil."

Only start optimizing once you have tested your code, and are
satisfied that it is correct. And only start to optimize when
you have seen that there is a performance issue, and have
pinpointed the issue with a profiler.

Yes, Donald Knuth leaves you 3% where it does matter. But he
also states that you should only worry about that after you
have identified that code.

Article can be found from
http://en.wikipedia.org/wiki/Program_optimization

Maarten
 
G

Guest

The compiler will most probably not replace "M_PI / 180.0" with its
result at compile time in the above expression, unless you specifically
set optimizations that allow it (eg. -ffast-math). If you want to avoid
the runtime division, do it like this:

return d * (M_PI / 180.0);

Now the compiler is allowed to do the division at compile time.
(OTOH, you should not assume that all compilers will do that when
dealing with floating point...)

inline double degreesToRadians (double d)
{
const double radsPerDeg = M_PI / 180.0;
return d * radsPerDeg;
}
 
R

Rui Maciel

ahso said:
Hi
I want to rewrite a function as below to not use pointers:

void NewPos(float angle, float speed, float *x, float *y){

angle = (angle-90.0)*0.0174532925199433;

*x = (cos(angle) * speed);
*y = (sin(angle) * speed);

}

I also don't know what this is doing exactly. Any explanations and
also why this needs pointers?
Many thanks

I agree with Marcel Müller: it does look like C code. Or, better yet, it
looks like the C way of passing arguments by reference.

So, here is the breakdown of this function:

- It basically it performs a coordinate transformation on a 2D vector from
polar coordinates (angle, magnitude) to rectangular coordinates. So, it
takes two pairs of parameters: a couple of floats used to represent a vector
described in polar coordinates (angle, speed) and a couple of pointers to
floats intended to describe a vector in rectangular coordinates (x, y).
- the "angle" parameter is defined in degrees, but the trigonometric
functions require that the angle is described in radians. This requires a
conversion from degrees to radians. The "angle" parameter is subjected to a
translation (angle - 90).
- the function was written so that the result of this vector transformation
was stored in a couple of objects which are passed as parameters (i.e.,
float x and float y). To be able to do that with the C programming
language, we need to pass pointers which point to the address of those
objects. By doing this, it becomes possible to set the value of those
objects by dereferencing the pointers to them.


Hope this helps,
Rui Maciel
 
R

Rui Maciel

Victor said:
The name 'Point' is misleading IMNSHO and so is the name of the
function. What is returned is a velocity vector, not a position.

And I am not so sure one couldn't just return std::pair<float,float>
since it essentially does the same thing, except that its members are
not called 'x' and 'y'... Why invent another type when a standard one
exists?

User-defined data types improve code readability. Under some circumstances,
it also help reduce the propensity to inadvertently add bugs to the code.


Rui Maciel
 
J

Juha Nieminen

inline double degreesToRadians (double d)
{
const double radsPerDeg = M_PI / 180.0;
return d * radsPerDeg;
}

That still doesn't guarantee that the compiler will calculate the
division at compile time any more than with my version. Remember
that a 'double' isn't a compile-time constant in C++98.

It's probably different in C++11, where you can use:

constexpr double radPerDeg = M_PI / 180.0;

Here the compiler has no choice (AFAIK) than to perform the calcuation
at compile time.
 
R

Rui Maciel

Maarten said:
As Donald Knuth once put it: "There is no doubt that the grail
of efficiency leads to abuse. Programmers waste enormous amounts
of time thinking about, or worrying about, the speed of noncritical
parts of their programs, and these attempts at efficiency actually
have a strong negative impact when debugging and maintenance are
considered. We should forget about small efficiencies, say about
97% of the time: premature optimization is the root of all evil."

Only start optimizing once you have tested your code, and are
satisfied that it is correct. And only start to optimize when
you have seen that there is a performance issue, and have
pinpointed the issue with a profiler.

Yes, Donald Knuth leaves you 3% where it does matter. But he
also states that you should only worry about that after you
have identified that code.

Article can be found from
http://en.wikipedia.org/wiki/Program_optimization

Knuth's quote tends to be abused a bit. Some individuals employ it to,
under Knuth's authority, imply that any attention to efficiency, however
remote it might be, is also evil, and therefore no attention whatsoever
should be ever paid to it. This may pose a serious problem in applications
which do need to run efficiently, as it isn't possible to fix performance
problems caused by fundamental design decisions by postponing any attention
to the application's efficiency to a testing stage.


Rui Maciel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,167
Latest member
SusanaSwan
Top