By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,220 Members | 1,542 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,220 IT Pros & Developers. It's quick & easy.

debugging... dereferencing, & etc.

P: n/a
Hi,

I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

- - - - - - -
#include <iostream>
using namespace std;

#define DAYS 7

int main()
{
void bsort(char **, int);

char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"};

cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

bsort(p_string, DAYS);

cout << "After sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

return 0;
}

void bsort(char **ptr, int n)
{
void order(char*&, char*&);
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(ptr[j], ptr[k]);
}

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}
- - - - -

It runs fine (just copy/paste)...

There are 2 posibilites (at least) that works:

The above has prototype inside bsort:

1) void order(char*&, char*&);

.... and:

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

- - - - - - - - - - - - - - - - - - - - - -
But.... I can also do (prototype instide bsort):

2) void order(char*, char*);

.... and:

void order(char* pp1, char* pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

This also works...

- - - - - - - - - - -

The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

- - - - - - - - - - -

So the difference between method 1 and 2 is??? I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????

There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it :-)
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 25 '06 #1
Share this Question
Share on Google+
28 Replies


P: n/a
Martin Jørgensen wrote:
I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

- - - - - - -
#include <iostream>
using namespace std;

#define DAYS 7

int main()
{
void bsort(char **, int);

char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
Ought to be

char const *p_strings[DAYS] = ...

(note the 'const').
"Wednesday", "Thursday",
"Friday", "Saturday"};

cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

bsort(p_string, DAYS);

cout << "After sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

return 0;
}

void bsort(char **ptr, int n)
void bsort(char const **pptr, int n)
{
void order(char*&, char*&);
void order(char const*&, char const*&);
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(ptr[j], ptr[k]);
}

void order(char*& pp1, char*& pp2)
void order(char const*& pp1, char const*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
std::swap(pp1, pp2);
}
}
- - - - -

It runs fine (just copy/paste)...

There are 2 posibilites (at least) that works:

The above has prototype inside bsort:

1) void order(char*&, char*&);

... and:

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

- - - - - - - - - - - - - - - - - - - - - -
But.... I can also do (prototype instide bsort):

2) void order(char*, char*);

... and:

void order(char* pp1, char* pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

This also works...
No, it doesn't. Did you try it?
- - - - - - - - - - -

The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

- - - - - - - - - - -

So the difference between method 1 and 2 is???
Run them. Does 1 sort the pointers? Does 2?
I didn't quite
understand it, but obviously there are 2 different ways in which the
program works.
Huh? These are two different programs.
I see that method 2 directly shows (sunday) or
(monday) or whatever from inside the debugger.
Who cares about the debugger? What's the output of the program?
Have you actually bothered to look at it?
Method 1 has a strange
@ in front of the address and it doesn't show (sunday/monday). What's
that @-thing? I would assume this &-means alias to/reference to????
Ask in the newsgroup that deals with your debugger.
There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it
:-)


I have no idea what you mean.

V
--
Please remove capital As from my address when replying by mail
Mar 25 '06 #2

P: n/a
Victor Bazarov wrote:
-snip-
Ask in the newsgroup that deals with your debugger.


I don't think you're good enough at C++ programming to understand the
code...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 25 '06 #3

P: n/a

Martin Jørgensen skrev:
Victor Bazarov wrote:
-snip-
Ask in the newsgroup that deals with your debugger.
I don't think you're good enough at C++ programming to understand the
code...

Surely if you follow this newsgroup for just the shortest amount of
time, you'll know that Victor knows more than enough about C++ to
answer just about anything here.
And a quick glance at your code just as easily convinces us that you
should take some time off studying C++ just so that you some day might
have a C++ program to ask questions about.

/Peter

Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk


Mar 25 '06 #4

P: n/a
peter koch wrote:
Martin Jørgensen skrev:

Victor Bazarov wrote:
-snip-

Ask in the newsgroup that deals with your debugger.
I don't think you're good enough at C++ programming to understand the
code...


Surely if you follow this newsgroup for just the shortest amount of
time, you'll know that Victor knows more than enough about C++ to
answer just about anything here.


Well, sorry about that but I would assume that understanding references
and pointers in C++ could be enough to explain what the difference is
between method 1 and 2. I see that one of the methods doesn't sort the
pointers, but both run fine and I don't understand why one sorts the
pointers and the other doesn't.

And that @ could perhaps be easy to guess what means, for a C++
programmer. If that is very difficult to understand, then I misjudged
Victor's understanding, since I thought that was easy for a C++
programmer to realize what meant - just by having a basic understanding
of the program.
And a quick glance at your code just as easily convinces us that you
should take some time off studying C++ just so that you some day might
have a C++ program to ask questions about.


That is ridicouls. You don't think this a C++ program? What do you think
it is then? Do you think it is a Matlab program? A Fortran program? No,
I can't guess what you think the programming language for the posted
code is.
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 25 '06 #5

P: n/a
* Martin Jørgensen:

I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

- - - - - - -
#include <iostream>
using namespace std;

#define DAYS 7
In C++ preferentially don't use macros: use typed constants, e.g.

int const nDays = 7;

