当你想了解一个函数(或方法)在做什么,你可以如下策略:
- 根据函数名猜测
- 阅读函数头的注释
- 分析函数是如何被使用
- 阅读函数体內的代码
- 查询外部程序文档
- 养成碰到库函数就阅读文档的习惯(传送门如何查看函数)
注释是重点啊啊啊!强行观看,下面上“热腾腾”开源代码
<span style="font-size:18px;"> /*<span style="color: rgb(255, 0, 0);">返回值储存于整型变量中</span>*/
while ((<span style="color: rgb(255, 0, 0);">c</span> = getopt (argc, argv, "t:")) != -1) {
switch (c) {
case 't':
getstops(optarg);
break;
/*<span style="color: rgb(255, 0, 0);">二者共用一段代码</span>*/
case '?':
default:
usage();
/* NOTREACHED */
}
}
</span>
<span style="font-size:18px;"> case 'a':
fts_options |= FTS_SEEDOT;
/* <span style="color:#ff0000;">FALLTHROUGH </span>
<span style="color:#ff0000;">没有break,return,continue时,用一条注释进行说明.接着判断'</span><span style="color: rgb(255, 0, 0); font-family: SimSun;">A'</span>
*/
case 'A':
f_listdot = 1;
break</span>
<span style="font-size:18px;"> case BATCH:
writefile(time(NULL), 'b');
break;
/*<span style="color:#ff0000;">捕获产生意外值的程序错误提醒程序维护者</span>*/
default:
panic("Internal error");
break;</span>
<span style="font-size:18px;"> while ((c = getchar()) != EOF) {
/*<span style="color:#ff0000;">switch语句用作程序字符处理循环的一部分</span>*/
switch (c) {
case '\t':
if (nstops == 0) {
do {
putchar(' ');
column++;
} while (column & 07);
continue;
}
if (nstops == 1) {
do {
putchar(' ');
column++;
} while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
continue;
}
for (n = 0; n < nstops; n++)
if (tabstops[n] > column)
break;
if (n == nstops) {
putchar(' ');
column++;
continue;
}
while (column < tabstops[n]) {
putchar(' ');
column++;
}
continue;
case '\b':
if (column)
column--;
putchar('\b');
continue;
/*<span style="color:#ff0000;">所有其他字符*</span>/
default:
putchar(c);
column++;
continue;
case '\n':
putchar(c);
column = 0;
continue;
}
}
} while (argc > 0);
exit(0);
}
</span>
<span style="font-size:18px;">if ((<span style="color:#ff0000;">dd = opendir(dir)) == NULL)</span>
return (CC_ERROR);
words = sl_init();
/*<span style="color:#ff0000;">循环处理库函数返回的结果集</span>*/
for (<span style="color:#ff0000;">dp = readdir(dd); dp != NULL; dp = readdir(dd)</span>)</span>
<span style="font-size:18px;"><span style="color:#ff0000;">for (cnt = 1, t = p; cnt <= cnt_orig; ++t, ++cnt)</span> {
t->lno = lno;
t->coff = 0;
t->soff = cnt;
SMAP_FLUSH(t);
if (vs_line(sp, t, NULL, NULL))
return (1);
} </span>
<span style="font-size:18px;">void
transition(s)
state_t s;
{
/*<span style="color:#ff0000;">无限循环控制所有的unix进程
在大多的情况下,无限循环用来表达循环开始或结束时退出条件无法确定的循环
return,break,exit退出
</span> */
for (;;) {
s = (state_t) (*s)();
#ifndef LETS_GET_SMALL
quiet = 0;
#endif
}
}
</span>
<span style="font-size:18px;">static void
getstops(cp)
char *cp;
{
int i;
nstops = 0;
for (;;) {
i = 0;
/*将字符串转换为数字*/
while (*cp >= '0' && *cp <= '9')
i = i * 10 + *cp++ - '0';
/*<span style="color:#ff0000;">德摩根法则解开复杂的逻辑表达式*</span>/
if (i <= 0 || i > 256) {
/*<span style="color:#ff0000;">抱怨不合理的说明</span>*/
bad:
fprintf(stderr, "Bad tab stop spec\n");
exit(1);
}
/*<span style="color:#ff0000;">短路求值*</span>/
if (nstops > 0 && i <= tabstops[nstops-1])
goto bad;
tabstops[nstops++] = i;
/*<span style="color:#ff0000;">跳出循环,局部重构*</span>/
if (*cp == 0)
break;
else if (*cp != ',' && *cp != ' ')
goto bad;
else
cp++;
}
}
</span>
<span style="font-size:18px;">/*<span style="color:#ff0000;">短路求值,只有t == NULL时,才计算t->type的值*</span>/
if (t != NULL && t->type != TEOF && interactive && really_exit)
</span>
<span style="font-size:18px;">/*<span style="color:#ff0000;">移位运算符计算</span>*/
n = ((dp - cp) << 2) + 1; /* 4 times + NULL */
</span>
<span style="font-size:18px;">int
atmresolve(rt, m, dst, desten)
register struct rtentry *rt;
struct mbuf *m;
register struct sockaddr *dst;
/*<span style="color:#ff0000;">有时也用标有in或out的注释来标记引用参数*/</span>
register struct atm_pseudohdr *desten; /<span style="color:#ff0000;">* OUT *</span>/
{</span>
</pre><pre name="code" class="cpp"><span style="font-size:18px;">
</span>
<span style="font-size:18px;"> /*<span style="color: rgb(255, 0, 0);">初始化栈</span>*/
stackp = de_stack;
while ((code = getcode(zs)) > -1) {
if ((code == CLEAR) && block_compress) {
for (code = 255; code >= 0; code--)
tab_prefixof(code) = 0;
clear_flg = 1;
free_ent = FIRST - 1;
if ((code = getcode(zs)) == -1) /* O, untimely death! */
break;
}
incode = code;
/* Special case for KwKwK string. */
if (code >= free_ent) {
/*<span style="color: rgb(255, 0, 0);">将finchar压栈*</span>/
*stackp++ = finchar;
code = oldcode;
}
/* Generate output characters in reverse order. */
while (code >= 256) {
*stackp++ = tab_suffixof(code);
code = tab_prefixof(code);
}
*stackp++ = finchar = tab_suffixof(code);
/* And put them out in forward order. */
middle: do {
if (count-- == 0)
return (num);
/*<span style="color: rgb(255, 0, 0);">将栈顶内容弹到*bp中</span>*/
*bp++ = *--stackp;
} /*<span style="color: rgb(255, 0, 0);">检查栈是否为空*</span>/
while (stackp > de_stack);</span><pre name="code" class="cpp" style="font-size: 18px;">利用指针方式访问基于数组的栈
<span style="font-size:18px;">char *inet_ntoa(ad)
struct in_addr ad;
{
unsigned long int s_ad;
int a, b, c, d;
/*<span style="color:#ff0000;">防止返回的数组的内存空间被重写*</span>/
static char addr[20];
s_ad = ad.s_addr;
d = s_ad % 256;
s_ad /= 256;
c = s_ad % 256;
s_ad /= 256;
b = s_ad % 256;
a = s_ad / 256;
sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
return addr;
}</span>