分类: C/C++
2008-04-25 21:49:48
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int max);
int strindex(char source[], char searchfor[]);
char patterns[] = "ould"; /* pattern to search for */
/* find all lines matching pattern */
int main()
{
char line[MAXLINE];
int found = 0;
while (getline(line, MAXLINE) > 0)
if (strindex(line, pattern) >= 0) {
printf("%s", line);
found++;
}
return found;
}
// 注意与第一章的getline进行比较。区别主要在于控制结构的使用。在第一章用的是for语句。这里使用
// 的是while语句
/* getline: get line into s, return length */
int getline(char s[], int lim)
{
int c, i;
i = 0;
while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
s[i++] = c;
if (s == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
// 注意了解此函数接口设计的缘由,书中有相关介绍
// 对于寻找子串应该有更好的算法
/* strindex: return index of t in s, -1 if none */
int strindex(char s[], char t[])
{
int i, j, k;
for (i = 0; s[i] != '\0'; i++) {
for (j=i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++)
;
if (k > 0 && t[k] == '\0')
return i;
}
return -1;
}
#include <ctype.h>
/* atof: convert string to double */
double atof(char s[])
{
double val, power;
int i, sign;
/* skip white space */
for (i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if (s[i] == '.')
i++;
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10;
}
return sign * val / power;
}
#include <stdio.h>
#define MAXLINE 100
/* rudimentary calculator */
int main()
{
double sum, atof(char []); //注意这里对函数的声明方式
char line[MAXLINE];
int getline(char line[], int max); // 声明getline函数
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n", sum += atof(line));
return 0;
}
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []); // 这种申明方式自己以前还没有用到过
void push(double);
double pop(void);
/* reverse Polish calculator */
main()
{
int type;
double op2;
char s[MAXOP];
// 看来getop的实现很关键
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
return 0;
}
}
#define MAXVAL 100 /* maximum depth of val stack */
// 下面两个是外部变量的例子了。
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
/* push: push f onto value stack */
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
/* pop: pop and return top value from stack */
double pop()
{
if (sp > 0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getop: get next character or numeric operand */
int getop(char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[i] = '\0';
if (!isdigit(c) && c != '.')
return c; /* not a number */
i = 0;
if (isdigit(c)) /* collect integer part */
while (isdigit(s[++i] = c = getch())
;
if (c == '.') /* collect fraction part */
while (isdigit(s[++i] = c = getch())
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
// 另外两个external变量的实例。
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) /* get a (possibly pushed-back) character */
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* push character back on input */
{
if (bufp > BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
第四节和第五节讲解的是Scope rules和header files。也就是如何将上面的几个文件进行分配,以存放到不同的文件中。一种比较常见的方法是将所有外部可用的函数都声明在一个hearder files中,然后再在其他的.c文件中进行实现。
第六节 将static variables。当将static用于external variables时,可以限制该external variables只能在定义该变量的文件中使用。在上面的代码中,其实我们就可以将buf和bufp声明为static变量,如
static char buf[BUFSIZE];
static int bufp = 0;
另外static同样可以运用于函数以及internal variables。但是含义有所变化。
第十一节 预处理。分为三个部分:文件的包含,宏替换和条件编译。对于文件包含也就是#include命令。对于宏替换,是用#define命令。对于宏替换的几个例子:
#define forever for(;;) /* infinite loop */
#define max(A, B) ((A) > (B) ? (A) : (B))
#define dprint(expr) printf(#expr " = %g\n", expr) //#的作用
#define paste(front, back) front ## back
//##的作用, paste(name, 1) == name1
#if !defined(HDR)
#define HDR
/* contents of hdr.h go here */
#endif
#if SYSTEM == SYSV
#define HDR "sysv.h"
#elif SYSTEM == BSD
#define HDR "bsd.h"
#elif SYSTEM == MSDOS
#define HDR "msdos.h"
#else
#define HDR "default.h"
#endif
#include HDR
#ifndef HDR
#define HDR
/* contents of hdr.h go here */
#endif