int main()
{
void bsort(char **, int);
Please don't declare functions within other functions.

And in general, it's a good idea to not forward-declare functions unless
mutual recursion is needed.

Instead, just define the functions in the order needed to avoid
forward-declarations (that can help you straighten out the code).

char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"};
Make those strings 'const'.

cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;
Preferentially use '++j' instead of 'j++' (just a good habit, never
invoke more functionality than what you're actually interested in).

bsort(p_string, DAYS);

cout << "After sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;
Preferentially use '++j' instead of 'j++' (just a good habit, never
invoke more functionality than what you're actually interested in).

Also, whenever you repeat code like this, consider defining a function.

Code redundancy is generally evil: it leads to maintenance problems.
return 0;
}

void bsort(char **ptr, int n)
{
void order(char*&, char*&);
Please don't declare functions within other functions.

And in general, it's a good idea to not forward-declare functions unless
mutual recursion is needed.

Instead, just define the functions in the order needed to avoid
forward-declarations (that can help you straighten out the code).
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(ptr[j], ptr[k]);
}

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}
Although this is C, not C++, you're probably trying to learn C++, so as
a first step: look up std::swap.

- - - - -

It runs fine (just copy/paste)...

There are 2 posibilites (at least) that works:

The above has prototype inside bsort:

1) void order(char*&, char*&);

... and:

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

- - - - - - - - - - - - - - - - - - - - - -
But.... I can also do (prototype instide bsort):

2) void order(char*, char*);

... and:

void order(char* pp1, char* pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

This also works...
No, it doesn't, if by "works" you mean that it sorts things.

In case (2) you are passing the pointers by value, and exchanging the
local copies, not affecting anything outside the 'order' function.

- - - - - - - - - - -

The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64
That's probably the memory addresses of the pointers. This is
tool-dependent. Since there are several items of information relevant
to e.g. 'pp1' (address of pointer, pointer value, value that it points
to) you have to consult your debugger's documentation about how to
display other items of information: you're seeing just one.

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)
That's probably the memory addresses of the strings, plus string values.

- - - - - - - - - - -

So the difference between method 1 and 2 is???
See above.

But do consider writing C++ instead of C.

What book are you using? I recommend "Accelerated C++". That C stuff
is no good: it makes you really work to do very trivial things, thus
advancing very slowly.

I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????
Probably. Ask in a newsgroup where your particular toolset is on-topic. ;-)

There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it :-)


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 26 '06 #6

P: n/a
In article <ch************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:
Hi,

I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}
vs.
void order(char* pp1, char* pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

This also works...
Actually no... Read the output for each program.
The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

So the difference between method 1 and 2 is??? I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????
Yes, '&' means exactly "reference".
There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it :-)


void order(char** pp1, char** pp2)
{
if( strcmp(*pp1, *pp2) > 0)
{
char *tempptr = *pp1;
*pp1 = *pp2;
*pp2 = tempptr;
}
}

void bsort(char **ptr, int n)
{
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(&ptr[j], &ptr[k]);
}

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 26 '06 #7

P: n/a
Me
Martin Jørgensen wrote:
order(ptr[j], ptr[k]); ... void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
} vs void order(char* pp1, char* pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)
No, the difference between the two is that the first way (which
actually works) is basically a shortcut for:

order(&ptr[j], &ptr[k]);

void order(char **pp1, char **pp2)
{
if (strcmp(*pp1, *pp2) > 0) {
char *tempptr = *pp1;
*pp1 = *pp2;
*pp2 = tempptr;
}
}

and the second way is:

void order(char *pp1, char *pp2)
{
/* all of this code here is useless because it just
* operates on the local variables pp1 and pp2
*/
if (strcmp(pp1, pp2) > 0) {
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}
So the difference between method 1 and 2 is??? I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????


Who knows, read your debugger's manual. Your debugger looks like it's
doing something like this:

if (expr.type() matches "T &") {
convert "&" in expr.type() to "*";
}
if (expr.type() matches "T *") {
if (expr.type() matches "T **") {
display("@", expr);
} else {
display(expr, " (");
display(dereference(expr));
display(")");
}
}

i.e. for expressions of type T & or T *, if T is a type the debugger
knows how to display, it will automatically dereference the pointer and
display what it points to.

(The above is probably a simplified version of what your debugger does.
The one I use does a variation of the above but it's smart enough to
print char * as a null terminated string but displays only a single
character for char &)

Mar 26 '06 #8

P: n/a

"Martin Jørgensen" <un*********@spam.jay.net> skrev i meddelandet
news:54************@news.tdc.dk...

Well, sorry about that but I would assume that understanding
references and pointers in C++ could be enough to explain what the
difference is between method 1 and 2. I see that one of the methods
doesn't sort the pointers, but both run fine and I don't understand
why one sorts the pointers and the other doesn't.
Yes, they both sort the pointers, but the one passing by reference
sorts actual the pointers passed to the fucntion. The other function
sorts its local copies of the parameters, not the ones passed to it.

It is a different level of indirection.
And a quick glance at your code just as easily convinces us that
you
should take some time off studying C++ just so that you some day
might
have a C++ program to ask questions about.


That is ridicouls. You don't think this a C++ program? What do you
think it is then? Do you think it is a Matlab program? A Fortran
program? No, I can't guess what you think the programming language
for the posted code is.


It actually looks very much like C code, with just some C++ added.
Sorry! :-)
Bo Persson
Mar 26 '06 #9

P: n/a
Bo Persson wrote:
"Martin Jørgensen" <un*********@spam.jay.net> skrev i meddelandet
news:54************@news.tdc.dk...
Well, sorry about that but I would assume that understanding
references and pointers in C++ could be enough to explain what the
difference is between method 1 and 2. I see that one of the methods
doesn't sort the pointers, but both run fine and I don't understand
why one sorts the pointers and the other doesn't.

Yes, they both sort the pointers, but the one passing by reference
sorts actual the pointers passed to the fucntion. The other function
sorts its local copies of the parameters, not the ones passed to it.

It is a different level of indirection.


Oh, yeah... The one with the copies doesn't work ofcourse.
And a quick glance at your code just as easily convinces us that
you
should take some time off studying C++ just so that you some day
might
have a C++ program to ask questions about.


