![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Newbie
Join Date: Dec 2005
Posts: 15
Rep Power: 0
![]() |
Code Critique
Hi, all. I don't so much have a problem. My code works (or at least, it does in all tests I've ran so far), but as I'm still working on some of the examples in K&R, I'm just looking for some comments. Criticisms especially. If I've done something dumb, I want to know about it. Any feedback is helpful
.Please note that I'm not using pointers, functions, or anything that has not been introduced yet at this time in the book... trying to play fair. ![]() Anywhoo... here's the assignment, from the K&R text. Quote:
/* K&R
* Chapter 1
* Exercise 1-13
* Prints a histogram of word sizes
*/
#include <stdio.h>
#define MAXSIZE 10 /* Maximum word size */
int main(void)
{
int arr[MAXSIZE+1]; /* 10 sizes of words, plus a >MAXSIZE field */
int i, j, nc, c; /* Loop counters, number of characters, character */
int highest = 0; /* Used to get the highest value in arr[] */
/* initialize arr[] to 0*/
for (i = 0; i <= MAXSIZE; ++i)
arr[i] = 0;
nc = 0;
while ((c = getchar()) != EOF) {
++nc; /* Here we increment with each character until we hit a blank... */
if (c == ' ' || c == '\n' || c == '\t' || c == EOF){
--nc; /* ...then drop the blank */
if (nc <= MAXSIZE) {
arr[nc-1]++;
nc = 0;
} else if (nc > MAXSIZE) {
arr[MAXSIZE]++;
nc = 0;
}
}
}
/* Let's see what the highest number in arr[] is */
for (i = 0; i <= MAXSIZE; ++i) {
if (arr[i] > highest)
highest = arr[i];
}
/*Now let's do a vertical histogram */
while (highest > 0) {
printf("\t%3d: ", highest);
for (i = 0; i <= MAXSIZE; ++i) {
if (highest > arr[i])
printf(" ");
else
printf(" | ");
}
printf("\n");
highest--;
}
/* And now, the footer */
printf("\t --------------------------------------------------------\n\t ");
for(i = 0; i <= MAXSIZE; ++i) {
if (i < MAXSIZE)
printf(" %d ", i+1);
else
printf(">%d ", MAXSIZE);
}
return 0;
}Thanks, Phil |
|
|
|
|
|
|
#2 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5
![]() |
1) Declare your array to be of dimension MAXSIZE rather than MAXSIZE+1, and set loop conditions accordingly. For example, your first loop would be;
for (i = 0; i < MAXSIZE; ++i) arr[i] = 0; 2) Favour preincrement (eg ++arr[nc-1]) over postincrement (eg arr[nc-1]++) unless you need to use the previous value. 3) If the first character in your input is a space, then the logic will be (commented) nc = 0;
while ((c = getchar()) != EOF) {
++nc; /* nc now 1 */
if (c == ' ' || c == '\n' || c == '\t' || c == EOF){ /* we've entered a space, so ... */
--nc; /* nc now zero */
if (nc <= MAXSIZE) { /* this test is true */
arr[nc-1]++; /* arr[-1]++ */4) Rather than testing against various whitespace characters, try the function isspace() which is in <ctype.h> 5) Compute the max value in your array like this; highest = arr[i];
for (i = 1; i < MAXSIZE; ++i) { /* end condition corrected as per first tip */
if (arr[i] > highest)
highest = arr[i];
}6) Better yet, eliminate the computation of max and simply sort the array (but retain duplicate values). Then the values will contain values in order that you want to print them, and you simply need to count the number of times a value is in sequence to get the value for your histogram. This will be more efficient than what you're doing (printing highest, searching the whole array for that value, decrementing highest, and going over and over again). |
|
|
|
|
|
#3 | |
|
Newbie
Join Date: Dec 2005
Posts: 15
Rep Power: 0
![]() |
Quote:
while ((c = getchar()) != EOF) {
++nc;
if (isspace(c) ){
--nc;
if ((nc > 0) && (nc < MAXSIZE)) {
++arr[nc-1];
nc = 0;
} else if (nc > MAXSIZE) {
arr[MAXSIZE]++;
nc = 0;
}
}
}Phil |
|
|
|
|
|
|
#4 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5
![]() |
My third comment is about a real problem in your code; that problem is a showstopper. If your user inputs a space as the first character (or a '\n' or a '\t' ....) the program yields undefined behaviour. This is because of a basic flaw in your program logic. Read the comments in the code snippet I gave to see why.
The point of my 4th comment is to use isspace() from <ctype.h>. That is a minor improvement, which has nothing to do with addressing the preceding problem of undefined behaviour. |
|
|
|
|
|
#5 | |
|
Newbie
Join Date: Dec 2005
Posts: 15
Rep Power: 0
![]() |
Quote:
At any rate, I added an additional test to the second if statement (see comments), only entering the statement if nc is between 0 and MAXSIZE. When I get home I'm going to work on this some more. I do appreciate the help, though! :-)
while ((c = getchar()) != EOF) {
++nc; /* Increment to 1*/
if (isspace(c) ){
--nc; /* Toss out the space, nc is now 0 */
if ((nc > 0) && (nc < MAXSIZE)) { /* This test fails if nc is 0, correct? */
++arr[nc-1];
nc = 0;
} else if (nc > MAXSIZE) {
arr[MAXSIZE]++;
nc = 0;
}
}
} |
|
|
|
|
|
|
#6 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5
![]() |
A couple more comments
1) If you use a test case that contains two or more spaces in sequence, the histogram will not be correct. I'm guessing all your test cases only have one space between two words. 2) Something that works along the lines; ++x;
if (some_condition)
{
--x;
more_stuff();
}[code] if (some_condition)
{
more_stuff();
}
else
{
++x;
} |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|