idioms
shuiming.....i got the main structure part of c, such as # include
for ( ; *s != '\0'; s++)
if (*s < '0' || *s > '9')
return 0;
return 1;
cc.....That's a normal stage. The structure is the skeleton, and details like this are where C packs a lot into a few characters. The best method is to translate each piece into words, then trace a tiny example by hand. Here's the whole function, since the first two lines matter too:
int digits_only(const char *s)
{
if (*s == '\0')
return 0;
for ( ; *s != '\0'; s++)
if (*s < '0' || *s > '9')
return 0;
return 1;
}
The same logic, written more slowly If the compact form is hard to read, these do exactly the same thing:
// with an index instead of moving the pointer
for (i = 0; s[i] != '\0'; i++)
if (s[i] < '0' || s[i] > '9')
return 0;
// with while: setup, test, step on separate lines
while (*s != '\0') {
if (*s < '0' || *s > '9')
return 0;
s++;
}
K&R's style, and mine in cc-c.c, is the compact one. Once each piece has a meaning in your head, the compact form reads just as easily, and that comes from repetition, one exercise at a time.
A habit that helps with every dense line: take the smallest possible input ("1x"), write the memory boxes on paper, and step through with your finger. It's slow the first ten times and automatic after that.
shuiming.....good news is that those dense lines are limited numbers. so one by one they are going to be solved.
cc.....Exactly. C has a small set of idioms, dense patterns that come back again and again. Once you know one, you recognize it everywhere. Most of K&R is built from about a dozen of them:
Idiom In words Where you've seen it
while ((c = getchar()) != EOF) read a character, stop at end of input detab, entab, my_getline
for ( ; *s != '\0'; s++) walk a string to its end digits_only, todigits
*p++ = c store at p, then move p along my_getline
*++p move p along, then read day_of_year (5-9)
c - '0' turn a digit character into its number todigits, K&R's atoi
n = 10 * n + (c - '0') build a number digit by digit todigits
c >= '0' && c <= '9' (or its opposite) is it a digit? digits_only
(x >> k) & 1 read bit k putbits, hexagrams_big
x & 0x3F, x | 0x80 keep some bits, set some bits UTF-8 encode/decode
sizeof a / sizeof a[0] number of elements in an array 5-8's test tables
(*++argv)[0] vs *++argv[0] next word vs next character find
val[sp++] = f / val[--sp] push and pop a stack expr (5-10)
cond ? a : b choose one of two values YANG : YIN, putbits
That's roughly the whole list for chapters 1–5. Chapter 6 (structures) adds a few more, like p->next, but the pattern is the same: finite, repeated, and learnable one at a time, just as you said.
A good way to use the table: next time a dense line stops you, check whether it's one of these. Usually it is, sometimes two combined.