435,543 Members | 2,085 Online
Need help? Post your question and get tips & solutions from a community of 435,543 IT Pros & Developers. It's quick & easy.

# Nodes with unlimited children.

47 Replies

 P: n/a Karl Heinz Buchegger Re: Nodes with unlimited children, You wrote, " Start the whole thing with a forward declaration of NodeT. " Oh, how so very sweet, thank you much ! By the way, I just realized that the code that I showed in my original post was really designed for a NodeT of varying length, which I don't think I really need. So this is how it looks now ( and it works ), struct NodeT ; typedef NodeT * Link ; // B is the Beginning of an array of NodeT's. // E is the End of an array of NodeT's that are in use. // Room the end of an array of all NodeT's, used or not. struct Lnk_T { Link B, E, Room ; }; struct NodeT { Lnk_T Lnk ; }; Lnk_T Lnk ; enum { Sz_Node = sizeof NodeT, Chunk_Lnk = 4 }; GrowList ( Lnk_T & Lnk ) { if ( Lnk.E + 1 < Lnk.Room ) return; int Room = Lnk.Room - Lnk.B + Chunk_Lnk, E = Lnk.E - Lnk.B ; Lnk.B = ( Link ) realloc( Lnk.B, Room * Sz_Node ); Lnk.Room = Lnk.B + Room ; Lnk.E = Lnk.B + E ; memset( Lnk.E, 0, ( Lnk.Room - Lnk.E ) * Sz_Node ); } __stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // Lnk is a global, so it's initialized. // This creates a child for Lnk. // There is no limit to the number of children. GrowList ( Lnk ); // This creates a grandchild for Lnk. GrowList ( ( * Lnk.E ++ ).Lnk ); // etc } You wrote, " BTW: I consider your formatting style horrible. " Everyone employs whitespace differently, I even change my own style from time to time. So I don't see how it's worth commenting on. Jul 22 '05 #4

 P: n/a "Jeff Relf" wrote in message news:_J*************************@NCPlus.NET... Hi All, I plan on using the following C++ code to create nodes with unlimited children: There's a clever way to get this effect with only two Node *'s per Node: class Node { /* put data here */ Node *firstChild; Node *nextSibling; }; Then, to get all the children of a node, you just do for (Node *child = myNode->firstChild; child != 0; child = child->nextSibling) { // whatever } This works great as long as you don't need constant-time access to the nth child of a Node. Joe Gottman Jul 22 '05 #5

 P: n/a Hi General Protection Fault, Re: Precedence vs. overused parentheses, such as: ( * Lnk.E ++ ).Lnk in the following code, struct NodeT ; typedef NodeT * Link ; // B is the Beginning of an array of NodeT's. // E is the End of an array of NodeT's that are in use. // Room the end of an array of all NodeT's, used or not. struct Lnk_T { Link B, E, Room ; }; struct NodeT { Lnk_T Lnk ; }; Lnk_T Lnk ; enum { Sz_Node = sizeof NodeT, Chunk_Lnk = 4 }; GrowList ( Lnk_T & Lnk ) { if ( Lnk.E + 1 < Lnk.Room ) return; int Room = Lnk.Room - Lnk.B + Chunk_Lnk, E = Lnk.E - Lnk.B ; Lnk.B = ( Link ) realloc( Lnk.B, Room * Sz_Node ); Lnk.Room = Lnk.B + Room ; Lnk.E = Lnk.B + E ; memset( Lnk.E, 0, ( Lnk.Room - Lnk.E ) * Sz_Node ); } __stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // Lnk is a global, so it's initialized. // This creates a child for Lnk. // There is no limit to the number of children. GrowList ( Lnk ); // This creates a grandchild for Lnk. GrowList ( ( * Lnk.E ++ ).Lnk ); // etc } If you're asking me, it's much better to know the precedence of operators than to overuse parentheses. For example: ( * Lnk.E ++ ).Lnk is better than ( * ( Lnk.E ++ ) ).Lnk But it's subjective, so why quibble ? As for you maintaining my code, I wouldn't worry about that if I were you. Here is the order of precedence, highest first: ++ Post-increment, Left to right -- Post-decrement ( ) Function call [ ] Array element -> Pointer to structure member .. Structure or union member ++ Pre-increment, Right to left -- Pre-decrement ! Logical NOT ~ Bitwise NOT - Unary minus + Unary plus & Address * Indirection sizeof Size in bytes new Allocate program memory delete Deallocate program memory ( type ) Type cast [ for example, ( float ) i ] ..* Pointer to member ( objects ), Left to right ->* Pointer to member ( pointers ) * Multiply, Left to right / Divide % Remainder + Add, Left to right - Subtract << Left shift, Left to right Right shift < Less than, Left to right <= Less than or equal to Greater than= Greater than or equal to == Equal, Left to right != Not equal & Bitwise AND, Left to right ^ Bitwise exclusive OR, Left to right | Bitwise OR, Left to right && Logical AND, Left to right || Logical OR, Left to right ? : Conditional, Right to left = Assignment, Right to left *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= Compound assignment , Comma, Left to right Jul 22 '05 #6

 P: n/a Oops, I should've said: I prefer Lnk.E ++ -> Lnk over ( Lnk.E ++ ) -> Lnk Jul 22 '05 #8

 P: n/a Hi Joe Gottman, You showed something similar this: class Node_Type { Node * firstChild ; Node * nextSibling ; }; for ( Node_Type * child = myNode->firstChild ; child != 0 ; child = child->nextSibling ) ... For what I'm doing, I prefer my dynamic array of nodes. such as: Lnk.E ++ -> Lnk ( defined below ), That allows me to do things like: Lnk.B [ 4 ] which directly references the fifth node. My NodeT is very small and has a fixed size, if NodeT was large or if it had a dynamic size I'd use the code that I originally posted in this thread: news:_J*************************@NCPlus.NET To loop though all the child nodes I define this: ( Lnk is a global, see below ) #define LoopChildren \ Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.E ) Which is then called like this: LoopChildren _Lnk->Whatever ; Here's how I declared those variables: struct NodeT ; typedef NodeT * Link ; // B is the Beginning of an array of NodeT's. // E is the End of an array of NodeT's that are in use. // Room the end of an array of all NodeT's, used or not. struct Lnk_T { Link B, E, Room ; }; struct NodeT { int Whatever ; Lnk_T Lnk ; }; Lnk_T Lnk ; // This is a global variable, so it's initialized. enum { Sz_Node = sizeof NodeT, Chunk_Lnk = 4 }; GrowList ( Lnk_T & Lnk ) { if ( Lnk.E + 1 < Lnk.Room ) return; int Room = Lnk.Room - Lnk.B + Chunk_Lnk, E = Lnk.E - Lnk.B ; Lnk.B = ( Link ) realloc( Lnk.B, Room * Sz_Node ); Lnk.Room = Lnk.B + Room ; Lnk.E = Lnk.B + E ; memset( Lnk.E, 0, ( Lnk.Room - Lnk.E ) * Sz_Node ); } __stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // This creates a child for Lnk. // There is no limit to the number of children. GrowList ( Lnk ); // This creates a grandchild for Lnk. GrowList ( Lnk.E ++ -> Lnk ); // etc } Jul 22 '05 #9

 P: n/a Hi International All-Star Cast, Win XP's File Properties is... well... specific to Win XP, and therefore it can't be part of the main C# framework. I'm sure that there is plenty of C# code that only runs on Win XP. To be sure that your C# code _ Shines _ on dual 64-bit PowerPCs as well as on some arcane cell phone, you'd better damn well test it on all of those devices. Jul 22 '05 #10

 P: n/a Jeff Relf wrote: Hi International All-Star Cast, Win XP's File Properties is... well... specific to Win XP, and therefore it can't be part of the main C# framework. I'm sure that there is plenty of C# code that only runs on Win XP. To be sure that your C# code _ Shines _ on dual 64-bit PowerPCs as well as on some arcane cell phone, you'd better damn well test it on all of those devices. Sure, sure, but it's a web service...so I could care less. Yesterday, I wrote an synchronous Delegate ( what you overtrained c++ might term a callback function ) so that my GUI web service consumer could do work in the background. It's very cool. -- http://kentpsychedelic.blogspot.com Jul 22 '05 #11

 P: n/a Karl Heinz Buchegger wrote: BTW what you do with pointers and int in the above is illegal. I wonder why your compiler didn't barf on it. Forget that. It is legal. My fault. -- Karl Heinz Buchegger kb******@gascad.at Jul 22 '05 #13

 P: n/a Oops, two errors, It's printf( "%d", Inc ( Inc ( Lnk ).Lnk ).Whatever ); not printf( "%d", Inc ( Inc ( Lnk ).Lnk )->Whatever ); Because the each call to Inc() returns it as a reference to * Lnk.P, not Lnk.P Jul 22 '05 #15

 P: n/a Jeff Relf wrote: Hi Karl Heinz Buchegger, You wrote, << ...in this group ( clc++ ) we are used to seeing problems/requests which can be traced back to simply bad formatting. Reformatting and reindenting shows the errors quite clearly. So the regulars do this, reply with the reformatted code and the OP sees his problem on his own. >> I'm of the opinion that one's choice of whitespace and the names one chooses for the identifiers is less important than just going over the code. i.e. It helps to simply change the whitespace, no matter how you change it. For that very reason, I often change my style. Besides, my original question was answered quickly by you after you examined the first few lines of my post. Quickly is good. I had to cut&paste that mess into my editor and start reindenting and reformatting to even have a chance to figure out what is wrong and in which way it needs to be changed It's ironic that you would rename those 3 variables, because after examining this code myself I've decided to change them to: B, P, and E. Which only proofs that it is possible to write Fortran code in every language. (Apologies to Fortran programmers. Although I didn't write Fortran programs since 15 years any more, I know that Fortran has evolved in this time.) I cross-posted to Comp.OS.Linux.Advocacy ( Cola ) because I'm only reading that group, not Comp.Lang.C++. Good reason :-) -- Karl Heinz Buchegger kb******@gascad.at Jul 22 '05 #16

 P: n/a "Jeff Relf" wrote in message news:_J*************************@NCPlus.NET... Re: Precedence vs. overused parentheses, such as: ( * Lnk.E ++ ).Lnk in the following code, Um... the parentheses are necessary in this expression. If you were to write *Lnk.E++.Lnk it would mean the same as *((Lnk.E++).Lnk) Jul 22 '05 #17

 P: n/a On Fri, 30 Jul 2004 13:01:16 -0700, The Ghost In The Machine wrote: Or one can declare a templated "smart pointer" class: std::list > roomPointerList This is undefined behavior. std::auto_ptr cannot be used as a standard container member because it doesn't have the copy semantics that the standard containers require. Ali Jul 22 '05 #20

 P: n/a In comp.os.linux.advocacy, Ali Cehreli wrote on Fri, 30 Jul 2004 14:35:08 -0700 : On Fri, 30 Jul 2004 13:01:16 -0700, The Ghost In The Machine wrote: Or one can declare a templated "smart pointer" class: std::list > roomPointerList This is undefined behavior. std::auto_ptr cannot be used as a standard container member because it doesn't have the copy semantics that the standard containers require. Ali Ew. Thanks for the heads-up. :-) (You can tell how often I use it. :-) ) -- #191, ew****@earthlink.net It's still legal to go .sigless. Jul 22 '05 #21

 P: n/a Hi The Ghost In The Machine, Even if your .CPP to .HTML syntax highlighter works, I didn't like the .HTML code you showed me. I know that mine works, and it works well, and I prefer the HTML that it generates. That C++ code of mine is at: news:_J*************************@NCPlus.NET Ghost, I think you mostly write server-side Java, so C++ is not really your forte... No shame in that. As I think you suggested, my children are in a dynamic array, So I might have to do a memmove() to insert nodes, Or maybe use qsort() on it... I haven't gotten that far yet. Here's an example of how my tree routines might be called. ( Correcting some mistakes I made earlier ) __stdcall WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // In the line below, the first call to Inc() // creates one child ( * Lnk.P ) for Lnk // ( Lnk is a global ) and returns a reference to it. // // That child ( * Lnk.P ) // is then is passed in a second call to InC(), // which returns a reference to * Lnk.P->Lnk.P, a grandchild. // // There's no limit to the number of children per node. // // Afterwards Lnk.P->Lnk.P->Whatever // is a valid int which is initialized to zero. printf( "%d", Inc ( Inc ( Lnk ).Lnk ).Whatever ); // This prints all of Lnk's children. LoopChildren printf( "%d, ", _Lnk->Whatever ); } Here are the definitions... // The - 1 below is so that I can pre-increment. #define LoopChildren \ Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P ) struct NodeT ; typedef NodeT * Link ; // B is the Beginning of an array of NodeT's. // P is the Pointer to the NodeT being use. // E is the End of an array NodeT's. // Inc() allocates/increments P. struct Lnk_T { Link B, P, E ; }; struct NodeT { int Whatever ; Lnk_T Lnk ; }; Lnk_T Lnk ; // A global, so it's already initialized. enum { Sz_Node = sizeof NodeT }; NodeT & Inc ( Lnk_T & Ln ) { if ( Ln.E && ++ Ln.P < Ln.E ) return * Ln.P ; // 4 nodes are created at a time, but this could be tweaked // so that it grows by a certain percentage of Ln.P - Ln.B int E = Ln.E - Ln.B + 4 ; int P = Ln.P - Ln.B ; Ln.B = ( Link ) realloc( Ln.B, E * Sz_Node ); Ln.E = Ln.B + E ; Ln.P = Ln.B + P ; memset( Ln.P, 0, ( Ln.E - Ln.P ) * Sz_Node ); return * Ln.P ; } Jul 22 '05 #22

 P: n/a Hi Karl Heinz Buchegger, You think my C++ code would be easier to maintain is I used more whitespace and longer identifiers ? I don't agree at all. You will never ever catch me telling someone that his code is hard to maintain ( at least if I'm honest ). I might well refuse to maintain someone's old code, as I always prefer total rewrites. Re: struct Lnk_T { Link B, P, E ; }; You commented: << Which only proves that it is possible to write Fortran code in every language. >> I actually own a 450 dollar copy of MS Fortran for Win98. ( From when I converted some Fortran code to C ) But I never used it, thank God... I refused to. So I know what Fortran code ( and Fortran programmers ) look like ( with their big iron, IBM, and all that ). I've seen those huge hard disk platters. Hmm... Where they the forerunner to floppies ? ( Not counting tape, of course ) Jul 22 '05 #23

 P: n/a [snips] On Fri, 30 Jul 2004 04:32:42 +0000, Jeff Relf wrote: struct Lnk_T { Link B, E, Room ; }; struct NodeT { int Whatever ; Lnk_T Lnk ; }; Lnk_T? NodeT? Consistency is a good thing in programming. Jul 22 '05 #24

 P: n/a On Sat, 31 Jul 2004 08:32:10 +0000, Jeff Relf wrote: Hi Karl Heinz Buchegger, You think my C++ code would be easier to maintain is I used more whitespace and longer identifiers ? If it were formatted for readability and used variables and other symbols which themselves indicated their use, yes. I might well refuse to maintain someone's old code, as I always prefer total rewrites. Not surprising, given your code. Most of us, however, don't see reinventing the wheel as a good thing; if there's existing code which can be modified to suit the task, rather than writing entirely new code, we do it; it saves time, effort and bugs - the existing code is much more likely to have been relatively debugged than the new code. Writing unmaintainable code, as you do, does, indeed, make one want to rewrite it. Jul 22 '05 #25

 P: n/a In comp.os.linux.advocacy, Kelsey Bjarnason wrote on Sun, 01 Aug 2004 13:11:49 -0700 : [snips] On Fri, 30 Jul 2004 04:32:42 +0000, Jeff Relf wrote: struct Lnk_T { Link B, E, Room ; }; struct NodeT { int Whatever ; Lnk_T Lnk ; }; Lnk_T? NodeT? Consistency is a good thing in programming. Assumine anyone even wants to pursue this already-solved problem. Herewith examples of processing things in STL. The "explicit typedef/for loop" way. #include class C { public: C() {...} ... }; typedef std::list list_of_things_type; list_of_things_type list_of_things; void routine() { /* ... */ for(list_of_things_type::const_iterator i = list_of_things.begin(); i != list_of_things.end(); i++) { const C & obj = *i; /* ... obj ... */ } Or, if one wants to, #include #include class C { public: C() {...} ... }; std::list list_of_things; void func(const C & obj) { /* ... */ } class D { public: void operator()(C const & obj) { ... } }; D dobj; void routine() { /* ... */ std::for_each(list_of_things.begin(), list_of_things.end(), func); std::for_each(list_of_things.begin(), list_of_things.end(), dobj); } which evokes memories of LISP's apply(), for those so inclined. If one replaces std::list<> with std::vector<>, std::set<>, or std::hashset<> -- the code changes are minimal, limited only to the declaration. std::map<> and std::hashmap<> require a little work, mostly because the iterator returns a pair of items (key/value). But std::set<> takes as one of its template arguments a comparison method, which means that the collection can be in any order the programmer wants, automatically maintained as objects are added or removed. Compared to this level of elegance, Jeff's code is, in the considered opinion of this particular C++ programmer, swamp muck. :-P~~~ Not that this is a perfect solution, mind you; there are some constructs in C++/STL that are downright ugly. Try writing the following loop using std::find(), for example. typedef std::map > things_map_type; things_map_type things_map; /* ... */ for(things_map_type::const_iterator i = things_map.begin(); i != things_map.end(); i++) { const C & key = (*i).first; const C & val = (*i).second; if(!val.isDesirable()) break; } The best I can do is something using std::unary_negate<> and _Select2nd, and I'm not sure that's quite kosher -- or even right. Yuck. But at least C++/STL can do it; in Java one would probably have to leave the loop as is. (Java does offer Arrays.binarySearch() and Collections.binarySearch(), but both assume already-sorted collections (either an array or a list).) -- #191, ew****@earthlink.net It's still legal to go .sigless. Jul 22 '05 #29

 P: n/a Hi Kelsey Bjarnason, Re: #define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL ) You commented: << Marvellous; symbol clashes, just because you use this macro twice in the same scope. Talk about badly-written. >> You're worried about compilation errors ? Real programmers are Never concerned about that. This code compiles, and it does just what I would expect: FuBar () { int X = -1, Y = -1 ; Loop ( 6 ) { ++ X ; Loop ( 7 ) ++ Y ; } // Prints: 5 and 6 printf ( " %d and %d ", X, Y ); } You wrote: << Do us a favour: never, ever, post your code anywhere again. Some poor unsuspecting soul might think you know what you're doing and try to mimic you. >> Call me an ignorant idiot ( yet again ), but I, for one, don't think you're a Real programmer. I started coding HP-67 calculators ( with the magnetic strips ) back in 1976. Programming has been my sole profession since the start of 1982, and, as you can see, I'm building my own newsreader... So it's also my hobby. I wrote: << I know nothing about Eclipse, but I am curious as to who exactly would want a machine to control so many aspects of one's source code. >> And you replied: << To automate converting code such as yours into something sane. >> Now I know you're not a programmer, changing the whitespace, macros and such is a really good way to familiarize yourself with the code. That's why I sometimes do that to my own code. ( e.g. Stuff I wrote 12 years ago ) Jul 22 '05 #31

 P: n/a Jeff Relf wrote: Hi Kelsey Bjarnason, Re: #define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL ) You commented: << Marvellous; symbol clashes, just because you use this macro twice in the same scope. Talk about badly-written. >> You're worried about compilation errors ? Real programmers are Never concerned about that. Real programmers don't piss their colleagues off. They write clear, simple, robust, and easily-changed code. This helps keep their colleagues in the ... loop. -- Phlip http://industrialxp.org/community/bi...UserInterfaces Jul 22 '05 #32

 P: n/a Hi The Ghost In The Machine, You showed something like this: for ( list_of_things_type::const_iterator i = list_of_things.begin(); i != list_of_things.end(); i ++ ) { const C & obj = *i; /* ... obj ... */ } And then you commented: << Compared to this level of elegance, Jeff's code is, in the considered opinion of this particular C++ programmer, swamp muck. :-P~~~ >> Are you really a C++ programmer ? I don't think so. Java maybe, server side perhaps, but you're not a serious Win XP C++ programmer. You want to make comparisons ? This is how I loop through a list of unthread Usenet messages: ( From news:_J************************@NCPlus.NET ) LoopC ( & Flat ) if ( Eq ( Par, ( * Arr )->Ln [ _MID ] ) ) break ; This is how I delete a forest of threaded messages: DeC ( Lnk_T Lnk ) { if ( ! Lnk->B ) return ; LoopC ( Lnk ) { Lnk_T P = * Arr ; // Recursively deletes... how fun. DeC ( P ); // Deletes the array of lines that contain // the abbreviated headers. LineArr Ln = P->Ln - 1 ; Loop( _Lns ) free ( * ++ Ln ); free ( P ); } free ( Lnk->B ); } I'm looking at your way... and my way... I'm comparing the two, and I'm very much preferring my way. By the way... People are Still inventing wheels... as they well should. It's called: A better tire. Jul 22 '05 #33

 P: n/a Jeff Relf wrote: Hi The Ghost In The Machine, _____________________ /| /| | | ||__|| | Please do not | / O O\__ | feed the | / \ | Trolls | / \ \|_____________________| / _ \ \ || / |\____\ \ || / | | | |\____/ || / \|_|_|/ | _|| / / \ |____| || / | | | --| | | | |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ | || / _ \\ | / ` * / \_ /- | | | * ___ c_c_c_C/ \C_c_c_c____________ -- Karl Heinz Buchegger kb******@gascad.at Jul 22 '05 #34

 P: n/a Hi The Ghost In The Machine, Re: #define LoopChildren \ Link _Lnk = Lnk.B - 1 ; while ( ++ _Lnk < Lnk.P ) You wrote: << Also, you could just do while(_Lnk < Lnk.P) _Lnk++; though it depends on whether you've looked at the assembly output or not to see which method's more efficient. >> No, you missed one of the main reasons for LoopChildren: It pre-increments. ( Hence the initial -1 ) Your alternatives, mentioned in your other posts, all used post-increments, which I don't like. The other reason for defining something like LoopChildren is how clean it makes the code look. For an example of that, see my other post: news:_J************************@NCPlus.NET You mentioned: " Pointers don't fit in ints anymore. :-) " I don't ever do that, never did. All the code that I showed used: typedef char * Line ; enum { Sz_Ptr = sizeof Line }; Slap that on a 64-bit computer, and is still works... I know because I've done this before. Re: Memory faults, You asked: << And suppose I want to cluster my allocations 8 to a page ? For that matter, how about allocating an entire page ? Memory faults are a problem. >> ... << ...realloc() is a problem waiting to happen on C++ classes, if not used properly. >> My memory usage is not very taxing at all. I'm not writing a fault-tolerant server that supports terabytes of data and has to remain up for months on end. At any rate, I'm no longer using the code you were referring to. Now I only allocate dynamic arrays of pointers, not nodes... But even that node that you were referring to was tiny, just an int and three pointers, it was not designed to be large. Jul 22 '05 #35

 P: n/a Hi Karl Heinz Buchegger, Re: The Ghost In The Machine and me, You wrote: << _____________________ /| /| | | ||__|| | Please do not | / O O\__ | feed the | / \ | Trolls | / \ \|_____________________| / _ \ \ || / |\____\ \ || / | | | |\____/ || / \|_|_|/ | _|| / / \ |____| || / | | | --| | | | |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ | || / _ \\ | / ` * / \_ /- | | | * ___ c_c_c_C/ \C_c_c_c____________ At least we're talking abut C++, doesn't that count ? I don't think the Ghost is a troll, I just think he has a different point of view from me. A lot of people have scored me down too, but that's fine with me... I'm not entering anyone's popularity contest. It's even possible that The Ghost and I could come to a understanding. There's so much miscommunication on Usenet... Why not try to resolve some of it ? Jul 22 '05 #36

 P: n/a In comp.os.linux.advocacy, Karl Heinz Buchegger wrote on Tue, 03 Aug 2004 11:34:43 +0200 <41***************@gascad.at>: Jeff Relf wrote: Hi The Ghost In The Machine, _____________________ /| /| | | ||__|| | Please do not | / O O\__ | feed the | / \ | Trolls | / \ \|_____________________| / _ \ \ || / |\____\ \ || / | | | |\____/ || / \|_|_|/ | _|| / / \ |____| || / | | | --| | | | |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ | || / _ \\ | / ` * / \_ /- | | | * ___ c_c_c_C/ \C_c_c_c____________ Hmph. Well, if you insist. :-) -- #191, ew****@earthlink.net It's still legal to go .sigless. Jul 22 '05 #39

 P: n/a In comp.os.linux.advocacy, Jeff Relf wrote on 3 Aug 2004 10:22:39 GMT <_J************************@NCPlus.NET>: Hi Karl Heinz Buchegger, Re: The Ghost In The Machine and me, You wrote: << _____________________ /| /| | | ||__|| | Please do not | / O O\__ | feed the | / \ | Trolls | / \ \|_____________________| / _ \ \ || / |\____\ \ || / | | | |\____/ || / \|_|_|/ | _|| / / \ |____| || / | | | --| | | | |____ --| * _ | |_|_|_| | \-/ *-- _--\ _ \ | || / _ \\ | / ` * / \_ /- | | | * ___ c_c_c_C/ \C_c_c_c____________ At least we're talking abut C++, doesn't that count ? I don't think the Ghost is a troll, I just think he has a different point of view from me. Very different. :-) A lot of people have scored me down too, but that's fine with me... I'm not entering anyone's popularity contest. It's even possible that The Ghost and I could come to a understanding. I understand you well enough. Admittedly, there are those out there who think nothing of putting no comments at all into swamp muck, codeswill, or execrable crap, then using it as the documentation basis for whatever the tool is supposed to do. (The computer has no problem understanding Obfuscated C. But mere mortals have to take it apart. Code should be understandable to both man and machine -- ideally.) Of course part of my position is self-defense. I write something, come back to it later, and wonder why the hell I wrote it that particular way. It behooves me to be able to read my own code -- and presumably that means others can at least have a chance of decoding what I scribbled into the computer at some point. ObLinux: I can get the source code. That is a plus in itself. There's so much miscommunication on Usenet... Why not try to resolve some of it ? -- #191, ew****@earthlink.net It's still legal to go .sigless. Jul 22 '05 #41

 P: n/a Hi The Ghost In The Machine, Oops, I showed: << FuBar () { int X = -1, Y = -1 ; Loop ( 6 ) { ++ X ; Loop ( 7 ) ++ Y ; } // Prints: 5 and 6 printf ( " %d and %d ", X, Y ); } And you correctly corrected me: << The results I get are 5 and 41, before and after conversion. This is regardless of whether I use 'i' or 'j' as the inner variable, which shadows the outer one. >> I meant to write this: FuBar () { int X = -1, Y = -1 ; { Loop ( 6 ) ++ X ; } Loop ( 7 ) ++ Y ; // Prints: 5 and 6 printf ( " %d and %d ", X, Y ); } I say that this: { Loop ( 6 ) ++ X ; } Loop ( 7 ) ++ Y ; is more readable than this: for(int i = 0; i < 6; i++) { x++; for(int j = 0; j < 7; j++) y++; } You commented: " I'm surprised you can read that gunk. " That only goes to show that one man's meat is another man's poison. I'm into targeting Win XP for personal use, ( I put the personal in personal computer )... and you're into targeting servers in a large corporation... As the saying goes: I'm ok, you're ok, and Microsoft should give us a 75 billion dollar rebate. Jul 22 '05 #42

 P: n/a Hi The Ghost In The Machine, You showed: << it = std::binary_search( collection.begin(), collection.end(), "constant"); Yea, my original plan was to : A. qsort() the unthread list of Usenet messages ( Flat ). ( Flat contains one huge array of pointers to nodes, as described here news:_J************************@NCPlus.NET ) B. Then do a binary search on it. But then I ran the code... No need for the binary search. It's already instant, even with a list of two thousand messages. ( Even more so when compared to how long it takes me to download those messages using a spotty dial-up service ) In fact, it's much much Much faster than 40Tude Dialog, the newsreader that I was using before I wrote X. ( Actually, I'm still using Dialog for some things, because X is still so primitive ) Re: Your code: typedef std::string itemtype; // or whatever you want typedef std::xxx collectiontype; // xxx = set, vector, or list collectiontype collection; collectiontype::const_iterator it; You said: " ...it should be fairly clear what I'm doing. " Yes, it is quite clear ( and quite interesting too ). You showed: << Now, after one's assigned a value to 'it', one can then test 'it': if ( it != collection.end() ) /* found it */ Of course, I do that all the time... Only I say this: if ( J < LLL ) // found, i.e. broke out. after: Loop( 5 ) if ( Eq( "Hello", Line_Array[ J ] ) ) break; where: #define Eq ! strcmp #define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL ) The main difference is that I'm using J, not " it ", and LLL, not collection.end() . Re: collection.erase( it ); With my dynamic arrays of pointers to children and/or lines, ( Using B, P, E, and Inc() described recently: _J************************@NCPlus.NET )... ...I just free one or more pointers and then use memmove to overwrite them, the I adjust P, e.g. -- Ln.P, or -- Forest.P . ( I would show you exactly how I do that, but it's past 6 am now, and I usually go to bed at 3 am, and I have to be on campus by 10 am... uuugh ! ) You wrote: << Dereferencing a non-end pointer ( '*it' ) will get the item back. >> Yea, that's similar to my code here: LoopC ( & Flat ) if ( Eq ( Par, ( * Arr )->Ln [ _MID ] ) ) break ; You showed: collection.erase( collection.begin(), collection.end() ); saying: << If one wants an explicit forest of items some work will be required to encapsulate them properly. >> Right, the STL has no " Forest " type, especially not one with unlimited children... So your code above wouldn't work... forests have to be recursively deleted/printed. You said: " Enjoy your swamp muck... ". Oh, of that you can be Quite sure... I'm loving every minute of it. But I've got to go now... Jul 22 '05 #43

 P: n/a In message , Phlip writesJeff Relf wrote: Hi Kelsey Bjarnason, Re: #define Loop( N ) int J = -1, LLL = N ; while ( ++ J < LLL ) You commented: << Marvellous; symbol clashes, just because you use this macro twice in the same scope. Talk about badly-written. >> You're worried about compilation errors ? Real programmers are Never concerned about that.Real programmers don't piss their colleagues off. They write clear, simple,robust, and easily-changed code. This helps keep their colleagues in the ...loop. They don't change the subject line with every reply, either. -- Richard Herring Jul 22 '05 #44