That is ridicouls. You don't think this a C++ program? What do you
think it is then? Do you think it is a Matlab program? A Fortran
program? No, I can't guess what you think the programming language
for the posted code is.

It actually looks very much like C code, with just some C++ added.
Sorry! :-)


Well, as long as it compiles with no errors with g++ I consider it c++
code, unless there is a problem with g++ which I don't hope.
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #10

P: n/a
Daniel T. wrote:
In article <ch************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote: -snip-
Actually no... Read the output for each program.


I think I posted the wrong code somehow and first realized it today...
The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

So the difference between method 1 and 2 is??? I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????

Yes, '&' means exactly "reference".


It also means: Pass the address of that variable, doesn't it?
There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it :-)

void order(char** pp1, char** pp2)
{
if( strcmp(*pp1, *pp2) > 0)
{
char *tempptr = *pp1;
*pp1 = *pp2;
*pp2 = tempptr;
}
}

void bsort(char **ptr, int n)
{
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(&ptr[j], &ptr[k]);
}


EXACTLY! Thanks for posting that... See my other replies.
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #11

P: n/a
Daniel T. wrote:
In article <ch************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:

-snip-

New code - I hope this is better than the old (but what the hell - I
enjoy reading the comments and am still learn something from it):

- - - - - - - - - - - - - - - - - -

#include <iostream>
using namespace std;

#define DAYS 7

int main()
{
void bsort(char **, int);

char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"};

cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

bsort(p_string, DAYS);

cout << "After sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

return 0;
}
/* method 1 here */
void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

void bsort(char **ptr, int n)
{
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(ptr[j], ptr[k]);
}
/* method 2 here
void order(char** pp1, char** pp2)
{
if( strcmp(*pp1, *pp2) > 0)
{
char *tempptr = *pp1;
*pp1 = *pp2;
*pp2 = tempptr;
}
}

void bsort(char **ptr, int n)
{
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(&ptr[j], &ptr[k]);
}
*/

- - - - - - - - - - - - - - - - - -

If somebody can think of other ways to reference the pointers/solve the
problem I would be interested in seeing how...

So here it is actually more interesting to learn about the difference
between method 1 and 2, I think...

As far as I can see: Method 1 takes the addresses of the pointers pp1
and pp2 as arguments... Since their addresses are arguments, there is no
need for dereferencing... hmmm... ?

Method 2 is more "strange". It needs some dereferencing, which is more
difficult to understand, IMO.....

I notice that both methods gets called to by "bsort(p_string, DAYS);",
but both the order and bsort functions differ slightly for these methods...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #12

P: n/a
Me wrote:
Martin Jørgensen wrote: -snip-
No, the difference between the two is that the first way (which
actually works) is basically a shortcut for:

order(&ptr[j], &ptr[k]);
That is the same as:

order(ptr[j], ptr[k]);

IIRC?
void order(char **pp1, char **pp2)
{
if (strcmp(*pp1, *pp2) > 0) {
char *tempptr = *pp1;
*pp1 = *pp2;
*pp2 = tempptr;
}
}


And that should be the same as:

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

This is exactly what is difficult for me to understand... hmmm. I guess
I'll have to spend some time looking at this...

-snip debugger, yes: who knows... -
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #13

P: n/a
Alf P. Steinbach wrote:
* Martin Jørgensen:

I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

- - - - - - -
#include <iostream>
using namespace std;

#define DAYS 7

In C++ preferentially don't use macros: use typed constants, e.g.

int const nDays = 7;


