Letters to the editor may be sent via email to [email protected], or via the postal service to Letters to the Editor, C/C++ Users Journal, 1601 W. 23rd St., Ste 200, Lawrence, KS 66046-2700.
Dear CUJ,
I greatly enjoyed the December 2001 CUJ issue, but I have a problem with Koenig & Moos first example in their column on for and while loops. They find the sum of the integers from 1 to 10 using a loop, an O(n) solution, but a constant time solution was devised some time ago!
By noting that
1+10 = 2+9 = 3+8 = ... = 11
we can deduce the sum
1+2+...+10 = 11*10/2 = 55
and in general, the sum of the integers 1..n is (n+1)n/2.
Of course, the purpose of the article was not to demonstrate the best way to sum series of integers, but I found the use of such an inferior algorithm distracting. Their second example would have sufficed for the entire article.
I am of course nitpicking, but everybody needs a hobby. Keep up the great work;)
Regards,
Patrick King
You are quite correct that it is easy to compute the sum of the first n integers without actually adding the integers. In that sense, the second example,
for (Node* p = head; p; p->next) { /* ... */ }is more satisfying. However, in presenting a language feature, we often find it useful to choose a first example that is obvious in all respects except for its use of the feature. That way, the reader doesnt have to think of anything else.
With that strategy in mind, the second example might be too distracting. To understand it, one has to understand the meaning of the -> operator and to know that using a pointer as a condition implicitly compares that pointer to zero. Of course, these facts are common knowledge to many C and C++ programmers, but not to all of them especially if they have approached C++ in the way that our book Accelerated C++ recommends. In that case, they may well understand how to use containers and iterators and may never even have written a pointer.
For these reasons, we hope that you will forgive our choice of a deliberately trivial first example.
Regards,
Andrew Koenig
Barbara E. Moo
Dear CUJ,
I was reading the article, C++ Made Easier: A New Look at for Statements (December 2001), and thoroughly enjoyed the way Andrew Koenig and Barbara E. Moo have put together this discussion on when one would choose to use a for or while statement.
There is a place in the article where the authors have advocated the use of:
while(*p != ) ++p;
to
for( ; *p != ; ++p);
I, however, believe that there are places where the for statement without the initialization part is a better alternative to a while statement. Imagine a situation where one would have to iterate through a list of elements and based on its type or some condition decide as to whether or not to process it. When we do not want to process an element, we just continue with the other elements. For example:
while(*p!= ){ if ( p->type != the type we expect it to be ){ ++p; continue; } process element.... ...... if( the element does not satisfy some other condition ){ ++p; continue; } ..... ++p; // we repeat the increment // statement more than one time // in the code }
the same loop written with a for statement look like this:
for( ; *p != ; ++p){ if ( p->type != the type we expect it to be ) continue; process element.... ...... if( the element does not satisfy some other condition ) continue; ..... }
I would personally prefer the one written with a for statement in this case as I would not have to repeat the increment instruction every so often in the code. One might argue that if there are so many continues in the loop, then the loop is not well designed, but we still see a lot code that resembles the above-mentioned scenario. We might first write a loop with a while statement, and somebody else adds a condition check in the code with a continue on failure or success. This would go on until one fine day, we might have a loop with n continues.
The authors have very clearly pointed out that they strongly prefer while to for when one does not have to declare and initialize a variable. However, where we use what kind of a loop should be completely a matter of choice.
With Regards,
Vivek Venkatesan
Design Engineer
IBM
Your example points out a context that we did not explore in which it might make sense to prefer a for to a while: when each iteration of the loop corresponds to a single value of the control variable.
Loops with that property usually initialize the control variable at the beginning, which is why we didnt mention explicitly the case where they dont do so. In your example, for example, we would expect it to be more common to see:
for (p = buffer; *p != ; ++p) { // ... }
than to see
for ( ; *p != ; ++p) { // ... }
Nevertheless, the second form does occur from time to time, and if the loop really does have a unique value of p that corresponds to each iteration, a for statement may well be the most appropriate form.
We completely agree with you that recommendations ours and others should never override programmers responsibility to think about what they do and exercise their judgment.
Regards,
Andrew Koenig
Barbara E. Moo
Dear CUJ,
I am creating a C++ class that will contain and operate on many different component classes.
(Call the big parent class vehicle.)
Although most of the component classes will usually be created by a parent vehicle, I want these component classes to be able to exist independently of vehicle.
(Call one of these component classes radio.)
There are times however in the component classes where I need to get a handle to the parent vehicle if present. (radio needs to get a handle to the battery, which is only known by the vehicle.)
On to the question: Any thoughts on how to set up an interface so radio can get a handle on its parent vehicle? I am hoping there is some solution in which I do not have to store a pointer to parent vehicle in every base component class.
In MFC apps, this problem is solved with the use of AfxGetApp where the vehicle is a CWinApp object. However, unlike MFC apps, which are constrained to have a single CWinApp object, I want to allow my program to have more than one vehicle in it.
Any thoughts ?
Thanks,
Matt McGarvey
If a radio can only be in one vehicle at a time, then it makes sense to have a pointer to the parent and a member function to yield that pointer. If a component can be connected to multiple parent objects, then you might want to register interest between the objects a la the Observer Pattern. In the absence of more information, thats the best I can come up with. cda
Hello,
This may be a question you get a lot; if so I apologize for that. I am looking for some sample C++ code to help me hone my programming skills and to learn OOP. The books I have looked at are either mostly theoretical or contain only short snippets of code. What would be extremely helpful would be a complete working program that follows the guidelines set out by the gurus. I think a medium-sized program would be the most valuable. Perhaps something between 1k and 10k lines of code. It would also be nice if it was something that was useful or interesting to the average person (a game would be great). Another nicety would be that there are obvious features that can be added to the project. This way the programmer could get hands-on experience working with the code. I believe a professionally constructed piece of software of this nature would prove extremely useful for countless programmers at many different skill levels.
Michael Solem
As you imagine, we cannot run such large code examples in CUJ. My book (C & C++ Code Capsules) has several chapters with large code projects, but they are somewhat beyond what a beginner would like to see (thats the innate difficulty with fulfilling your request). John Lakos book (Large-scale C++ Software Design) is filled with wisdom for building large C++ projects, but again, it doesnt have lengthy code excerpts. Lets see if other readers may be able to help. cda
Re: Editors Forum, January 2002
One valarray use: I used valarray in some scientific C++/Fortran-90 code and found implementations from several vendors to be defective in several ways especially exception-safety. Ive provided fixes to some and have even extended it to allow for optional externally-provided storage (e.g., to wrap a valarray around a too-large-to-copy Fortran array).
Regarding language definition committees: from the perspective of an HPC programmer, issues such as large arrays (64-bit indexing) and cross-language interfacing need to be considered by those committees specifying languages so that we practitioners are not burdened with the need to create hard-to-port hacks to workaround the undefined behavior cop-outs and imprecision found in the language specs. Saying that interfacing with other languages is beyond our scope is not good enough. C++s extern "C" and other languages C interfacing mechanisms are a helpful start, but more needs to be done by coordinating groups e.g., Fortran name-mangling, strings, exact basic type sizes (C9X), exceptions, memory allocation, GC, initialization, finalization, concurrency, etc., to facilitate real-world multi-platform multi-language application development.
It is time to place the needs of application programmers above those of compiler writers after all we outnumber them by several orders of magnitude. Survey the audience and practical usage of the languages. Every major language committee should include members that are experienced practitioners in other related (in practice) languages so that crucial compatibility and cross-language interfacing issues are not overlooked.
Todd Plessel
Concerning valarray, one of the designers of that class recently made the following comment in a private email: Believe it or not, I never use valarray any more. It was designed with an architecture in mind (the vectorized supercomputer) that is obsolete. Numerical C++ programmers seem to be migrating to libraries like Blitz.
Some (but not all) of your recommendations for C++ extensions are currently being considering by the standards committee for the next version of the language (C++0x). The committee is open for all organizations that want to participate. It is true that implementors sit on the committee, but many user representatives also participate. cda