Need HELP

K

kupiko

Please can anyone help me on this code? I want
to write all odd numbers in range from a to b but it doesn't work at all
cases mainly when a is higher than b and when i type in negative numbers.


Here is the code and i would appreciate anybody helping me. THANKS.

#include<stdio.h>
#include<math.h>
void odd(float x, float y);
void change(float x, float y);

void odd(float x, float y)
{
int i;
if (x>y) change(x,y);
x=roundf(x);
y=roundf(y);
for(i=1;i<(y-x)+1;i++)
if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
",(x+i) );
}

void change(float x, float y)
{
float c;
c=x;
x=y;
y=c;
}

main()
{

float a,b;
printf("Type two real numbers :");
scanf("%f%f",&a,&b);
odd(a,b);
getchar();
getchar();
}
 
D

Don Morris

kupiko said:
Please can anyone help me on this code? I want
to write all odd numbers in range from a to b but it doesn't work at all
cases mainly when a is higher than b and when i type in negative numbers.


Here is the code and i would appreciate anybody helping me. THANKS.

#include<stdio.h>
#include<math.h>
void odd(float x, float y);
void change(float x, float y);

void odd(float x, float y)
{
int i;
if (x>y) change(x,y);
x=roundf(x);
y=roundf(y);
for(i=1;i<(y-x)+1;i++)
if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
",(x+i) );
}

void change(float x, float y)
{
float c;
c=x;
x=y;
y=c;
}

Just on first glance (i.e. I wouldn't swear that you don't have
other bugs...), your problem is in how you call change().
When you call a C function, the function works on local copies
of the parameters -- not on the values in the scope of the caller.

So here -- you have the following:

main gets a and b (main:a, main:b for short), calls odd with them.
odd gets copies of main:a, main:b which are named odd:x, odd:y.
main:a and main:b are (of course) unchanged).

odd calls change with odd:x, odd:y -- and change's copies are
called change:x, change:y.

change:x, change:y and change:c are modified and change returns..
leaving odd:x and odd:y unchanged.

So if you want to do this, I'd recommend one of the following:

i) Rewrite change to be a macro, not a function so that
you work with the actual variables you intend, such as:

#define SWAP_FLOAT(float __x, float __y ) \
do { \
float __temp; \
__temp = __x; \
__x = __y; \
__y = __temp; \
} while (0)

This lets you use SWAP_FLOAT as if it were a function,
having odd() do SWAP_FLOAT(x, y) will change the
variables in odd()'s scope [odd:x, odd:y] as you intend.

ii) Rewrite change to work with the addresses of the
variables, not the contents.

void change (float *x, float *y)
{
float temp;
if ( x == NULL || y == NULL ) {
/* Die with error? Your call on handling */
return;
}
temp = *x;
*x = *y;
*y = temp;
}

Don
 
K

kupiko

void change (float *x, float *y)
{
float temp;
if ( x == NULL || y == NULL ) {
/* Die with error? Your call on >handling */
return;
}
temp = *x;
*x = *y;
*y = temp;
}

Thank you very much for this advice. It's first time I see how to use
pointers and it is useful as I see but still there are errors in my
rewritten code. And i don't know anything about pointers so i can't solve
what it mean could you please help me?
I haven't much time otherwise i would not annoy you.

ERROR:
cannot convert `float' to `float*' for argument `1' to `void
vymen(float*, float*)'

CODE:

#include<stdio.h>
#include<math.h>

void odd(float x, float y);
void change(float *x, float *y);

void odd(float x, float y)
{
int i;
if (x>y) change(x,y);
x=roundf(x);
y=roundf(y);
for(i=1;i<(y-x)+1;i++)
if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
",(x+i) );
}

void change(float *x, float *y)
{
float c;
if ( x==NULL || y==NULL ) return;
c=*x;
*x=*y;
*y=c;
}

main()
{
float a,b;
printf("Type two real numbers :");
scanf("%f%f",&a,&b);
odd(a,b);
getchar();
getchar();
}
 
D

Don Morris

kupiko said:
Thank you very much for this advice. It's first time I see how to use
pointers and it is useful as I see but still there are errors in my
rewritten code. And i don't know anything about pointers so i can't solve
what it mean could you please help me?
I haven't much time otherwise i would not annoy you.

It isn't annoying me... just a sign my mind isn't focused on
work yet this morning. :) Sorry I wasn't more clear.
ERROR:
cannot convert `float' to `float*' for argument `1' to `void
vymen(float*, float*)'