Ok, but why is that so when the compiler doesn't complain?
int main()
{
void bsort(char **, int);

Please don't declare functions within other functions.

And in general, it's a good idea to not forward-declare functions unless
mutual recursion is needed.


I thought "forward-declaring" was necessary if you mean putting
prototypes in the top of the program?
Instead, just define the functions in the order needed to avoid
forward-declarations (that can help you straighten out the code).
Isn't that just a matter of taste? Sometimes I like to have main() in
the top of the program and insert prototypes... Or is there a specific
reason for that?
char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"};

Make those strings 'const'.


hmm... I couldn't... I get something like:

test.cpp:18: error: invalid conversion from 'const char**' to 'char**'
test.cpp:18: error: initializing argument 1 of 'void bsort(char**, int)'

And I tried:
const char *p_string[DAYS] ...
char const *p_string[DAYS] ....
cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

Preferentially use '++j' instead of 'j++' (just a good habit, never
invoke more functionality than what you're actually interested in).


That's is wrong here, isn't it? I didn't test it, but I would guess then
j would go from 1 to 7 which is wrong (it should go from 0->6).
bsort(p_string, DAYS);

cout << "After sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

Preferentially use '++j' instead of 'j++' (just a good habit, never
invoke more functionality than what you're actually interested in).

Also, whenever you repeat code like this, consider defining a function.

Code redundancy is generally evil: it leads to maintenance problems.


Agreed, thanks.
return 0;
}

void bsort(char **ptr, int n)
{
void order(char*&, char*&);

Please don't declare functions within other functions.


Also if they're not used anywhere else for sure?
And in general, it's a good idea to not forward-declare functions unless
mutual recursion is needed.
Not sure I understood what you meant by "forward-declaring"?
Instead, just define the functions in the order needed to avoid
forward-declarations (that can help you straighten out the code).
int j,k;

for(j=0; j<n-1; j++)
for(k=j+1; k<n; k++)
order(ptr[j], ptr[k]);
}

void order(char*& pp1, char*& pp2)
{
if( strcmp(pp1, pp2) > 0)
{
char *tempptr = pp1;
pp1 = pp2;
pp2 = tempptr;
}
}

Although this is C, not C++, you're probably trying to learn C++, so as
a first step: look up std::swap.


Yeah, I know that... But I think it's also important to learn to use
pointers correctly, which I'm trying now...

-snip-
This also works...

No, it doesn't, if by "works" you mean that it sorts things.

In case (2) you are passing the pointers by value, and exchanging the
local copies, not affecting anything outside the 'order' function.


Damn... I think I screwed up and posted the wrong code.... :-(

That is really embarrassing... I had two functions that I believed
sorted these char-arrays correctly yesterday at some moment.... But what
the heck. Se my other post with the new code - I took it from Daniel T's
posting and AFAIR that was also how my code was at some point earlier
yesterday...
The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

That's probably the memory addresses of the pointers. This is
tool-dependent. Since there are several items of information relevant
to e.g. 'pp1' (address of pointer, pointer value, value that it points
to) you have to consult your debugger's documentation about how to
display other items of information: you're seeing just one.


It could mean that it is an automatic generated variable that only
exists inside the function, couldn't it?
and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

That's probably the memory addresses of the strings, plus string values.


Yes. That is true and verified.
So the difference between method 1 and 2 is???

See above.

But do consider writing C++ instead of C.

What book are you using? I recommend "Accelerated C++". That C stuff
is no good: it makes you really work to do very trivial things, thus
advancing very slowly.


It's called "Object-oriented programming in C++", 4.ed, by Robert
Lafore... It says that more than 100.000 copies worldwide has been sold.

But I would also like to learn C so it's not that bad for me...
I didn't quite understand it, but obviously there are 2 different ways
in which the program works. I see that method 2 directly shows
(sunday) or (monday) or whatever from inside the debugger. Method 1
has a strange @ in front of the address and it doesn't show
(sunday/monday). What's that @-thing? I would assume this &-means
alias to/reference to????

Probably. Ask in a newsgroup where your particular toolset is on-topic.
;-)


I'm pretty sure that it means something like: the variable is an
automatic generated variable and it only exists inside the function
itself...
There are probably also other methods this program could work.... If
anyone wants to tell, go on and I hope I can learn to understand it :-)


Just as Daniel T. and "me" understood, I think...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #14

P: n/a
* Martin Jørgensen:
Alf P. Steinbach wrote:
* Martin Jørgensen:

I have a "funny" question, which I think is pretty "healthy" to
examine... This program is being investigated:

- - - - - - -
#include <iostream>
using namespace std;

#define DAYS 7

In C++ preferentially don't use macros: use typed constants, e.g.

int const nDays = 7;


Ok, but why is that so when the compiler doesn't complain?


The compiler doesn't complain about bad code.

For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).
int main()
{
void bsort(char **, int);

Please don't declare functions within other functions.

And in general, it's a good idea to not forward-declare functions
unless mutual recursion is needed.


I thought "forward-declaring" was necessary if you mean putting
prototypes in the top of the program?


There's no good reason to put prototypes at the top of the program text,
or anywhere else, for a single-source non-recursive program.

Instead, just define the functions in the order needed to avoid
forward-declarations (that can help you straighten out the code).


Isn't that just a matter of taste? Sometimes I like to have main() in
the top of the program and insert prototypes... Or is there a specific
reason for that?


Avoid redundancy.

char *p_string[DAYS] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"};

Make those strings 'const'.


hmm... I couldn't... I get something like:

test.cpp:18: error: invalid conversion from 'const char**' to 'char**'
test.cpp:18: error: initializing argument 1 of 'void bsort(char**, int)'


You need to fix your function signatures also.

With prototypes you also have to fix the prototypes.

But instead, just remove them, delete them, burn them.

cout << "Before sorting the pointers:\n\n";
for(int j=0; j<DAYS; j++)
cout << p_string[j] << endl;

Preferentially use '++j' instead of 'j++' (just a good habit, never
invoke more functionality than what you're actually interested in).


That's is wrong here, isn't it?


No.
I didn't test it, but I would guess then
j would go from 1 to 7 which is wrong (it should go from 0->6).


Do test before replying. Nothing is gained by arguing supposition.
Please don't declare functions within other functions.


Also if they're not used anywhere else for sure?


Yes.

Nothing prevents you from using the functions elsewhere.

On the other hand, a convention of not using prototypes imposes a
constraint where you can rule out that f calls g by name if f precedes g
in the source code.

And in general, it's a good idea to not forward-declare functions
unless mutual recursion is needed.


Not sure I understood what you meant by "forward-declaring"?


Those prototypes, get rid of them.

What book are you using? I recommend "Accelerated C++". That C stuff
is no good: it makes you really work to do very trivial things, thus
advancing very slowly.


It's called "Object-oriented programming in C++", 4.ed, by Robert
Lafore... It says that more than 100.000 copies worldwide has been sold.


<url:
http://accu.org/index.php/book_reviews?url=view.xqy?review=o003132&term=lafo re>

Francis Glassborow: "I cannot recommend this book as it is".
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 26 '06 #15

P: n/a
In article <vi************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:
Daniel T. wrote:
In article <ch************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:

-snip-
Actually no... Read the output for each program.


I think I posted the wrong code somehow and first realized it today...
The difference between 1 and 2 is that if I place a breakpoint inside
order(), my debugger shows that using method...

1) pp1 = @0xbffffa60, pp2 = @0xbffffa64

and using the other method:

2) pp1 = 0xde80 (sunday), pp2 = 0xde8c (monday)

So the difference between method 1 and 2 is??? I didn't quite understand
it, but obviously there are 2 different ways in which the program works.
I see that method 2 directly shows (sunday) or (monday) or whatever from
inside the debugger. Method 1 has a strange @ in front of the address
and it doesn't show (sunday/monday). What's that @-thing? I would assume
this &-means alias to/reference to????

