debugging... dereferencing, & etc.

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

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
 
V

Victor Bazarov

Martin said:
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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

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
 
P

peter koch

Martin Jørgensen skrev:
Victor Bazarov wrote:
-snip-


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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

peter said:
Martin Jørgensen skrev:



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
 
A

Alf P. Steinbach

* 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. ;-)
 
D

Daniel T.

Martin Jørgensen said:
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]);
}
 
M

Me

Martin said:
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 &)
 
B

Bo Persson

Martin Jørgensen said:
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.
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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Bo said:
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.
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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Daniel said:
Actually no... Read the output for each program.

I think I posted the wrong code somehow and first realized it today...
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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Daniel said:
Martin Jørgensen <[email protected]> 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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Me said:
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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Alf said:
* Martin Jørgensen:



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?
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.
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-
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...
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?
That's probably the memory addresses of the strings, plus string values.

Yes. That is true and verified.
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...
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...

Just as Daniel T. and "me" understood, I think...


Best regards / Med venlig hilsen
Martin Jørgensen
 
A

Alf P. Steinbach

* Martin Jørgensen:
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).


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.

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.


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.

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

Those prototypes, get rid of them.

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=lafore>

Francis Glassborow: "I cannot recommend this book as it is".
 
D

Daniel T.

Martin Jørgensen said:
I think I posted the wrong code somehow and first realized it today...


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

Yes. A shame I think but something you "just have to know."
 
D

Daniel T.

Martin Jørgensen said:
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.
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Alf said:
* Martin Jørgensen: -snip-



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-
<url:
http://accu.org/index.php/book_reviews?url=view.xqy?review=o003132&term=lafore>


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
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Daniel said:
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
 
A

Alf P. Steinbach

* Martin Jørgensen:

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>.



Nearly there!

Good.

Just two mouse-clicks away (or was it one mouse-click), you find
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! :)
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top