Dear DDJ,
In his "Structured Programming" column in the March 1988 issue, Kent Porter points out that two-dimensional arrays can be implemented as an array of pointers to rows instead of the usual contiguous array of rows (where a row is itself an array of data elements). Besides overcoming the 8088 64K segment restriction, this programming technique is commonly used for arrays where the rows have different lengths or are of uncertain length and number.
The best known example for C programmers is the processing of the command line. The hidden startup code splits the command line into words and allocates space for and fills in an array of pointers to the words. It then passes the address of the pointer array to the function main(). Other examples are given in Kernighan and Ritchie's The C Programming Language.
Porter's implementation of this technique in Pascal, while a service for Pascal programmers, also illustrates some contrasts between Pascal and C. In Pascal, array element references change their syntax, after auxiliary type declarations, from a^(I,J) to the more awkward A^(I).col^(J). To convert a program to use large matrices with the alternate storage method, all array references would have to be modified. In C, only the allocation function would have to be changed. Arrays references would keep the form A[I][J] in spite of the change in storage method since the compiler handles such internal details. This is illustrated by the following short program which prints the command line as a two-dimensional array of characters.
main(int n, char **v) {
register int i, j;
for (i=0; v[i]; i+ +) {
for (j=0; v[i][j]; j+ +)
putchar(v[i][j]);
putchar(`\n');
}
}Admittedly, however, if the C programmer had used explicit pointer references for the sake of `efficiency,' then the conversion effort might be even greater than with Pascal.
Terry J. Reedy
Los Angeles, CA
Dear DDJ,
I realize that Fortran is no longer fashionable as a computer language, but--without casting aspersions on Borland's dialect of Pascal--I would like to submit the example below as a substitute for Kent Porter's Turbo Pascal program hugemats (DDJ, March 1988). Apart from the compiler directives, it is a portable Fortran 77 program and, although with out comments, its intent is more immediately obvious.
c Fortran implementation of ``hugemats''
c
program hugemat
implicit integer*2 (a - z)
parameter (mrow=250, mcol=300)
dimension a(mrow,mcol), b(mrow,mcol),
c(mrow,mcol)
call acquir (a, mrow, mcol)
call acquir (b, mrow, mcol)
do 20 i = 1, mrow
do 10 j = 1, mcol
c(i,j) = a*i,j) + b(i,j)
10 continue
20 continue
print 30, 'Proof:'
print 40, '1[1,1]', a(1,1)
print 40, 'b[1,1]', b(1,1)
print 40, 'c[1,1]', c(1,1)
print 30, ' '
print 40, 'a[mrow,mcol]', a(mrow,mcol)
print 40, 'b[mrow,mcol]', b(mrow,mcol)
print 40, 'c[mrow,mcol]', c(mrow,mcol)
30 format (' ',a)
40 format (' ',a,' = ',i5)
end
subroutine acquir (array, n1, n2)
implicit integer*2 (a - z)
dimension array(n1,n2)
do 20 8 = 1, n1
do 10 j = 1, n2
array(i,j) = i * 10 + j
10 continue
20 continue
return
end
C.B. Chapman
London, Ontario
Dear DDJ,
I have followed the "Turbo C vs. Quick C" debate with some interest. Availability? Quick C has been on sale at my local branch of B. Dalton for weeks. Turbo C was rushed to market earlier (but still late) and full of bugs.
Few people have focused upon the single most important difference between the two compilers--debugging. In my many years as a professional programmer I have learned that finding runtime bugs is by far the most difficult and time consuming part of programming. Finding syntax errors at compile time is normal, but not significant. Why has Borland never produced a source level debugger like Codeview? There are plenty out there that Borland could simply buy and customize. I think that this is the single greatest weakness of all Borland products.
Colin J. Davies
Granada Hills, CA
Unbeknownst to his colleagues, Gil had reached the end of his interrupt chain.
Dear DDJ,
I was reading with amusement your recent exchanges about the relative merits of the Quick C and Turbo C compilers. Since I have bought and used both, and since I returned my Quick C compiler for a refund, have some opinions about them. My version of Quick C was 1.0, and my Turbo C is 1.5. I have a 4,800 line program that had already trashed my Let's C source-level debugger and my DOS-Debug utility, and it did the same for Quick C's debugger. The Quick C debugger developed a case of frozen screen with funny-looking symbols and music notes appearing at random on what was supposed to be the display of my program executing.
About the Quick C documentation: Yes, indeed, it does have excellent C documentation, although the Turbo C documentation really is not that bad compared with, say, The C Programming Language of K and R. But the documentation for the Quick C debugger is almost nonexistent and what is there is cryptic and unusable. Let someone cleverer than me find out how to single-step the debugger from the documentation; or, how to stop the debugger once it is started in "display steps in execution" mode. There are no answers anywhere in the manuals, nor even references in the index on the debugger.
Since the main reason that I bought Quick C was to use the debugger, I have some reasons to dislike what I got: first of all, the debugger is crippled. It only accepts programs that have just been compiled, and excludes re-loading and debugging previously compiled programs. You can only compile in medium model if you want the debugger to work, even if you have a program that only works in huge model (I hope C beginners realize that large programs have to use special "memory models" to work properly on the PC), and Quick C does not support huge model compilation. And, let me tell you, you can write a will and fill out your income tax while Quick C is compiling and then loading the debugger. With my 4,800-line program, the debugger took over a half hour to compile and load. If you have ever used the Let's C compiler and source debugger, you know that Quick C makes Let's C look good on that basis.
Do you know what the underground bargain C compiler of this year is? It's the Mix Power C compiler. For under $25 with shipping, it is one heck of a good compiler, and the manual is worth the price of admission. It's C preprocessor will substitute macro arguments into the middle of strings for you (so you can macroize your printf ("debug message with dubbed parameter") statements using your h file); and, while it has a problem with newlines inserted in the middle of parameters supplied to the macro-processor, it is otherwise quite stable and handles really large programs (in large model, not huge). While Turbo C is faster and can handle huge model programs, its macro preprocessor will not substitute arguments into the middle of strings for you, instead the strings resulting from the macro-expansion will contain the macro parameter name.
To be fair, the Turbo C Windows package is worth the cost of the compiler, and the Power C business math and graphics package is definitely a worthwhile acquisition. Turbo C has to be the world's fastest screen writer, both in windows mode and standard printf to stdout and stderr mode. Both Turbo C and Power C have optional run-time stack overflow tests automatically inserted into compiled code.
Since C programs work in mysterious ways and can and do overwrite memory and go into recursive bugs, the stack test is a minimal safety net that is really needed. I only wish that the enumeration type of C could be used to force range tests Pascal-style in compiled code. That way, while debugging I could enum some of my important variables and specify their lower and upper bounds in the enum set, knowing that the compiler would insert correctness tests wherever I did C arithmetic with these variables. As matters presently stand, the compilers refuse to let me do arithmetic with these variables, and don't seem to enforce bounds on their values by run-time checking.
Victor Schneider
Brighton, MA 02146