Yes, '&' means exactly "reference".


It also means: Pass the address of that variable, doesn't it?


Yes. A shame I think but something you "just have to know."
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 26 '06 #16

P: n/a
In article <on************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:
If somebody can think of other ways to reference the pointers/solve the
problem I would be interested in seeing how...


You could do it the way the standard library functions do it:

bool in_order( const char* left, const char* right )
{
return strcmp( left, right ) < 0;
}

void bsort( const char** first, const char** last )
{
while ( first != last ) {
for ( const char** next = first + 1; next != last; ++next ) {
if ( ! in_order( *first, *next ) )
swap( *first, *next );
}
++first;
}
}

which would be called by:

bsort( p_string, p_string + days );

Then you generalize that to:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
{
while ( first != last ) {
for ( T next = first + 1; next != last; ++next ) {
if ( ! ordered( *first, *next ) )
swap( *first, *next );
}
++first;
}
}

Which can be called by:

bsort( p_string, p_string + days, &in_order );

and can also be used to sort other types. For example:

int p_ints[days] = { 3, 1, 5, 6, 4, 0, 2 };

bsort( p_ints, p_ints + days, less<int>() );

(std::less<T> is defined in <functional>)
But it still won't work with std::list, because it requires random
access iterators. So let's fix that:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
{
while ( first != last ) {
T next = first;
std::advance( next, 1 );
for ( ; next != last; ++next )
if ( ! ordered( *first, *next ) )
std::swap( *first, *next );
++first;
}
}

And now we have a general purpose bubble sort function that can work
with any type of container that might need sorting, compare any type of
element, and sort it in any order the user wants.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 26 '06 #17

P: n/a
Alf P. Steinbach wrote:
* Martin Jørgensen:

-snip-
In C++ preferentially don't use macros: use typed constants, e.g.

int const nDays = 7;

Ok, but why is that so when the compiler doesn't complain?

The compiler doesn't complain about bad code.

For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).


Question 97 here: http://www.cs.indiana.edu/~zlu/cpp_faq.html ?

Or here http://public.research.att.com/~bs/bs_faq.html ?

I didn't find any good enough reason for avoiding #define here even
though I tried.

-snip-
What book are you using? I recommend "Accelerated C++". That C
stuff is no good: it makes you really work to do very trivial things,
thus advancing very slowly.

It's called "Object-oriented programming in C++", 4.ed, by Robert
Lafore... It says that more than 100.000 copies worldwide has been sold.

<url:
http://accu.org/index.php/book_reviews?url=view.xqy?review=o003132&term=lafo re>
Francis Glassborow: "I cannot recommend this book as it is".


I find that criticism to be too hard. It's a thick book consisting of
about 1000 pages with plenty of examples which I like very much... But
now I have it, so I won't throw it out.
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #18

P: n/a
Daniel T. wrote:
In article <on************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:

If somebody can think of other ways to reference the pointers/solve the
problem I would be interested in seeing how...

You could do it the way the standard library functions do it:

bool in_order( const char* left, const char* right )
{
return strcmp( left, right ) < 0;
}

void bsort( const char** first, const char** last )
{
while ( first != last ) {
for ( const char** next = first + 1; next != last; ++next ) {
if ( ! in_order( *first, *next ) )
swap( *first, *next );
}
++first;
}
}


Very nice... Is char **first the same as first[0][0] and also the same
as &first? I keep believing that, anyway - don't know why...
which would be called by:

bsort( p_string, p_string + days );

Then you generalize that to:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
Huh? What's that template/typename-line doing?
{
while ( first != last ) {
for ( T next = first + 1; next != last; ++next ) {
if ( ! ordered( *first, *next ) )
swap( *first, *next );
}
++first;
}
}

Which can be called by:

bsort( p_string, p_string + days, &in_order );

and can also be used to sort other types. For example:

int p_ints[days] = { 3, 1, 5, 6, 4, 0, 2 };

bsort( p_ints, p_ints + days, less<int>() );

(std::less<T> is defined in <functional>)
Never heard about that...
But it still won't work with std::list, because it requires random
access iterators. So let's fix that:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
{
while ( first != last ) {
T next = first;
std::advance( next, 1 );
for ( ; next != last; ++next )
if ( ! ordered( *first, *next ) )
std::swap( *first, *next );
++first;
}
}
I didn't learn about iterators yet, although I read something about it
(but didn't understood it)... In a few weeks, I'll probably know what it
means...
And now we have a general purpose bubble sort function that can work
with any type of container that might need sorting, compare any type of
element, and sort it in any order the user wants.


Nice... I'll have to look at this code, once I learn (more) about
iterators which I don't really know anything about now... :-(
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 26 '06 #19

P: n/a
* Martin Jørgensen:
Alf P. Steinbach wrote:
For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).
Question 97 here: http://www.cs.indiana.edu/~zlu/cpp_faq.html ?


Uh, it's almost an achievement to find a 10 year old version of the FAQ!
I couldn't if I tried. The current FAQ for this group comes on top of
Google's hit list when I type in "C++ FAQ".

See e.g. <url: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7>.
Or here http://public.research.att.com/~bs/bs_faq.html ?
Nearly there!

Good.

Just two mouse-clicks away (or was it one mouse-click), you find
<url: http://public.research.att.com/~bs/bs_faq2.html#macro>.

I didn't find any good enough reason for avoiding #define here even
though I tried.


Well, the important thing is that you tried. Hopefully, now that I've
given you direct URLs, next time you'll have a better idea how to find
the most relevant passages. And so on, so in a few months, you'll be
helping others here! :-)
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 27 '06 #20

P: n/a
Me
Martin Jørgensen wrote:
void order(char **pp1, char **pp2)

