idioms

2026-09-27

shuiming.....i got the main structure part of c, such as # include ; #define MAXSTOPS 100 ; int start = 0; int istab(int col); in main(int argc, char *argv[]; int digits_only(const char *s) etc. my issue is in details, such as

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.