Right -- we've changed the function to take pointers, which means
you need to call it with pointers (aka the address of x, not x
itself).
CODE:

#include<stdio.h>
#include<math.h>

void odd(float x, float y);
void change(float *x, float *y);

void odd(float x, float y)
{
int i;
if (x>y) change(x,y);

if ( x > y ) {
change(&x, &y);
}

Don
 
M

Mac

#define SWAP_FLOAT(float __x, float __y ) \

Is this a C99 thing? I've never seen a function-like macro defined this
way (with types) and my compiler won't accept it.

Maybe you meant to type:
#define SWAP_FLOAT(__x, __y ) \
do { \
float __temp; \
__temp = __x; \
__x = __y; \
__y = __temp; \
} while (0)

And why are you using the undercores in the identifier names? They seem
to me to be completely unnecessary. Couldn't you just do it like this:

#define SWAP_FLOAT(x, y ) \
do { \
float temp; \
temp = x; \
x = y; \
y = temp; \
} while (0)


--Mac
 
A

Artie Gold

Mac said:
Is this a C99 thing? I've never seen a function-like macro defined this
way (with types) and my compiler won't accept it.

And your compiler is correct!
Maybe you meant to type:
#define SWAP_FLOAT(__x, __y ) \




And why are you using the undercores in the identifier names? They seem
to me to be completely unnecessary. Couldn't you just do it like this:

Well, it was a misguided attempt at avoiding inadvertent variable
capture. Identifiers starting with an underscore are reserved for the
implementation.
#define SWAP_FLOAT(x, y ) \
do { \
float temp; \
temp = x; \
x = y; \
y = temp; \
} while (0)
Consider, however, what happens if you have the following code:

void nonsensical() {
float temp = 3.0;
float other = 4.0;
printf("before swap, temp = %f, other = %f", temp, other);
SWAP_FLOAT(temp, other);
printf("after swap, temp = %f, other = %f", temp, other);
}

Macros can be useful -- but (particularly if they declare variables) can
bite you in the^H^H^H^H^H^H^H^H^H^H^H^H^H^H^Hcause problems.

HTH,
--ag
 
O

Old Wolf

Artie said:
Consider, however, what happens if you have the following code:

void nonsensical() {
float temp = 3.0;
float other = 4.0;
printf("before swap, temp = %f, other = %f", temp, other);
SWAP_FLOAT(temp, other);
printf("after swap, temp = %f, other = %f", temp, other);
}

The problem is that 'temp' in the macro clashes with 'temp' in
the parameter. So how about this:

#define SWAP_FLOAT(x, y) \
do { \
float x##y; \
x##y = x; \
x = y; \
y = x##y; \
} while (0)

No possibility of clashes now (even if 'x' and 'y' are #defined
to something else already, I think)
 
P

Peter Nilsson

Old said:
...
The problem is that 'temp' in the macro clashes with 'temp' in
the parameter. So how about this:

#define SWAP_FLOAT(x, y) \
do { \
float x##y; \
x##y = x; \
x = y; \
y = x##y; \
} while (0)

SWAP_FLOAT(er, rno);
SWAP_FLOAT(x, *y);
 
P

Peter Nilsson

Old said:
No problem, local errno takes precedence over global errno.

You don't seem to realise that, if <errno.h> is included,
errno is a _macro_ "...which expands to a modifiable lvalue
that has type int". [7.5p2] It needn't expand to the name of
a 'global'.
Ah, serious problem.I guess that takes us back to the
pick-something-weird-and-wacky option.

Or to 'inline' under C99, if such an implementation is available.
 

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

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top