And that should be the same as:

void order(char*& pp1, char*& pp2)

This is exactly what is difficult for me to understand... hmmm. I guess
I'll have to spend some time looking at this...


It's simple, just keep in mind that in C++, *every* type is passed by
value (except for arrays but I'd consider that more like automatic
decomposition into pointers):

void foo(int a)
{
++a;
}

int j = 0;
foo(j);
foo(10); // works

after the call to foo, j is still 0.

void foo(int *a)
{
++*a;
}

int j = 0;
foo(&j);
foo(&10); // error

after the call to foo, j is 1.

void foo(int &a)
{
++a;
}

int j = 0;
foo(j);
foo(10); // error

after the call to foo, j is 1.

For the most part, T &var is exactly the same thing as T * const var
(which is one reason why it has to be initialized and can't be
reassigned later) except having a reference type buys you more things
over just having a pointer. One of the major ones is that the null
reference, *(T*)0, is undefined and with all this combined, this is how
C++ gets away with treating the reference as an automatically
dereferenced pointer.

What's really going to bake your noodle is this:

void foo(const int *a)
{
cout << *a;
}

int j = 0;
foo(&a);
foo(&10); // error

void foo(const int &a)
{
cout << a;
}

int j = 0;
foo(j);
foo(10); // ok

What happens here is that the compiler creates a temporary:

const int dummy = 10;
foo(dummy);

It used to work for regular references but it lead to very hard to
detect bugs like this one:

void foo(int &a)
{
++a;
}

float f = 0;
foo(f); // ok in ancient C++

because the compiler would turn this into:

float f = 0;
int dummy = f;
foo(dummy);
// whoops, the temporary gets incremented but not f

Mar 27 '06 #21

P: n/a
On 2006-03-27, Alf P. Steinbach <al***@start.no> wrote:
* Martin Jørgensen:
Alf P. Steinbach wrote:
For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).
Question 97 here: http://www.cs.indiana.edu/~zlu/cpp_faq.html ?


Uh, it's almost an achievement to find a 10 year old version of the FAQ!
I couldn't if I tried. The current FAQ for this group comes on top of
Google's hit list when I type in "C++ FAQ".


In fairness, that depends on the google being used : it varies on
locale from country to country.
Well, the important thing is that you tried. Hopefully, now that I've
given you direct URLs, next time you'll have a better idea how to find
the most relevant passages. And so on, so in a few months, you'll be
helping others here! :-)


hear hear
Mar 27 '06 #22

P: n/a
In article <91************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:
Daniel T. wrote:
In article <on************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:

If somebody can think of other ways to reference the pointers/solve the
problem I would be interested in seeing how...

You could do it the way the standard library functions do it:

bool in_order( const char* left, const char* right )
{
return strcmp( left, right ) < 0;
}

void bsort( const char** first, const char** last )
{
while ( first != last ) {
for ( const char** next = first + 1; next != last; ++next ) {
if ( ! in_order( *first, *next ) )
swap( *first, *next );
}
++first;
}
}


Very nice... Is char **first the same as first[0][0] and also the same
as &first? I keep believing that, anyway - don't know why...


I don't know why ether, they're all different types.

which would be called by:

bsort( p_string, p_string + days );

Then you generalize that to:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )


Huh? What's that template/typename-line doing?


Baby steps now... You'll get to it.

{
while ( first != last ) {
for ( T next = first + 1; next != last; ++next ) {
if ( ! ordered( *first, *next ) )
swap( *first, *next );
}
++first;
}
}

Which can be called by:

bsort( p_string, p_string + days, &in_order );

and can also be used to sort other types. For example:

int p_ints[days] = { 3, 1, 5, 6, 4, 0, 2 };

bsort( p_ints, p_ints + days, less<int>() );

(std::less<T> is defined in <functional>)


Never heard about that...


Again, you are learning the language from the inside out. There are all
kinds of useful things that your book simply hasn't bothered to tell you
about. Instead your book is teaching you about parts that should only be
for experts. Thus making it much harder on you than it should be. :-(

But it still won't work with std::list, because it requires random
access iterators. So let's fix that:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
{
while ( first != last ) {
T next = first;
std::advance( next, 1 );
for ( ; next != last; ++next )
if ( ! ordered( *first, *next ) )
std::swap( *first, *next );
++first;
}
}


I didn't learn about iterators yet, although I read something about it
(but didn't understood it)... In a few weeks, I'll probably know what it
means...


It's simple. An iterator is an object that acts in some ways like a
pointer. There are several kinds of iterators, some act more like
pointers than others.

And now we have a general purpose bubble sort function that can work
with any type of container that might need sorting, compare any type of
element, and sort it in any order the user wants.


Nice... I'll have to look at this code, once I learn (more) about
iterators which I don't really know anything about now... :-(


Sure you do, a pointer *is* an iterator.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 27 '06 #23

P: n/a
In article <tr************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:
Alf P. Steinbach wrote:
* Martin Jørgensen:

-snip-
In C++ preferentially don't use macros: use typed constants, e.g.

int const nDays = 7;
Ok, but why is that so when the compiler doesn't complain?

The compiler doesn't complain about bad code.

For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).


Question 97 here: http://www.cs.indiana.edu/~zlu/cpp_faq.html ?

Or here http://public.research.att.com/~bs/bs_faq.html ?

I didn't find any good enough reason for avoiding #define here even
though I tried.


Try here:
<http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7>

What book are you using? I recommend "Accelerated C++". That C
stuff is no good: it makes you really work to do very trivial things,
thus advancing very slowly.
It's called "Object-oriented programming in C++", 4.ed, by Robert
Lafore... It says that more than 100.000 copies worldwide has been sold.

<url:
http://accu.org/index.php/book_revie...3132&term=lafo
re>
Francis Glassborow: "I cannot recommend this book as it is".


I find that criticism to be too hard. It's a thick book consisting of
about 1000 pages with plenty of examples which I like very much... But
now I have it, so I won't throw it out.


Keep in mind, you aren't an expert in the language. The important thing
though is that the book hasn't dissuaded you from continuing to learn.

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 27 '06 #24

P: n/a
Alf P. Steinbach wrote:
* Martin Jørgensen:
Alf P. Steinbach wrote:
For reasons why you should avoid macros, see the FAQ and Bjarne
Stroustrup's FAQ.

Google to find the FAQs (that's what I'd have to do to give you URLs).

Question 97 here: http://www.cs.indiana.edu/~zlu/cpp_faq.html ?

Uh, it's almost an achievement to find a 10 year old version of the FAQ!
I couldn't if I tried. The current FAQ for this group comes on top of
Google's hit list when I type in "C++ FAQ".

See e.g. <url: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7>.


Thanks... I also think my link was in the top... Can't remember what I
searched on, but I wouldn't have clicked on it if it didn't say:
something about "official comp.lang.c++ FAQ"...
Or here http://public.research.att.com/~bs/bs_faq.html ?

Nearly there!

Good.

Just two mouse-clicks away (or was it one mouse-click), you find
<url: http://public.research.att.com/~bs/bs_faq2.html#macro>.

I didn't find any good enough reason for avoiding #define here even
though I tried.

Well, the important thing is that you tried. Hopefully, now that I've
given you direct URLs, next time you'll have a better idea how to find
the most relevant passages. And so on, so in a few months, you'll be
helping others here! :-)


