473,396 Members | 1,915 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Returning values from a function

I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand this
is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?

Nov 13 '05 #1
41 3733
WW
Materialised wrote:
I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand
this is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?


Ehem. The first one is that you try to program in C++ without a good
textbook. :-(

First of all, your program has not return value. You do not return
anything. There is no return statement.

The second: how do you expect to return 3 integers in one?

The third: as you wrote the function definition (signature) it takes the
arguments by value, so x,y and z (which you have clearly typed wrong) is a
*copy* of a b and c. Writing into them will write into the copy.

You can take the arguments by reference, then you will be able to change
them. *If* you work in C++. If you do work in C, you will need to take
pointers to them.

--
WW aka Attila
Nov 13 '05 #2
Materialised wrote:

I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand this
is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?


These are Questions 4.8 and 20.1 in the comp.lang.c
Frequently Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

--
Er*********@sun.com
Nov 13 '05 #3
Materialised wrote:
I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand this
is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void randomise(int *x, int *y, int *z)
{
srand((unsigned) time(NULL));
*x = rand();
*y = rand();
*z = rand();
}

int main(void)
{
int a, b, c;
randomise(&a, &b, &c);
printf("%d %d %d\n", a, b, c);
return 0;
}

--
Martin Ambuhl

Nov 13 '05 #4
WW wrote:
Materialised wrote:
I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand
this is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?

Ehem. The first one is that you try to program in C++ without a good
textbook. :-(

First of all, your program has not return value. You do not return
anything. There is no return statement.

The second: how do you expect to return 3 integers in one?

The third: as you wrote the function definition (signature) it takes the
arguments by value, so x,y and z (which you have clearly typed wrong) is a
*copy* of a b and c. Writing into them will write into the copy.

You can take the arguments by reference, then you will be able to change
them. *If* you work in C++. If you do work in C, you will need to take
pointers to them.

Thanks for your help, I realised my error right after posting

int randomise()
{
int x;
srand((unsigned)time(NULL));
x = rand();
return x;
}

and in main

a = randomise();
b = randomise();
c = randomise();

Nov 13 '05 #5
Materialised wrote:
WW wrote:
Materialised wrote:
I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand
this is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?


Ehem. The first one is that you try to program in C++ without a good
textbook. :-(

First of all, your program has not return value. You do not return
anything. There is no return statement.

The second: how do you expect to return 3 integers in one?

The third: as you wrote the function definition (signature) it takes the
arguments by value, so x,y and z (which you have clearly typed wrong) is a
*copy* of a b and c. Writing into them will write into the copy.

You can take the arguments by reference, then you will be able to change
them. *If* you work in C++. If you do work in C, you will need to take
pointers to them.

Thanks for your help, I realised my error right after posting

int randomise()
{
int x;
srand((unsigned)time(NULL));
x = rand();
return x;
}

and in main

a = randomise();
b = randomise();
c = randomise();


No, you don't want to do that either.
Calling `srand()' multiple times like that (i.e. for each call to
`rand()') will not make the numbers any more random, and may do
exactly the opposite.

Call srand() once...

....and please reread the suggestions elsethread.

HTH,
--ag

--
Artie Gold -- Austin, Texas
Oh, for the good old days of regular old SPAM.

Nov 13 '05 #6
In <bn************@ID-204621.news.uni-berlin.de> Materialised <ma**********@privacy.net> writes:
I am writing a simple function to initialise 3 variables to pesudo
random numbers.

I have a function which is as follows

int randomise( int x, int y, intz)
{
srand((unsigned)time(NULL));
x = rand();
y = rand();
z = rand();

}
And I call this function with

randomise(a,b,c);

However a,b,c do not contain the randomised integers, I understand this
is a problem with the return value of my function,
I have tried
return x,y,z;
But this doesnt work either.

Can anyone point out where my problem is?


Sure, both your favourite C book and the FAQ can.

The *right* way of solving this problem in C is by using a structure:

struct random { int x, y, z; };

struct random randomise(void)
{
struct random t;
srand((unsigned)time(NULL)); /* this function call doesn't belong
here, unless you call this function exactly once */
t.x = rand();
t.y = rand();
t.z = rand();
return t;
}

Ignore any advice recommending the usage of three pointers in the
function's interface. Such interfaces are evil, in general, even if, in
this particular case, there is no big deal. Functions should not use
their parameters as a way of returning back information to the caller.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #7
In comp.lang.c Dan Pop <Da*****@cern.ch> wrote:
Ignore any advice recommending the usage of three pointers in the
function's interface. Such interfaces are evil, in general, even if, in
this particular case, there is no big deal. Functions should not use
their parameters as a way of returning back information to the caller.


Why is this? In what circumstances can pointers lead to tragedy?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 13 '05 #8
WW wrote:
You can take the arguments by reference, then you will be able to change
them. *If* you work in C++. If you do work in C, you will need to take
pointers to them.

Where did the OP say he was working in C++?


Brian Rodenborn
Nov 13 '05 #9
WW wrote:
Ehem. The first one is that you try to program in C++ without a good
textbook. :-(

C++
Nov 13 '05 #10
Materialised <ma**********@privacy.net> writes:
[...]
Thanks for your help, I realised my error right after posting

int randomise()
{
int x;
srand((unsigned)time(NULL));
x = rand();
return x;
}

and in main

a = randomise();
b = randomise();
c = randomise();


As someone else pointed out, you don't want to call srand() more than
once in your program. You can either call it once in your main
program, or use a static variable in randomise() to allow randomise()
to call srand() only the first time. Calling it in main() is the
simplest approach, but putting the srand() call inside randomise()
might be better in terms of program organization.

Also, the way your randomise() function is now written, the variable x
is unnecessary. Assuming you call srand() from main(), randomise()
could look like this:

int randomise(void)
{
int x;
x = rand();
return x;
}

which is equivalent to this:

int randomise(void)
{
return rand();
}

which means you probably might as well eliminate the randomise() function
altogether:

#include yadda yadda

int main(void)
{
srand((unsigned)time(NULL));
a = rand();
b = rand();
c = rand();
...
}

A couple more things to note:

C library implementations of rand() are often of poor quality; there
might be a system-specific routine that gives you better random
numbers.

The values return by rand() are in the range 0 .. RAND_MAX (defined in
<stdlib.h>). You probably want some range that you specify; see
question 13.16 in the C FAQ for details.

Given these complications, getting a useful random number is going to
involve more than just calling rand(), and you probably do want
something like your randomise() function.

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #11
In <bn**********@chessie.cirr.com> Christopher Benson-Manica <at***@nospam.cyberspace.org> writes:
In comp.lang.c Dan Pop <Da*****@cern.ch> wrote:
Ignore any advice recommending the usage of three pointers in the
function's interface. Such interfaces are evil, in general, even if, in
this particular case, there is no big deal. Functions should not use
their parameters as a way of returning back information to the caller.


Why is this? In what circumstances can pointers lead to tragedy?


In most cases, using pointer arguments this way results in less readable
and maintainable code. It's not clear whether the callee will use the
existing values of the pointed-to objects or whether it will
unconditionally change them. When encountering such a function call,
you *must* study its definition, to see what exactly is happening.
Functions not taking pointers to scalars as their arguments don't raise
such issues, you can safely ignore their definitions if they are not
directly relevant to the issue you're currently investigating.

To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #12
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
In most cases, using pointer arguments this way results in less readable
and maintainable code. It's not clear whether the callee will use the
existing values of the pointed-to objects or whether it will
unconditionally change them. When encountering such a function call,
you *must* study its definition, to see what exactly is happening.
Functions not taking pointers to scalars as their arguments don't raise
such issues, you can safely ignore their definitions if they are not
directly relevant to the issue you're currently investigating.

To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.


And how do you tell on the caller side that the function
(a) does not use the values in *array, *(array + 1), *(array + 2)
(b) puts something in there
(c) uses three items?

This solution is as good or as bad as passing three separate pointers.
I'd even argue it is worse as (c) is non-obvious.

Andre'
Nov 13 '05 #13
In <bn**********@anderson.hrz.tu-chemnitz.de> =?iso-8859-1?Q?Andr=E9_P=F6nitz?= <po*****@gmx.net> writes:
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
In most cases, using pointer arguments this way results in less readable
and maintainable code. It's not clear whether the callee will use the
existing values of the pointed-to objects or whether it will
unconditionally change them. When encountering such a function call,
you *must* study its definition, to see what exactly is happening.
Functions not taking pointers to scalars as their arguments don't raise
such issues, you can safely ignore their definitions if they are not
directly relevant to the issue you're currently investigating.

To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.


And how do you tell on the caller side that the function
(a) does not use the values in *array, *(array + 1), *(array + 2)
(b) puts something in there
(c) uses three items?


The function's prototype clearly suggests that the function is using the
pointer in write mode. And, if the array is not already initialised,
it is a (relatively) safe bet that it ignores the existing contents.

If this is not enough for your immediate needs, you can always check the
function definition.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #14
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.
And how do you tell on the caller side that the function
(a) does not use the values in *array, *(array + 1), *(array + 2)
(b) puts something in there
(c) uses three items?


The function's prototype clearly suggests that the function is using the
pointer in write mode.


I see no particular difference between

void func(int *item1, int *item2, int *item3);

void foo()
{
int i1, i2, i3;
func(&i1, &i2, &i3);
}

and

void func(int *arr);

void foo()
{
int arr[3];
func(arr);
}

at least noct to a degree to call the seond version "safer".

And, if the array is not already initialised,
it is a (relatively) safe bet that it ignores the existing contents.
So when I debug code and see the caller side I have to assume it is
correct to make a guess on how the function works?

This is not different from the original proposal.
If this is not enough for your immediate needs, you can always check the
function definition.


I thought your main point was that your solution makes checking the
definition unnecessary.

I am still not convinced and still maintain that your solution is not
better than the original. But maybe I simply don't

Andre'

--
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one. (T. Jefferson or B. Franklin or both...)
Nov 13 '05 #15

On Tue, 21 Oct 2003, Dan Pop wrote:

Christopher Benson-Manica <at***@nospam.cyberspace.org> writes:
In comp.lang.c Dan Pop <Da*****@cern.ch> wrote:
Ignore any advice recommending the usage of three pointers in the
function's interface. Such interfaces are evil, in general, even if, in
this particular case, there is no big deal. Functions should not use
their parameters as a way of returning back information to the caller.
Why is this? In what circumstances can pointers lead to tragedy?


In most cases, using pointer arguments this way results in less readable
and maintainable code.


While this is true, I must respectfully disagree with most of the
rest of what you're saying.
It's not clear whether the callee will use the
existing values of the pointed-to objects or whether it will
unconditionally change them. When encountering such a function call,
you *must* study its definition, to see what exactly is happening.
....unless the pointer parameters have 'const' attached to them in
the right places, so you can tell they're not being changed. If
they're *not* constified, then it's almost always better to assume
they *will* be changed. (No guarantees, though.)
To be more clear, I'm talking about returning back scalar information to
s/returning back/returning/
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.


I think this is worse than the original for *several* reasons.

void foo(int *bar);

is the accepted idiom for "bar is an array of int," with no constness
guarantees either way; it's rare IME to see

void foo(const int *bar);

So just by looking at the prototype, the client can't tell as reliably
whether the value of *bar will be changed.

void foo(const int bar[3]);

would be preferable in this case, since it specifies that we need to
pass exactly 3 integers in the array -- not 2, not 4, but 3. Doesn't
help the compiler, but it can help the client.

Finally, I think that the average programmer is likely to find the
array-based solution simply too clumsy. It takes time and LOC to
initialize an array that would be slightly less annoying to do with
single ints. Unless, of course, the parameters are part of a larger
"chunk" of information (say, the XYZ coordinates of a point), in
which case it probably makes more sense to pass around a (pointer to
a) 'struct'.

When I see

int a, b, c;
...
foo(&a, &b, &c);

it's pretty obvious that something is going to get changed inside
foo. In contrast, when I see

int r[3];
...
foo(r);

I can't even tell without checking types again that r *is* getting
"passed by pointer." I think that's more of a disadvantage than
whatever advantages you see to the lack of & operators -- I consider
&s a red flag!

Just for completeness, what do you think of

void foo(int (*bar)[3]);

int r[3];
...
foo(&r);

?
(I think it's unnecessarily ugly and restrictive, myself.)

-Arthur

Nov 13 '05 #16
In <bn**********@anderson.hrz.tu-chemnitz.de> =?iso-8859-1?Q?Andr=E9_P=F6nitz?= <po*****@gmx.net> writes:
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.

And how do you tell on the caller side that the function
(a) does not use the values in *array, *(array + 1), *(array + 2)
(b) puts something in there
(c) uses three items?
The function's prototype clearly suggests that the function is using the
pointer in write mode.


I see no particular difference between

void func(int *item1, int *item2, int *item3);

void foo()
{
int i1, i2, i3;
func(&i1, &i2, &i3);
}

and

void func(int *arr);

void foo()
{
int arr[3];
func(arr);
}


I do: one is a clean design, the other is a quick and dirty hack.
at least noct to a degree to call the seond version "safer".
Who said it's safer?
And, if the array is not already initialised,
it is a (relatively) safe bet that it ignores the existing contents.


So when I debug code and see the caller side I have to assume it is
correct to make a guess on how the function works?


I was NOT talking about *debugging* code, I was talking about reading or
maintaining code. If the code is known not to behave as intended, nothing
can be assumed to be correct.

And I was, obviously, not talking about trivial cases, as the ones shown
by you.
This is not different from the original proposal.
If this is not enough for your immediate needs, you can always check the
function definition.
I thought your main point was that your solution makes checking the
definition unnecessary.


Checking the definition is necessary only if you want to know what
exactly gets stored in the array. But it is a safe bet that the original
contents will not survive the call.
I am still not convinced and still maintain that your solution is not
better than the original. But maybe I simply don't


Then, feel free to use the many pointers solution, any time you need to
return multiple values from a function. Hopefully, I won't have to
maintain your code.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #17
On Tue, 21 Oct 2003 10:03:24 +0200, Karl Heinz Buchegger
<kb******@gascad.at> wrote:
Materialised wrote:
I have been given a few solutions, using pointers, eliminating the
random function altogether, using a structure, etc, etc.

My question now is which of these solutions would be more efficient?
Or is this compiler dependent and considered OT?
(Dont wanna be flamed)


Sorry. Can't resist.
Why is it that newbies who are berely able to write a correct
program always care about efficiency.


Reword your question, and you have your answer: Why is it that
people who are barely competent in a field focus on part of it that
they can understand?

Nearly anyone understands that, all else equal, a more efficient
program is better.
To say it clearly: Forget about efficiency for now at this level.
Write your program correct, make it work. Then watch your
program. If it is fast enough: don't do anything. If not: profile!
and figure out where time is spent. Only after you know where your
program uses up the time you care about efficiency.


I noted this pattern years ago. It is quite understandable.
Your advice is correct as well.

Sincerely,

Gene Wirchenko

Nov 13 '05 #18
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
And I was, obviously, not talking about trivial cases, as the ones shown
by you.
This trivial case seems to be the OP's problem.
Then, feel free to use the many pointers solution, any time you need to
return multiple values from a function.
I rarely use C. I don't use pointers if not necessary.
Hopefully, I won't have to maintain your code.


Getting down to a personal level?

Andre'
Nov 13 '05 #19

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...

My question now is which of these solutions would be more efficient?
Or is this compiler dependent and considered OT?
(Dont wanna be flamed)


Sorry. Can't resist.
Why is it that newbies who are berely able to write a correct
program always care about efficiency.
To say it clearly: Forget about efficiency for now at this level.
Write your program correct, make it work. Then watch your
program. If it is fast enough: don't do anything.


I can't totally abide by that advice. In fact, I think you've got it
backwards to a certain extent! It's professionals who need to worry about
efficiency by finding bottlenecks when and if there are performance
problems. What programs "at this level" are ever too slow? Unless there's
an infinite loop, these programs are over practically by the time you hit
ENTER. At this point, he's *learning* about efficiency so he has some
knowledge to make that call later. I seriously doubt he's interested in
speeding up a throwaway program.
Nov 13 '05 #20
jeffc wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...

My question now is which of these solutions would be more efficient?
Or is this compiler dependent and considered OT?
(Dont wanna be flamed)


Sorry. Can't resist.
Why is it that newbies who are berely able to write a correct
program always care about efficiency.
To say it clearly: Forget about efficiency for now at this level.
Write your program correct, make it work. Then watch your
program. If it is fast enough: don't do anything.


I can't totally abide by that advice. In fact, I think you've got it
backwards to a certain extent! It's professionals who need to worry about
efficiency by finding bottlenecks when and if there are performance
problems. What programs "at this level" are ever too slow? Unless there's
an infinite loop, these programs are over practically by the time you hit
ENTER. At this point, he's *learning* about efficiency so he has some
knowledge to make that call later. I seriously doubt he's interested in
speeding up a throwaway program.


He's interested in speeding up a function that calls
time() once, srand() once, and rand() three times. It's
hard to imagine wanting to keep such a thing.

An old boss of mine gave the advice this way: "First,
make it work. Then make it robust. Finally, make it fast."
The O.P. is still at (or even before!) the first step.

--
Er*********@sun.com
Nov 13 '05 #21

"Eric Sosman" <Er*********@sun.com> wrote in message
news:3F***************@sun.com...
jeffc wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...
>
> My question now is which of these solutions would be more efficient?
> Or is this compiler dependent and considered OT?
> (Dont wanna be flamed)

Sorry. Can't resist.
Why is it that newbies who are berely able to write a correct
program always care about efficiency.
To say it clearly: Forget about efficiency for now at this level.
Write your program correct, make it work. Then watch your
program. If it is fast enough: don't do anything.


I can't totally abide by that advice. In fact, I think you've got it
backwards to a certain extent! It's professionals who need to worry about efficiency by finding bottlenecks when and if there are performance
problems. What programs "at this level" are ever too slow? Unless there's an infinite loop, these programs are over practically by the time you hit ENTER. At this point, he's *learning* about efficiency so he has some
knowledge to make that call later. I seriously doubt he's interested in
speeding up a throwaway program.


He's interested in speeding up a function that calls
time() once, srand() once, and rand() three times. It's
hard to imagine wanting to keep such a thing.

An old boss of mine gave the advice this way: "First,
make it work. Then make it robust. Finally, make it fast."
The O.P. is still at (or even before!) the first step.


Well that is my point. "Your boss" implies that you were actually working
somewhere, professionally. Presumably, you were not getting paid to write
10 line programs. You said he's interested in speeding up his function. I
disagree. I think he's interested in knowing *how* to speed up his program,
so that when his boss, one day, tells him, "finally, make it fast", he will
know how. Why would anyone be interested in speeding up a toy program?
Nov 13 '05 #22
jeffc wrote:
Karl Heinz Buchegger wrote:
My question now is which of these solutions would be more efficient?
Or is this compiler dependent and considered OT?
(Don't wanna be flamed)
Sorry. Can't resist.
Why is it that newbies who are barely able to write a correct
program always care about efficiency.
To say it clearly: Forget about efficiency for now at this level.
Write your program correctly, make it work.
Then watch your program. If it is fast enough: don't do anything.


I can't totally abide by that advice.
In fact, I think you've got it backwards to a certain extent!


No. Karl gives sound advice here.
It's professionals who need to worry about efficiency
by finding bottlenecks when and if there are performance problems.
Professional programmers look first for evidence that
there actually is a performance problem.
They run a profiler to find the "bottlenecks",
and fix the worst ones first.
They stop when performance is satisfactory.
What programs "at this level" are ever too slow?
Unless there's an infinite loop,
these programs are over practically by the time you hit ENTER.
Then you don't have a performance problem, do you?
At this point, he's *learning* about efficiency
so he has some knowledge to make that call later.
I seriously doubt he's interested in speeding up a throwaway program.


Premature optimization is a sin.
Write code that is easy to read, understand and maintain.
Exhaust your compiler's optimization options first.
Shop around for a better optimizing compiler second.
Only then should you run your profiler
and consider cobbling your code to make it run faster.

Nov 13 '05 #23
jeffc wrote:
I think he's interested in knowing *how* to speed up his program,
so that when his boss, one day, tells him, "finally, make it fast", he will
know how.


If that's the case then he'll probably be disappointed. Optimization
strategies don't scale in that way. The changes that will make a toy
program faster are likely to be of an entirely different nature from
those that will make a large program faster.

Jeremy.
Nov 13 '05 #24

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:3F**************@jpl.nasa.gov...
What programs "at this level" are ever too slow?
Unless there's an infinite loop,
these programs are over practically by the time you hit ENTER.


Then you don't have a performance problem, do you?


Obviously not. The OP never said he did.
At this point, he's *learning* about efficiency
so he has some knowledge to make that call later.
I seriously doubt he's interested in speeding up a throwaway program.


Premature optimization is a sin.


We're not talking about premature optimization. We're talking about a
simple question regarding efficiency. He is not working in a professional
environment, so your point is moot.
Nov 13 '05 #25

"Jeremy Yallop" <je****@jdyallop.freeserve.co.uk> wrote in message
news:bn************@ID-114079.news.uni-berlin.de...
jeffc wrote:
I think he's interested in knowing *how* to speed up his program,
so that when his boss, one day, tells him, "finally, make it fast", he will know how.


If that's the case then he'll probably be disappointed. Optimization
strategies don't scale in that way. The changes that will make a toy
program faster are likely to be of an entirely different nature from
those that will make a large program faster.


The OP asked a completely legitimate question regarding efficiency, not
performance tuning. Y'all lighten up now.
Nov 13 '05 #26
"jeffc" <no****@nowhere.com> wrote in message news:<3f********@news1.prserv.net>...
At this point, he's *learning* about efficiency
so he has some knowledge to make that call later.
I seriously doubt he's interested in speeding up a throwaway program.


Premature optimization is a sin.


We're not talking about premature optimization. We're talking about a
simple question regarding efficiency. He is not working in a professional
environment, so your point is moot.


Given the number of inexperienced programmers (here and in the Real
World) who focus on efficiency, I think Gene Wirchenko's point, that
efficiency is a focus because it's a simple concept, is very well
made.

If an inexperienced programmer asks about efficiency, as the OP did, I
think it is valuable to point out that their main concern should be
other things. Many will not know this - I didn't know it until the
first time someone told me. If the OP comes back and says "Yes, I know
that, but I want to learn about enhancing performance for when it is
necessary" then fine. But I've never seen that happen here so I expect
in most cases people are focusing on efficiency for the wrong reasons
and hopefully benefit from the advice. The point made elsethread that
optimising techniques are unlikely to scale from toy programs to large
programs is also important.

GJD
Nov 13 '05 #27
On Tue, 21 Oct 2003 10:03:24 +0200, Karl Heinz Buchegger wrote:


Materialised wrote:


I have been given a few solutions, using pointers, eliminating the
random function altogether, using a structure, etc, etc.

My question now is which of these solutions would be more efficient?
Or is this compiler dependent and considered OT?
(Dont wanna be flamed)


Sorry. Can't resist.
Why is it that newbies who are berely able to write a correct
program always care about efficiency.
To say it clearly: Forget about efficiency for now at this level.
Write your program correct, make it work. Then watch your
program. If it is fast enough: don't do anything. If not: profile!
and figure out where time is spent. Only after you know where your
program uses up the time you care about efficiency.


And nine out of ten, the speedup comes from rewriting algorithms, not
technical details.

I'm not saying technical details can't make a difference, just that they
are in the order of a few percent most of the time.

M4
Nov 13 '05 #28
On Tue, 21 Oct 2003 10:49:58 +0000, Dan Pop wrote:
To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.


I'ld always do this as

void randomise(int *array, int size);

HTH,
M4

Nov 13 '05 #29


Martijn Lievaart wrote:


I'm not saying technical details can't make a difference, just that they
are in the order of a few percent most of the time.


In a german magazine (c't) there was a comparison of C#, Java and C++
in the last issue. They compared (basically) the same program (some tree
operations on strings) to test the languages capability on working
with objects, but when doing the C++ port, the authors showed
such less C++ qualification, that they came to the wrong conclusion.
Their benchmark showed C++ nearly 2 times slower then C# or Java and
the conclusion was ... (well, I think you can imagine what it was)

Doing a few simple modifications (pass per const reference instead
of pass per value, using += instead of +, using std::string instead
of some homegrown string class) speeded the program significantly
such that it was faster then either of the other 2 languages.

Moral: While not caring for technical details is a good habit, one
nevertheless has to know his toolkit, to select the right tool for
the right job. And of course: knowing typical idioms helps.

But in the OP's case, I expect no critical speed difference at all.

--
Karl Heinz Buchegger
kb******@gascad.at
Nov 13 '05 #30
In <pa****************************@rtij.nl.removefrom here.invalid> Martijn Lievaart <m@rtij.nl.removefromhere.invalid> writes:
On Tue, 21 Oct 2003 10:49:58 +0000, Dan Pop wrote:
To be more clear, I'm talking about returning back scalar information to
the caller. It is perfectly OK to do it for arrays. So, in the case of
the OP, another valid solution would be

void randomise(int *array);

where the caller is passing the address of the first int in an array
of three int's.


I'ld always do this as

void randomise(int *array, int size);


There is very little point in doing this, as long as the size of the
array is constant all over the program. Simply hide the size behind a
macro and use the macro in all the relevant places.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #31
On 22 Oct 2003 13:30:25 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <pa****************************@rtij.nl.removefrom here.invalid> Martijn Lievaart <m@rtij.nl.removefromhere.invalid> writes:


[snip]
I'ld always do this as

void randomise(int *array, int size);


There is very little point in doing this, as long as the size of the
array is constant all over the program. Simply hide the size behind a
macro and use the macro in all the relevant places.


And should this change, it can get messy. I would prefer to save
trouble, so I would do what Martijn suggests.

Sincerely,

Gene Wirchenko

Nov 13 '05 #32
On 22 Oct 2003 03:27:25 -0700, de*********@hotmail.com (Gavin Deane)
wrote:
"jeffc" <no****@nowhere.com> wrote in message news:<3f********@news1.prserv.net>...
> > At this point, he's *learning* about efficiency
> > so he has some knowledge to make that call later.
> > I seriously doubt he's interested in speeding up a throwaway program.
>
> Premature optimization is a sin.

A mortal sin.
We're not talking about premature optimization. We're talking about a
simple question regarding efficiency. He is not working in a professional
environment, so your point is moot.
Given the number of inexperienced programmers (here and in the Real
World) who focus on efficiency, I think Gene Wirchenko's point, that
efficiency is a focus because it's a simple concept, is very well
made.


Thank you.
If an inexperienced programmer asks about efficiency, as the OP did, I
think it is valuable to point out that their main concern should be
other things. Many will not know this - I didn't know it until the
first time someone told me. If the OP comes back and says "Yes, I know
that, but I want to learn about enhancing performance for when it is
necessary" then fine. But I've never seen that happen here so I expect
in most cases people are focusing on efficiency for the wrong reasons
and hopefully benefit from the advice. The point made elsethread that
How does one compute digital sums?

You can follow the method implied by the definition: computing
sum of digits and using that as the new number until you get a
single-digit result. You can focus on coding something that very
efficiently performs this algorithm.

Or you could use different algorithm. Digital sum is little more
than a wrapper around a single modulo 9 division.

You are rather less likely to come up with the second method
unless you know your tools.
optimising techniques are unlikely to scale from toy programs to large
programs is also important.


Yes.

Some of my "toy programs" are very inefficient, because I apply
techniques of organisation that are really not suitable until dealing
with a larger system. I sacrifice some efficiency for the
organisation.

Why?

1) So that my program reflects RW conditions as much as possible.
"It worked in the lab." is not a nice thing to hear. 2) I am
experimenting, and my code is liable to be rather less than polished.
Anything that helps me keep things organised (so I can focus on the
matter at hand) is a benefit.

Sincerely,

Gene Wirchenko

Nov 13 '05 #33
Da*****@cern.ch (Dan Pop) wrote in message news:<bn**********@sunnews.cern.ch>...
In <bn**********@anderson.hrz.tu-chemnitz.de> =?iso-8859-1?Q?Andr=E9_P=F6nitz?= <po*****@gmx.net> writes:
In alt.comp.lang.learn.c-c++ Dan Pop <Da*****@cern.ch> wrote:
> To be more clear, I'm talking about returning back scalar information to
> the caller. It is perfectly OK to do it for arrays. So, in the case of
> the OP, another valid solution would be
>
> void randomise(int *array);
>
> where the caller is passing the address of the first int in an array
> of three int's.

And how do you tell on the caller side that the function
(a) does not use the values in *array, *(array + 1), *(array + 2)
(b) puts something in there
(c) uses three items?

The function's prototype clearly suggests that the function is using the
pointer in write mode.


I see no particular difference between

void func(int *item1, int *item2, int *item3);

void foo()
{
int i1, i2, i3;
func(&i1, &i2, &i3);
}

and

void func(int *arr);

void foo()
{
int arr[3];
func(arr);
}


I do: one is a clean design, the other is a quick and dirty hack.
at least noct to a degree to call the seond version "safer".


Who said it's safer?
And, if the array is not already initialised,
it is a (relatively) safe bet that it ignores the existing contents.


So when I debug code and see the caller side I have to assume it is
correct to make a guess on how the function works?


I was NOT talking about *debugging* code, I was talking about reading or
maintaining code. If the code is known not to behave as intended, nothing
can be assumed to be correct.

And I was, obviously, not talking about trivial cases, as the ones shown
by you.
This is not different from the original proposal.
If this is not enough for your immediate needs, you can always check the
function definition.


I thought your main point was that your solution makes checking the
definition unnecessary.


Checking the definition is necessary only if you want to know what
exactly gets stored in the array. But it is a safe bet that the original
contents will not survive the call.
I am still not convinced and still maintain that your solution is not
better than the original. But maybe I simply don't


Then, feel free to use the many pointers solution, any time you need to
return multiple values from a function. Hopefully, I won't have to
maintain your code.

Dan


I think I have the safer and more readable solution if you want to use
array only as input parameter.

void func(const int arr[]); /* func can't write array arr */

void foo()
{
int arr[3] = { 1, 2, 3 };
func(arr);
}
Nov 13 '05 #34
Karl Heinz Buchegger wrote:
Martijn Lievaart wrote:

I'm not saying technical details can't make a difference, just
that they are in the order of a few percent most of the time.


In a german magazine (c't) there was a comparison of C#, Java and
C++ in the last issue. They compared (basically) the same program
(some tree operations on strings) to test the languages capability
on working with objects, but when doing the C++ port, the authors
showed such less C++ qualification, that they came to the wrong
conclusion. Their benchmark showed C++ nearly 2 times slower then
C# or Java and the conclusion was ... (well, I think you can
imagine what it was)

Doing a few simple modifications (pass per const reference
instead of pass per value, using += instead of +, using
std::string instead of some homegrown string class) speeded the
program significantly such that it was faster then either of
the other 2 languages.

Moral: While not caring for technical details is a good habit,
one nevertheless has to know his toolkit, to select the right
tool for the right job. And of course: knowing typical idioms
helps.

But in the OP's case, I expect no critical speed difference at
all.


This is reminiscent of the fairly famous BWK "Why Pascal is not my
Favorite Language" essay, which is also seriously flawed. Such
comparisons should only be done by farming out each language
implementation to someone who is truly expert in that language.
BWK was adequate, but not expert, in Pascal, unlike his
capabilities in C, and was frustrated by inabilities to map Cisms
into Pascal.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #35

"Gene Wirchenko" <gw**************@CAPITALSwencomine.com> wrote in message
news:9d********************************@4ax.com...
On 22 Oct 2003 03:27:25 -0700, de*********@hotmail.com (Gavin Deane)
wrote:
"jeffc" <no****@nowhere.com> wrote in message news:<3f********@news1.prserv.net>...
> > At this point, he's *learning* about efficiency
> > so he has some knowledge to make that call later.
> > I seriously doubt he's interested in speeding up a throwaway program. >
> Premature optimization is a sin.


A mortal sin.


On the other hand, many programmers never learn basic efficient techniques.
(Why do we pass parameters as const reference? This is simply "accepted C++
technique" and is not "premature optimization". It is simply optimization.)
There are reasons for the code bloat and general sluggishness of many of
today's programs, and some of it is due to the fact that some programmers
simply don't get it. I repeat: one does not need to be involved in
"performance tuning" to be interested in generic efficiency. And I know
most readers agree with me too, whether that admit it or not - most
solutions here are relatively efficient, even when less efficient answers
would work.
Nov 13 '05 #36
On Wed, 22 Oct 2003 18:05:46 GMT, CBFalconer <cb********@yahoo.com>
wrote:

[snip]
This is reminiscent of the fairly famous BWK "Why Pascal is not my
Favorite Language" essay, which is also seriously flawed. Such
comparisons should only be done by farming out each language
implementation to someone who is truly expert in that language.
BWK was adequate, but not expert, in Pascal, unlike his
capabilities in C, and was frustrated by inabilities to map Cisms
into Pascal.


Pah! I was not a C programmer when I read it, and I found it
echoed my problems.

Standard Pascal, at least at the time of BWK's article, was very
weak. Note that BWK clearly stated he was looking for portability.
That is not something only of interest to C programmers.

Sincerely,

Gene Wirchenko

Nov 13 '05 #37
On Wed, 22 Oct 2003 14:02:29 -0400, "jeffc" <no****@nowhere.com>
wrote:
"Gene Wirchenko" <gw**************@CAPITALSwencomine.com> wrote in message
news:9d********************************@4ax.com.. .
[snip]
>> > Premature optimization is a sin.


A mortal sin.


On the other hand, many programmers never learn basic efficient techniques.
(Why do we pass parameters as const reference? This is simply "accepted C++
technique" and is not "premature optimization". It is simply optimization.)


No, it is doing things properly.

There is little decision that needs to be made. How is the
formal parameter used? That determines the declaration. Where is the
optimisation?

OTOH, figuring out which algorithm is the best choice for a
particular application could be much more involved. (A bubble sort is
sometimes a better choice than a quicksort. (For one, it preserves
any existing key-independent ordering.))
There are reasons for the code bloat and general sluggishness of many of
today's programs, and some of it is due to the fact that some programmers
simply don't get it. I repeat: one does not need to be involved in
"performance tuning" to be interested in generic efficiency. And I know
most readers agree with me too, whether that admit it or not - most
solutions here are relatively efficient, even when less efficient answers
would work.


Oh, I agree with you. I just draw a finer distinction.

Sincerely,

Gene Wirchenko

Nov 13 '05 #38
On Wed, 22 Oct 2003 14:00:02 +0200, Karl Heinz Buchegger wrote:
Doing a few simple modifications (pass per const reference instead
of pass per value, using += instead of +, using std::string instead
of some homegrown string class) speeded the program significantly
such that it was faster then either of the other 2 languages.

Moral: While not caring for technical details is a good habit, one
nevertheless has to know his toolkit, to select the right tool for
the right job. And of course: knowing typical idioms helps.


Yes, I understated (is there such a word?) the gain one can get, in some
cases this /can/ be significant.

Also, using simple idioms (passing by const reference is very important,
and not only for efficiency btw) one can avoid some performance pennalties.

But I tried to echo your sentiment about the obsession with speed some
newbies have. Hey I program 95% in Perl nowadays, I seldom reprogram in
another language for speed. Speed just seldom is an issue anymore.

But to the OP, there are some easy ways to avoid inefficiencies.
F.I. knowing about passing by value and by reference can save potential
copies, and those copies can be expensive. As you have to learn about
these issues anyhow, you'll learn to avoid needless copies as well.

M4

Nov 13 '05 #39
Gene Wirchenko <gw**************@CAPITALSwencomine.com> wrote in message news:<9d********************************@4ax.com>. ..
If an inexperienced programmer asks about efficiency, as the OP did, I
think it is valuable to point out that their main concern should be
other things. Many will not know this - I didn't know it until the
first time someone told me. If the OP comes back and says "Yes, I know
that, but I want to learn about enhancing performance for when it is
necessary" then fine. But I've never seen that happen here so I expect
in most cases people are focusing on efficiency for the wrong reasons
and hopefully benefit from the advice. The point made elsethread that


How does one compute digital sums?

You can follow the method implied by the definition: computing
sum of digits and using that as the new number until you get a
single-digit result. You can focus on coding something that very
efficiently performs this algorithm.

Or you could use different algorithm. Digital sum is little more
than a wrapper around a single modulo 9 division.

You are rather less likely to come up with the second method
unless you know your tools.


Although there will be times when clear, readable code is more
important then using the fastest algorithm. If the fast code is
unclear and requires significant documenting to explain it, that can
be a Bad Thing.

Digital sum is probably not a very good specific example, but the
principle is valid.

GJD
Nov 13 '05 #40
On Tue, 21 Oct 2003 11:14:12 -0700, E. Robert Tisdale wrote:
Premature optimization is a sin.
Absolutely.
Write code that is easy to read, understand and maintain.
Absolutely.
Exhaust your compiler's optimization options first.
Shop around for a better optimizing compiler second.
Only then should you run your profiler
and consider cobbling your code to make it run faster.


I don't completely agree here.

First, investigate it. Is it really the program that's causing the delay?
F.I. network protocols without some form of pipelining often are a
bottleneck. I've seen cases where the networkcard was experiencing
congestion becuase of a low mtu. Or is disk I/O the bottleneck? Sometimes
you cannot tell without a profiler, but I found that fairly simple
measurements can give a lot of insight.

I've seen to often that optimization options introduce compiler bugs to
play with them lightly. Also, deviating from the default optimization most
often gives only marginal gains, though for some programs the savings can
be enormous.

An other compiler is often not an option. F.I. opensource often only
compiles on gcc. OTOH, it's an option that is often overlooked. Intel
makes some fairly good compilers that should be drop in replacements for
others (most notably MSVC). A big win if you do numbercrunching.

And before switching compilers, you should profile. More often than not,
some fairly simple changes can make a huge difference. More intelligent
algrithms are the number one efficiency gain, often speeding up a program
by several orders. Switching to non-blocking I/O is another good one
sometimes. I once found through profiling that a program was busy about
20% of the time in converting UTF-8 to and from UCS32. Some simple caching
on this (a 5 minutes patch, isn't encapsulation wonderful) saved that 20%
almost completely.

Just doing a code review can be helpful, sometimes you find that you copy
objects needlessly. Sometimes it helps to break encapsulation to avoid
copies. But first profile to see if this is where the bottlenecks are.

But the number one advice still is measure, measure, measure. Start with
some real world tests and time them. Zoom in on the bottlenecks, some
print statements in the code can be a cheap and effective profiler. Don't
assume, measure. Programmers are notoriously bad at optimizing by
experience, so you need hard facts.

M4

Nov 13 '05 #41
In article <6d**************************@posting.google.com >,
de*********@hotmail.com says...

[ ... ]
Although there will be times when clear, readable code is more
important then using the fastest algorithm.


In my experience, you can expand this a bit: in many cases the
theoretically fastest algorithm is a truly heinous beast -- large,
complex, fragile and difficult to get truly correct. In most cases
there is also, however, an algorithm that's very close to as fast, but
it MUCH smaller, simpler and easier to get right. The vast majority of
the time, the latter is the one you really want.

A case in point would be string searching: Boyer-Moore string searching
is theoretically optimal -- it reduces the number of comparisons
involved to the minimum possible level for the job it does.
Unfortunately, it's sufficiently complex that as far as I can tell,
nobody published a correct implementation for at least 20 years after
the algorithm itself was published.

The obvious alternative is Sunday's variant of Boyer-Moore-Horspool --
which will often be faster in reality, because its setup is quicker.
It's also enough simpler that you can often progress from an explanation
of the algorithm to a correct implementation in less than an hour.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Nov 13 '05 #42

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Krackers | last post by:
How do you write a function which returns a reference to an array. I can only get a function to return a copy of the array itself. I've had a look at some other threads in this group an the return...
9
by: mjm | last post by:
Folks, Stroustrup indicates that returning by value can be faster than returning by reference but gives no details as to the size of the returned object up to which this holds. My question is...
7
by: Dr John Stockton | last post by:
What are the best ways of returning multiple results from a subroutine ? I've been using ... return } which is inelegant. I'm used to Pascal's procedure X(const A, B : integer; var C, D :...
17
by: Roland Hall | last post by:
Is there a way to return multiple values from a function without using an array? Would a dictionary object work better? -- Roland Hall /* This information is distributed in the hope that it...
1
by: Guha | last post by:
I have a problem with returning a 2D array using a function which is called in main(). The piece of the code is given below. This is a test code only. #include"stdio.h" #include"alloc.h" ...
9
by: Karl O. Pinc | last post by:
I want to return multiple values, but not a set, only a single row, from a plpgsql function and I can't seem to get it to work. (I suppose I'd be happy to return a set, but I can't seem to make...
14
by: Fabian Steiner | last post by:
Hello! I have got a Python "Device" Object which has got a attribute (list) called children which my contain several other "Device" objects. I implemented it this way in order to achieve a kind...
4
by: scparker | last post by:
Hello, We have a stored procedure that does a basic insert of values. I am then able to retrieve the ID number created for this new record. We are currently using ASP.NET 2.0 and use N-Tier...
0
by: anuptosh | last post by:
Hi, I have been trying to run the below example to get a Oracle Array as an output from a Java code. This is an example I have found on the web. But, the expected result is that the code should...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.