Code Disk UpdateThe C Users Journal provides all code listings from articles on a monthly code disk, which may be purchased separately from the magazine or on a subscription basis. In addition, the code disk typically contains listings that are too long to be printed in the magazine. Unfortunately, several code listings referenced in the October 93 CUJ didn't make it to the code disk. These files are described as follows:
splash.zip this file contains the entire splash class library described by Jim Morris in his article, "The SPLASH Class Library." Due to size constraints, this library was not listed in its entirety in the article, but was to be provided on the code disk.
winroth.zip this file contains the exception handling macros described by Harald Winroth and Matti Rendahl in their article, "Exception Handling in C."
1110072C this file contains Listing 6 for the article "Random Event Simulation for C Programmers" by Martin Scolnick.
We provide the missing files on the December 1993 code disk. However, if you received an October 1993 code disk missing these files, and would like a replacement, please call, write, or e-mail R&D Publications, Customer Relations, 1601 W. 23rd Suite #200, Lawrence, KS. 66046-2700. (913)-841-1631. e-mail: pam@rdpub.com.
Also, CUJ code listings are available online, from a variety of sources. For a description of these sources, refer to the section entitled "CUJ Online Source Code," in the Table of Contents, page 6.
Dear Mr. Plauger:
The article "Curve Fitting with Extrapolation" by Lowell Smith (CUJ, June, '93) got my attention due to the use of Chebychev polynomials and the fact that I am finishing documenting the use of the Chebyshev method as applied to approximations of bivariate cartographic projection functions. Although his discussion did not apply to my application, browsing his code brought up a problem that has bothered me ever since ANSI C was established. Why was the very useful function hypot dropped from the math library? I can understand dropping the more esoteric Bessel and error functions, but not hypot. It is widely used in engineering, scientific and graphics applications. "Dropping" does not apply to something that did not exist, but its near universal appearance in C libraries makes it seem that way.
The main reason for my concern for this issue is that many application developers may not know the proper method of evaluation and will simply use:
double hypot()(double x, double y) { return sqrt(x * x + y * y); }such as appears in the GNU project math library. But this method seriously degrades the dynamic range of the input arguments to about sqrt(DBL_MAX). Mr. Smith's article uses the appropriate algorithm in the procedure dpythag (listing on p. 37) but it is somewhat lacking in implementation.Although most C compilers, ANSI or not, still supply hypot with their math library, I must include a version of hypot with my distribution of projection software to support my claim that the system is "ANSI." As an alternative to dpythag, I am suggesting the following procedure that I use in this distribution:
double hypot()(double x, double y) { if ( x < 0.) x = -x; else if (x == 0.) return (y < 0. ? -y : y); if (y < 0.) y = -y; else if (y == 0.) return (x); if ( x < y ) { x /= y; return ( y * sqrt( 1. + x * x ) ); } else { y /= x; return ( x * sqrt( 1. + y * y ) ); } }which does not make unnecessary divisions nor divide by 0 when x or y is 0. It also executes faster than Mr. Smith's version and it even runs faster than the hypot in my system SVR4 math library.I strongly suggest that hypot become part of the C math library with the next C standards. I also would like to see matherr or equivalence also established, but that is another battle.
Gerald (Jerry) I. Evenden
Internet: gie@charon.er.usgs.gov
Postal: P.O. Box 1027
N.Falmouth, MA 02556-1027I agree that hypot is a useflibrary function, for the reasons you cite. Strictly speaking, however, it was not "dropped" from the C library during standardization. We began with the /usr/group (now POSIX) library which initially did not contain this or several other functions that are now commonplace. I vaguely recall a suggestion that we add hypot and friends later in the standardization process, but the proposal did not get strong backing. These functions are indeed serious candidates for addition to C when the C Standard is next revised. pjp
Dear Mr. Plauger,
I have been a sporadic off-the-shelf buyer for some time now. Having missed almost all of last year though, I have finally decided to buy into a subscription.
Though I do "know" C and have used it for a long time, it is only recently that I have endeavored to acquire the intimacy with this language that I have always wanted. You and your magazine provide a source of knowledge and insight that I have not been able to find elsewhere. It is a refreshing break from the formats of other, more commercially oriented magazines. I particulary enjoy the small descriptions of contributing writers (i.e. who they are, what they do, where they work) which accompany many articles. It is reassuring to hear from people who are just simple application minded programmers and who are not trying to land people on Neptune or split the proton with a doubly recursive 1 line function. From simple tips and formatting standards to the shape of C to come, yours is the magazine that I look forward to the most for information on the world in which I have decided to spend my working life.
Looking through some older copies, I notice a change in the subtitle on the main contents page "Advanced Solutions for C/C++ Programmers." I check the name of the magazine on the cover. It still says The C Users Journal. The time will come when I know C++. From what I have heard about it, I will learn not simply a new placement of semicolons and commas, but a new approach to expressing a solution. The English and French languages use (essentially) the same alphabet, but form ideas and shape solutions very differently. So too, it seems to me upon my very brief exposure, C++, though sharing much of the same appearance with respect to the parts of speech of C, offers a whole new approach to the problem.
However (here it comes), as I stated above, there are still many C programming concepts that I would like to learn. I do not want to be seen as being in any way critical of C++ or its popularity. I just want a place where I can go to be exposed to C The C User's Journal. Now, I realize that there is no way to build a wall around the magazine to keep C++ out, just as car review magazines would not block out reviews of trucks (sorry, it's the best analogy I can whip up right now). I do feel, though, that we the readers and supporters should be given some insight into the future of CUJ. The people at CUJ are astute enough to know that 2 magazines will be a very easy thing to do when C++ momentum really starts to roll. I just don't want to have my $54.00 a year subscription rate increased to cover things that I really can't make any use of yet.
The October, November and December issues are undoubtedly already well formed. My sincerest apologies if this topic has been already thoroughly covered in one of the issues that I missed, but I do feel very concerned about it. You at CUJ stand out because you aren't 100 pages of adverts and 80 pages of article. Please do not let C++ continue to take more and more space away from the pages of a C magazine. Please do not make me pay more for information I do not yet want. What is the future of CUJ C/C++UJ or two magazines?
Thank you for your time and product.
Ian Somerton
isomerton@kean.ucs.mun.ca
Memorial University of Newfoundland, CanadaI share your concern about balanced coverage. There is no question that C remains an important language for many applications. We will continue to publish articles, written by practicing programmers, that show you better ways to use C. There is also no question that C++ is an important new language that is closely related to C. Aside from being a powerful language in its own right, C++ also serves as the most popular testbed today for all sorts of extensions to C. (After all, C is standardized while C++ is not, as of yet.) So we will continue to publish equally practical articles that show you sensible ways to use C++.
The jury is still out on whether we eventually change our name. But be assured that we have no intention of changing our basic editorial philosophy. pjp
To the Editor:
I am writing in response to David R. Tribble's letter in the May, 1993 issue of The C Users Journal, p. 120.
I, too, have often wished for something like the __FUNC__ macro. To trap errors, I have a module called LOG.C (with a corresponding LOG.H header file) which contains functions for opening, writing to, and closing a log file. [See Listing 1. ] By wrapping every call to writelog in an #ifndef, calls to writelog can be selectively omitted or included by respectively defining or not defining NDEBUG.
Also, if I forget to use either the DEF_MODULE_NAME macro (at the top of a module) or the DEF_FUNC_NAME macro (at the top of a function), the compiler will warn me that the references to _MODULE_NAME[] and _FUNCTION_NAME[] are as yet undefined.
This system has its drawbacks: often I'll copy a function and alter the copy (rather than write a new function from scratch), and in the process I'll sometimes forget to change the parameter in the call to DEF_FUNC_NAME. But it's fairly simple to use a combination of grep (or DOS's FIND), sort, and uniq to find calls to DEF_FUNC_NAME with erroneously identical parameters.
Another drawback is that sometimes I'll forget to pass MODULE_NAME and FUNC_NAME as the first parameters to writelog following the format string. Or sometimes I'll forget to begin the format string with %s.%s. But if I copy the writelog call from a function that I know works, I'm usually safe. (I could probably cook up something with macros that automatically pastes the string %s.%s in front of the format string passed to writelog, but my system works well enough for me as it is.)
Sincerely,
Kim Moser
72241.1304@compuserve.comHi,
About the "complexity overload" editorial (April 1993 issue of The C Users Journal), I'm sorry to read that technology is starting to overwhelm you. There is a rule that applies to any thinking being, and that is "the more you learn, the less you know," and "the more you know, the more complex things are." I myself sometimes wonder if all this knowledge and complexity really means human progress, but these thoughts always vanish when I see the product of my, and others constructive efforts.
Yes, we all can make progress in this sea of complexity. Perhaps some time off will help to recharge your human spirit. I hope you don't ever abandon C and the C++ effort, it would be a great loss for the computer community. So, from the sunny land of south Florida, cheer up!
Miguel Sang
msang@vnet.ibm.comI appreciate the encouragement I get from readers during the lows of my annual manic depressive cycle. Thanks for writing. pjp
Dear PJ:
In the April 1993 Issue of The C Users Journal, Matt Weisfeld made a small error on lines 342-343 of the file uililbs.c. He is calling delwin and then erase_window. The result is a freed memory read violation. The correct sequence should be erase_window, and then delwin. Other than it is a greate piece of code.
Brad Wright
President and CEO
Wright SystemsThanks for the fix. pjp
Dear Sir,
I enjoyed analyzing the program ToJul (Date Conversions, February 1993, p30). I found it very clever, perhaps too much so. I feel that one should be able to understand each step of a program and develop some confidence that it is working correctly. The use of unexplained constants and convoluted arithmetic (instead of simple logic) makes this program somewhat hard to follow. It need not be so.
For example, during the calculation the program uses an adjustment factor based on whether the given date is in the March-December period (i.e. after the tricky last day of February or in the January-February time frame. A natural way to compute it is:
if( month == 1 || month == 2) adj= -1; else adj=0;Instead the program computes:
(lmonth - 14L) / 12LThis yields the same result (-1 in January and February, 0 otherwise) but is much more difficult to understand. The assumption seems to be that if statements are to be avoided at all costs.Also, the program needs the offset (in days) between the first of this month and the previous March first. In C this is best done by defining an array:
int marOffset[12] = { 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};and then referring to marOffset[month-1] wherever needed. Instead the program as published uses the fact that the expression
367L * (lmonth-2L-(lmonth-14L)/12L*12L) / 12Lhappens to give the same results, as you can verify by trying all 12 possible values of lmonth. But this expression is quite obscure (the person who thought of it is a genius!) whereas the purpose of the marOffset array can be guessed by anyone who looks at it and knows that it has something to do with the calendar. Furthermore, if I am ever stuck on a desert island (without a copy of the October 1968 Communications of the ACM, I will probably be able to write down the marOffset array, but I doubt I will be able to recall the equivalent mathematical expression.By the way, the use of March offsets (rather than, say, January offsets) in the program is a genuinely good idea that needs to be appreciated. It simplifies the handling of leap years. If January-based offsets were used then two arrays (or two expressions) would be needed, one for leap years and one for non-leap years: {0, 31, 59, ...} and {0, 31, 60, ...}. A single marOffset array handles both cases.
Actually the idea of using an array would work well with the adj factor also. Define the first two entries to be -1 and the others to be 0 and replace the if statement above with an array reference: adj[month-1]. Which is better? I suppose it is a matter of taste.
I feel that with a few more changes like this the program would become much easier to follow. The final step would be to add a comment that explains for what input values the caller can expect to get correct results. Square root routines for example always document the fact that the input should be a non-negative value. In this case the author states that the program has "been tested [with values] from 4000 B.C. to beyond 5000 A.D." Great! But don't be shy: a more assertive statement would be that this program is not to be used for dates earlier than 4712 B.C., since it is not designed to handle those cases. For everyday purposes it will work fine but don't try it on some astronomical puzzle like "how many times during the past 10,000 years did the full moon fall on Friday the 13th?." Perhaps a check for valid input should be added. (But that would add another one of those dreaded if statements.)
In any case, I have added ToJul to my collection of calendar routines. And I have enjoyed thinking about how I would it change to satisfy my coding criteria, which of course may be different from those of other people.
Sincerely Yours,
Alex Castaldo
System Constructs, Inc.
New York, NY
Compuserve: [76605,3240]Dear Sir:
It seems that all the books and articles about programming now stress two important points: the code should not contain any "magic numbers," whose meaning is hidden from anyone reading the code, and the code should be well commented so that any reader can understand the processes used. Yet you published David Burki's article "Date Conversions," CUJ February 1993, which, as the author points out, is just a reproduction of the 1968 FORTRAN code given by Fliegel and Van Flandern, complete with its 38 magic numbers, and with no explanation of the processes used.
It would be difficult if not impossible to modify this code to work for Julian dates prior to October 5, 1582 without some idea of what all these numbers represent. Pascal programs for the same processes, with the same limitations on acceptable dates were given by Robert G. Tantzen, Communications of the ACM, Vol. 6, Number 4, August, 1963. They contain only 31 magic numbers, but fail for many if not all dates prior to April 8, 4712.
With today's equipment and languages, it is easy to calculate Julian day numbers for dates within a specified range directly from the definition. Knowing that January 1, 4712 has Julian day number 0 and that for calculating Julian day numbers the Julian calendar is used for all dates through October 4, 1582 and the Gregorian calendar for dates from October 15, 1582 (with dates between these being invalid) it is easy to create an array of long int giving the Julian day number of the first day of each of the years to be considered; to find the Julian day number for any month/day in the specified year it is only necessary to add the appropriate amount to the Julian number of the first day of the year.
The advantage of such an approach is that it gives an understandable solution to the problem, without any mysterious unexplained numbers or processes. It seems that 20 years ago and earlier it was the fashion to present algorithms as single FORTRAN functions, with lots of magic numbers and the implication that you must simply take the author's word that it works. For example J. Douglas Robertson, Communications of the ACM, vol 15, Number 10, October 1972, gave a function for finding the day of the year for a given month, day, and year. It reads as follows, where I, J, K are long ints representing the year, month, and day, respectively:
IDAY(I,J,K) = 3055*(J+2)/100-(J+10)/13*2-91 +(1-(I-I/4*4+3)/4 +(I-I/100*100+99)/100 -(I-I/400*400+399)/400):1C(J+lO)/13+KThis gives the same result as the easily understood program day_of_year given in K&R, first edition, p.104, except that Robertson's program fails for all negative years that are not leap years. I have not the foggiest idea why it works for positive years and usually fails otherwise, or why Tantzen's program works for April 8, 4712 and above and apparently fails for all other years, and I doubt that anyone other than the authors could figure it out. Perhaps the equally obscure Fliegel and Van Flandern function also has places where it doesn't work.Burki claims that these routines "have been tested using a broad range of dates. Testing has included round tripping every valid date from 4000 B.C. to beyond 5000 A.D., as well as checking the day of the week against published calendars." By "round tripping" a date I presume he means taking a date, finding the Julian number for that date, finding the date corresponding to that number, and checking that is the same as the original date. Such a test shows that one of the routines is the inverse of the other, but does not indicate anything about their validity. It is easy to produce totally erroneous ToJul and FromJul functions which pass the round tripping test without any errors. For example, make ToJul (m,d,y) return m+1000*d+100000*y, and FromJul(jul,*m,*d,*y) set *y = jul/100000, *d = (jul-100000*(*y))/1000, *m = jul-100000*(*y)-1000*(*d). As for checking the day of the week against published calendars, this obviously is a very limited test of the validity of the functions given.
Programming has improved in the last 20 years, hasn't it? So why publish a 26-year-old undecipherable program without including any explanation of how it works or any proof that it does what is claimed?
Sincerely yours,
B. J. Ball
3304 Glen Rose Drive
Austin, TX 78731You're both absolutely right about the need to make code as readable as possible. I've been preaching that sermon for about 20 years now. But I still succumb to the temptation to write "clever" expressions from time to time too. pjp
To the editors of The C Users Journal:
When I read "A Natural Language Processor" in your April issue I thought at first it must be an April Fool's prank. But if it is, it is not a very good one, and my comments are given under the assumption that it was not a joke. I am writing this letter not just because the article presents a simplistic and inaccurate picture of natural language processing, but also because it was so prominently proclaimed as "Natural Language Processing" on the cover.
Mr. Suereth claims that his program is based on transformational grammar. This theory is characterized by the presence of a base component of context free phrase structure rules and a set of transformational rules that operate on the output of the base component. Neither is present in Mr. Suereth's approach. There is nothing remotely resembling transformational grammar, or any kind of grammar for that matter, in the approach described in the article.
The author also incorrectly claims that "there are a limited number of phrase structures" in transformational grammar. There are a limited number of phrase structure rules in the base component, but these are capable of generating an infinite number of sentence structures. The program given in the article simply enumerates two short sequences of surface forms. One might just as well construct an arithmetic expression processor by enumerating all the possible sequences of numbers and operators. The program does not even do a very good job of recognizing the two sentence patterns it knows about, accepting "Jim is ran in the house" as well as "Jim is running in the house." Mr. Suereth concludes the article by claiming that "expanding" his processor will enable it to read books and answer questions on them. I don't think so.
The approach and program described in the article completely ignore well known techniques from the fields of computer science and computational linguistics. The result offers no insight into NLP and is less efficient and harder to understand than accepted approaches to the problem such as chart parsers, definite clause grammars, augmented transition networks, or knowledge-based parsing.
I am disappointed that the editors of CUJ would promote this article as natural language processing. It is not up to the standards set by other excellent articles that have appeared in your magazine.
Pete Humphrey
Yeah. We ran the article because I thought it showed some simple ways to provide "English-like" capability for small C programs. I should have known better than to use the phraseology and jargon of a much more sophisticated discipline in conjunction with an admittedly elementary approach. The article is better judged for what the code actually does than for what the terminology suggests it might do. pjp
Dear Chuck Allison:
CRACK! And the Code Capsule columnist hits another one over the left field fence! As you can see, I enjoyed your April CUJ column, as well as every other month you've written. I had long since written off scanf as too dangerous to use in the real world, preferring rather to write my own number reading routines with fgets from stdin then using atoi or similar calls. But your creative uses of it has made me think that maybe I've been too hasty and should take another look. And I will.
Does CUJ plan to let you keep your column "permanently?" From earlier communication with you I got the feeling that it was a fairly temporary thing. I sincerely hope it is not in any way temporary.
This is probably too premature, but does X3J16 have a date on the "final" draft of Standard C++? (like anything is final in computers ;-).) Also any book plans on programming in "standard" C++?
Anyway, thanks again for your great column and keep up the good work!
/* Andrew */
As Senior Editor of CUJ, I hope to keep running Chuck's column for the foreseeable future. As a long-time standards drone, I can report with a straight face that X3J16 is supposed to release a fairly stable "working draft" of the C++ standard after its July 1994 meeting. And as a series editor for Prentice Hall, I keep encouraging Chuck to write a book based on his Code Capsules. pjp
Dear Mr. Plauger:
Here is some information for the reader that requested specs on the Hayes AT command set for a modem application. Digging through my back files, I came up with the following:
1) PC Tech Journal, Sep. 85 Two-page sidebar describing the Hayes standard for registers, AT commands, and word result codes.
2) PC Week, 13 May 86 Article describing the Hayes Command set: AT commands, result codes, register commands, and Smart-modem values.
3) PC Magazine, Jul 89 Sidebar to article on PS/2 modems, describing just the "AT Command Set."
Another reference might be the documentation to the Telix comm software, which comes set up for Hayes modems; also the Turbo Pascal source code to PibTerm (circa 1986 ?). Since these issues are long out of print, I would be happy to send a xerox if your reader wishes; just have him send a SASE to me:
Scott Daniels
9 Joval Street
East Lyme CT 06333Yet another, more recent resource, is Winn L. Rosch's Hardware Bible (1992, Brady Books, $45). I just received this volume today. This 1,000 page book covers just about everything to do with PC hardware, including a detailed section (pp. 731-735) on the Hayes modem spec AT commands, registers, etc. This looks like the best and certainly is the most recent and easiest to find, reference.
I came to CUJ a novice C-user, but the articles and your thought-provoking commentary are gradually pulling me into the C world. Keep up the good work.
Regards,
Scott Daniels
internet: CODE2111@NL.NUWC.navy.mil
CIS : 72212,745Wow. Thanks. pjp
To the Editor:
May I respond to the letter by Kevin R. Coombes that appeared in the July 1993 issue regarding my article, "Mixed Numbers in C?"
I think Coombes may have overreacted. I state early on that the data structure was chosen because I wanted to have each component of a mixed_t available for display. I wasn't concerned so much with elegance and efficiency, rather with mimicking the way arithmetic is done with pencil and paper by children. The code presented is an early version of an application meant for elementary and middle-school students, and destined to run on old, slow (you know, cheap) hardware.
I referred to Knuth's and several other books when considering which algorithms to use. Sometimes the "models of elegance and efficiency, don't get the job done the way you need it done. I wasn't only interested in the answer; I wanted everything in between too! I wanted to be able to display, step by step, everything that a student might see as he worked through examples. I modeled my algorithms on the examples in Stein's Refresher Mathematics, a popular math textbook. People, especially children, use sub-optimal algorithms to do arithmetic.
Coombes connects two sentences that have nothing to do with each other, and says I use the second to expand on a falsehood stated in the first. Let's see if I can clear this up.
The sentence he quotes from page 71 is correct in the context of the algorithm I chose to use to reduce fractions. This is a method children learn in school. The numerator and denominator are factored into primes and the common factors are then removed. The trial divisions are supplemented with a look-up table, and I knew in advance that the numbers needing factoring would not get too big. (See, for example, Knuth, The Art of Computer Programming, Seminumerical Algorithms, Volume 2, pages 365 and 367.)
Coombes then jumps to a different discussion and misreads the paragraph. On page 73, I am discussing how my functions handle calculations. I write that during calculations a gcd function could be used to "pre-reduce" each of the operands involved in the calculation, but that the answer is still not guaranteed to be in lowest terms.
Dr. Plauger, you read it correctly the first time.
[I replied to Coombes's letter that I must have failed to check the gcd discussion adequately in LaBrocca's article. pjp]
The discussion wasn't botched; rather Coombes missed the point again. Moreover, I didn't discuss any gcd algorithm at all. I guess that paragraph could have been more explicit.
In that same paragraph I point out that when adding up a long list of fractions there might be some advantage to pre-reducing them if doing so avoided overflow. However, about 61% of the time random number pairs produce gcds of 1, so I chose not to take out gcds during calculations. (See Knuth, pages 313 and 324.)
I won't argue about elegance and efficiency except to say that the two don't always go hand in hand. Mathematically elegant algorithms are sometimes unwieldy when implemented on a computer. The code in the article forms the core of an application that runs on PCs, Macintoshes and Apple IIGSs. The IIGS runs at about two MegaHertz and returns answers to complicated examples in under a second. A good test of efficiency is whether the job gets done reasonably on the targeted hardware. Taking gcds out of intermediate results took too long on the IIGS!
Coombes goes on (and on) to say that I was solving the wrong problem with the wrong methods. I thought the problem I was addressing was the lack of a method of inputting, working with, and outputting mixed numbers in C. That's even what I named the article. The fact that a mixed number is a rational number did not escape me. (I think it's correct to say that all numbers are represented in computers as rational numbers.) The point of the article was to introduce a convenient way of entering mixed numbers from the keyboard and providing some functions to do simple calculations with them.
Anyway, I hope I didn't do any mischief to Coombes's blood pressure. Only articles in gardening magazines get me that worked up.
P.J. LaBrocca
11 Ross Terrace
Manalapan, NJ 07726
(908)431-3025
plabrocc@nycenet. eduCUJ:
I liked Chuck Allison's clear and informative review of The Elements of C Programming Style, a book I co-authored with Jay Ranade. The review clearly conveys the overall intent of the book and accurately summarizes its content. I particularly liked that the reviewer chose to quote extensively from the book; his choice of quotations is excellent. However, just as he has a "very few nits to pick" with our book, I have a few nits to pick with his review. (And just as he points out that "two nits in 340 pages ain't bad," I must say that a few nits in an otherwise good review ain't bad either.)
First: The reviewer seems to have misunderstood the purpose of our chapter "Coding for non-C Programmers." Its purpose is not (as he asserts) "to gently introduce non-C programmers to the language" but rather to help C programmers to write code that will be read by non-C programmers. This is an important necessity in the corporate environment, where often your code has to be made (somewhat) understandable for managers and (God forbid) retrained COBOL programmers. This is explicitly stated at the beginning of that chapter, on page 275: "In most cases your readers will be C programmers. Sometimes, however, you might need to write your program so that it will be readable by non-C programmers... Much of the advice given in this chapter seems to contradict advice given in the rest of this book. There is no contradiction; the advice depends on your audience."
Second: Of the two nits the reviewer picks, one is clearly a bug in the book. However, the other, "the authors seem to think that wide characters and multibyte characters are the same thing" is not supported in the review. I could not find (I did not look too hard) anything in the book that supports this comment. The reference I did find (on page 265) says: "Wide characters have the type wchar_t. A wide character can represent any code of an extended character set. Multibyte characters can also represent codes of extended character sets. A multibyte character is a sequence of characters from the C character set used to represent an extended character."
Third: The reviewer asserts "They also think for(i=1, e=t=1.0; i<=n; t/=++i) e+=t; is clear." This assertion is not supported by the text; rather, this code example is provided solely as an extreme example of the power of the C for statement (which programmers coming to C from other languages often do not realize). This code example appears in the discussion of the rule "Use for instead of while whenever reasonable" (not as the main rule example) and is preceded simply by "while code can be rewritten as."
Fourth (very minor point): Tom Plum did beat us in producing a C programming style book earlier. However, stating that it was "in the eighties" might create the impression that that book appeared earlier than it did (its copyright date is 1989). The rules in that book are not as clear or direct as the ones in ours. Still, I agree with the reviewer that the claim in the back cover of our book might be "stretching things a bit."
Fifth: It is not true that we want our book to be a sequel to The Elements of Programming Style. In the preface we say: "This book has been strongly influenced by three excellent classics: The Elements of Style by William Strunk and E.B. White, The Elements of Programming Style by Brian Kernighan and P.J. Plauger, and The C Programming Language by Brian Kernighan and Dennis Ritchie. It strives to emulate the spirit of the first two to become a deserving sequel to the last one." That is, we would like to see our book become the standard second book of C. Once again thanks for a clear and informative review and for an excellent magazine.
Alan Nash
Compuserve ID: 71011, 2502Dear P.J. Plauger,
I have been enjoying the C Users Journal for a couple of months now. I wonder, however, why there is not an electronic supplement to the journal available? As a biochemist, I read the journal "Protein Science." This journal includes a supplemental diskette with each issue. This diskette contains additional information for the journal articles as well as a program and data for a viewer program that allows readers to see and manipulate protein structures that relate to journal articles. It seems to me that The C Users Journal could greatly benefit from a similar supplement.
It is important to understand the purpose of this supplement. It is not to be used to provide free software to readers as is done by other computing magazines. It would be a resource for authors and readers. The supplement would contain the code that is usually printed in the journal. This would save readers the time they might otherwise spend entering code that they find useful. But more exciting than this is that authors could include multiple examples of code that can be compiled by users. This would allow authors greater flexibility in demonstrating the ideas of their articles.
Finally is the implementation of the supplement. One method would be to provide either DOS or Mac diskettes as Protein Science does. At the time that one subscribes to the journal they would specify the format of their supplement. The other obvious choice would be a bulletin board electronic forum. Whatever method is chosen, it is important that it is easily available so as to get the maximum use by readers.
Sincerely,
Charles Letner
cletner@desire.wright.eduStill further incentive to provide better electronic support. pjp
Dear Sir:
I just recently started to subscribe to The C Users Journal. I have been an off-and-on reader since early 1992. I decided to subscribe to the Journal because I found the articles enlightening and informative. I also, enjoyed entering the code to see if my compiler had those capabilities. I am not an engineer, I am a school teacher.
I took up C two years ago to stop the summertime boredom. I now write small applications to help me in school. However, my programs are mostly text based. My students find them dull. They prefer to use programs with pictures and other graphic aids. These programs are fine, however, they often tell too much information or require me to supplement their material. Some are simply fun experiences with little learning value.
I want to import drawings (PCX) into programs. I want to give them more a professional look, so the students will not be overburden or given a free license to goof off. However, the companies who make the compiler I am using (Mix version 1.2, with C\Window\Toolchest) writes very little information about graphics. All efforts to contact them have come to naught. All they send is a product brochure.
I would appreciate any information you can give me. Or if direct help is not available, please direct me to a bulletin board, shareware, or a book which can remedy my situation.
Thank you
Lawrence H. Hardy
4561 Abilene
Denver, CO 80239I know I've seen one or more books in the past two years that document PCX and related file formats, but I can't remember authors or titles. Anybody? pjp