I hope, although I don't know if I ever get real "professional"...
Depends on if my professor is interested in my programming skills after
this semester and at this moment I think that he thinks I'm doing a fine
job generally (although this is a new language to me).... Now I'm also
doing my bachelor project (thesis) in C but I've seen some c++ code that
we're all interested in at the department... So I think actually he
wants me to continue learning to program more :-)

I'm not trying to learn c++ for doing some kind of homework exercise or
anything... I find this modelling of thermal processes interesting (that
is what my bachelor project is about) and there are some freely
available c++ libraries available that I would like to learn to use
later on.......
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 27 '06 #25

P: n/a
Daniel T. wrote:
In article <91************@news.tdc.dk>,
Martin Jørgensen <un*********@spam.jay.net> wrote:

-snip-
Very nice... Is char **first the same as first[0][0] and also the same
as &first? I keep believing that, anyway - don't know why...

I don't know why ether, they're all different types.


Oh, yeah..... You're right... If we have:

char **first; // "pointer-to-pointer" - to-char... type: ptr.

first[0][0]; // must be of type char and,
// the first element at memory address *(*(first[0]) )
// or something... ? hmm, not sure....
// I read something like that on google (not in my book)

&first // that is the address of first...
// Isn't that type void * ? (read that on google)...
which would be called by:

bsort( p_string, p_string + days );

Then you generalize that to:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )


Huh? What's that template/typename-line doing?

Baby steps now... You'll get to it.
{
while ( first != last ) {
for ( T next = first + 1; next != last; ++next ) {
if ( ! ordered( *first, *next ) )
swap( *first, *next );
}
++first;
}
}

Which can be called by:

bsort( p_string, p_string + days, &in_order );

and can also be used to sort other types. For example:

int p_ints[days] = { 3, 1, 5, 6, 4, 0, 2 };

bsort( p_ints, p_ints + days, less<int>() );

(std::less<T> is defined in <functional>)


Never heard about that...

Again, you are learning the language from the inside out. There are all
kinds of useful things that your book simply hasn't bothered to tell you
about. Instead your book is teaching you about parts that should only be
for experts. Thus making it much harder on you than it should be. :-(


Oh... Well, at least I like to learn about pointers, because when you
make functions (which is very likely) and you need to pass variables
then I think it's really important to know what's happening...

So, I'm still struggling a bit with the above but feel comfortable with
only dereferencing a pointer-to-something (one star "*"), as mentioned
earlier...
But it still won't work with std::list, because it requires random
access iterators. So let's fix that:

template < typename T, typename Op >
void bsort( T first, T last, Op ordered )
{
while ( first != last ) {
T next = first;
std::advance( next, 1 );
for ( ; next != last; ++next )
if ( ! ordered( *first, *next ) )
std::swap( *first, *next );
++first;
}
}


I didn't learn about iterators yet, although I read something about it
(but didn't understood it)... In a few weeks, I'll probably know what it
means...

It's simple. An iterator is an object that acts in some ways like a
pointer. There are several kinds of iterators, some act more like
pointers than others.


Oh, perhaps I should take a closer look at that in my book somewhere in
the weekend...
And now we have a general purpose bubble sort function that can work
with any type of container that might need sorting, compare any type of
element, and sort it in any order the user wants.


Nice... I'll have to look at this code, once I learn (more) about
iterators which I don't really know anything about now... :-(

Sure you do, a pointer *is* an iterator.


Ok... Then I must try it out soon :-)
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 27 '06 #26

P: n/a
Me wrote:
Martin Jørgensen wrote:
void order(char **pp1, char **pp2)


And that should be the same as:

void order(char*& pp1, char*& pp2)

This is exactly what is difficult for me to understand... hmmm. I guess
I'll have to spend some time looking at this...

It's simple, just keep in mind that in C++, *every* type is passed by
value (except for arrays but I'd consider that more like automatic
decomposition into pointers):


Oh..... Thanks for telling that inside the paranthesis... I just want to
make sure I understand that, so I've made some example code (untested)...

int n[5] = { {0,1,2,3,4} }; // untested - perhaps syntax error here?
int * ptr; // declaration
ptr = n[0]; // ptr points to first integer value now

// method 1.
function(ptr) // is this like passing &ptr? I think it is?...

// method 2.
function(n[0]) // is this like passing &n[0] or???
If somebody has comments, I'm sure I will think about that next time
I'll have time to debug some more and watch what is going on with some
example programs that is passing values and references on to functions...
-snip-
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 28 '06 #27

P: n/a
Me
Martin Jørgensen wrote:
int n[5] = { {0,1,2,3,4} }; // untested - perhaps syntax error here?
Some compilers accept extra braces but it's non-standard. It should be:

int n[5] = { 0, 1, 2, 3, 4 };
int * ptr; // declaration
and definition
ptr = n[0]; // ptr points to first integer value now
The type of n is int[5], the type of ptr is int *, the type of n[0] is
int. You need to apply the & operator to the int expression to convert
it to int *.
// method 1.
function(ptr) // is this like passing &ptr? I think it is?...
The type of ptr is int *. The type of &ptr is int **. It would be like
passing &ptr if function was declared like:

ret function(int *&);
instead of:
ret function(int *);
// method 2.
function(n[0]) // is this like passing &n[0] or???
The type of n[0] is int. The type of &n[0] is int *. It would be like
passing &n[0] if function was declared like:

ret function(int &);
instead of:
ret function(int);
If somebody has comments, I'm sure I will think about that next time
I'll have time to debug some more and watch what is going on with some
example programs that is passing values and references on to functions...


Arrays automatically decompose into pointers in certain contexts
(^^^^this only applies to the top-level array^^^^). For example:

int a[5] = { 1, 2, 3, 4, 5 };
int *p = &a[0];
/* the compiler internally converts this to: */
int *p = &*((int*)a + 0);
/* which is exactly equivalent to: */
int *p = (int*)a + 0;
/* which can be further optimized to: */
int *p = (int*)a;
/* leading us to just simply use the following instead: */
int *p = a;

This doesn't occur with this example because it only applies to the
top-level array:

int m[1][1] = { 0 };
int (*q)[1] = a;
/* good, we can convert int[1][1] (an array of an array of ints) to int
(*)[1] (a pointer to an array of ints) */
int **q = m;
/* error, we can't convert int[1][1] to int** (a pointer to a pointer
to an int) */
And just incase you're confused about precedence, &a[0] means &(a[0])
and not (&a)[0]. There is a slight difference:

int a[5];

a[0] is int, &(a[0]) is int *
&a is int(*)[5], (&a)[0] is int[5]

Most of the time it doesn't matter, but it makes the difference with:

void fn(int (&)[5]);

fn(&a[0]); // bad
fn(a); // good
fn((&a)[0]); // good
fn(*&a); /* good, this is the same thing remember? */

See if you can work your way through the types of the expressions to
see why.

Mar 28 '06 #28

P: n/a
Me wrote:
Martin Jørgensen wrote:
int n[5] = { {0,1,2,3,4} }; // untested - perhaps syntax error here?

Some compilers accept extra braces but it's non-standard. It should be:

int n[5] = { 0, 1, 2, 3, 4 };


Thanks...
int * ptr; // declaration

and definition

ptr = n[0]; // ptr points to first integer value now

The type of n is int[5], the type of ptr is int *, the type of n[0] is
int. You need to apply the & operator to the int expression to convert
it to int *.


Oh.... Makes sense.
// method 1.
function(ptr) // is this like passing &ptr? I think it is?...

The type of ptr is int *. The type of &ptr is int **. It would be like
passing &ptr if function was declared like:

ret function(int *&);
instead of:
ret function(int *);


hmmm. I see...
// method 2.
function(n[0]) // is this like passing &n[0] or???

The type of n[0] is int. The type of &n[0] is int *. It would be like
passing &n[0] if function was declared like:

ret function(int &);
instead of:
ret function(int);


Okay... I'll have to study this a couple of times more :-)
If somebody has comments, I'm sure I will think about that next time
I'll have time to debug some more and watch what is going on with some
example programs that is passing values and references on to functions...

Arrays automatically decompose into pointers in certain contexts
(^^^^this only applies to the top-level array^^^^). For example:

int a[5] = { 1, 2, 3, 4, 5 };
int *p = &a[0];
/* the compiler internally converts this to: */
int *p = &*((int*)a + 0);
/* which is exactly equivalent to: */
int *p = (int*)a + 0;
/* which can be further optimized to: */
int *p = (int*)a;
/* leading us to just simply use the following instead: */
int *p = a;

This doesn't occur with this example because it only applies to the
top-level array:

int m[1][1] = { 0 };
int (*q)[1] = a;
/* good, we can convert int[1][1] (an array of an array of ints) to int
(*)[1] (a pointer to an array of ints) */
int **q = m;
/* error, we can't convert int[1][1] to int** (a pointer to a pointer
to an int) */
And just incase you're confused about precedence, &a[0] means &(a[0])
and not (&a)[0]. There is a slight difference:

int a[5];

a[0] is int, &(a[0]) is int *
&a is int(*)[5], (&a)[0] is int[5]

Most of the time it doesn't matter, but it makes the difference with:

void fn(int (&)[5]);

fn(&a[0]); // bad
fn(a); // good
fn((&a)[0]); // good
fn(*&a); /* good, this is the same thing remember? */

See if you can work your way through the types of the expressions to
see why.


Wow.... I'll have to print this out tomorrow and study it carefully :-)

Thanks a lot - looks like some very good comments for me...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Mar 29 '06 #29

This discussion thread is closed

Replies have been disabled for this discussion.