C程序设计语言(第2版) 不念不忘少年蓝@ 2022-08-05 11:08 192阅读 0赞 C程序设计语言(第2版) 这儿有一篇写的很好的读后感:[http://www.cnblogs.com/xkfz007/articles/2566424.html][http_www.cnblogs.com_xkfz007_articles_2566424.html] 第1章 导言 1. 单词计数 ![复制代码][copycode.gif] \#include <stdio.h> int main()\{ int c,nl,nw,nc,flag; flag= 0; nl=nw=nc= 0; while((c=getchar())!=EOF)\{ ++nc; if(c== ' \\n ') nl++; if(c== ' '||c== ' \\n '||c== ' \\t ') flag= 0; else if(!flag)\{ flag= 1; ++nw; \} \} printf( " %3d %3d %3d\\n ",nl,nw,nc); return 0; \} ![复制代码][copycode.gif] ![201208051119386901.png][] 2. 函数参数——传值调用 在C语言中,所有函数参数都是通过"值"传递的。也就是说,传递给被调用函数的参数值存放在临时变量中,而不是存放在原来的变量中。这与其他某些语言是不同的。比如,Fortran等语言是通过"引用"调用,Pascal则采用var参数方式,在这些语言中,被调用的函数必须访问原始参数,而不是访问参数的本地副本。 最主要的区别在于,在C语言中,被调用函数不能直接修改主调函数中变量的值,而只能修改其私有临时副本的值。 传值调用的利大于弊。在被调用该函数中,参数可以看作是便于初始化的局部变量,因此额外使用的变量更少。这样程序可以更紧凑简洁。 3. 读入一组文本,打印出最长文本 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int getline\_( char s\[\], int lim)\{ int c,i; i= 0; while(i<lim- 1&&(c=getchar())!=EOF&&c!= ' \\n ')\{ s\[i++\]=c; \} if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') s\[i++\]=c; s\[i++\]= ' \\0 '; return i; \} void copy( char str1\[\], char str2\[\])\{ while((\*str1++=\*str2++)!= ' \\0 '); \} int main()\{ char line\[ 256\]; char longest\[ 256\]; char shortest\[ 256\]; int len; int max= 0,min= 256; while((len=getline\_(line, 256))>- 1)\{ if(len>=max) \{ max=len; copy(longest,line); \} else if(len<=min) \{ min=len; copy(shortest,line); \} \} if(max> 0) printf( " %d:%s ",max,longest); if(min< 256) printf( " %d:%s ",min,shortest); return 0; \} ![复制代码][copycode.gif] 下面是输出结果,输入是上面的源代码: ![201208051119395473.png][] 课后题程序: 习题1-8 编写一个统计空格、制表符和换行符个数的程序。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int main()\{ int c,nb,nt,nl; nb= 0; nt= 0; nl= 0; while((c=getchar())!=EOF)\{ if(c== ' ') nb++; else if(c== ' \\t ') nt++; else if(c== ' \\n ') nl++; \} printf( " %2d %2d %2d\\n ",nb,nt,nl); \} ![复制代码][copycode.gif] 习题1-9 编写一个将输入复制到输出的程序,并将其中连续的多个空格使用一个空格代替 ![复制代码][copycode.gif] \#include <stdio.h> int main()\{ int c; int nb; int prec=- 1; while((c=getchar())!=EOF)\{ if(c== ' '&&prec== ' ') continue; else \{ putchar(c); prec=c; \} \} \} ![复制代码][copycode.gif] 习题1-12 编写一个程序,以每行一个单词的形式打印其输入 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int main()\{ int c; int flag; flag= 0; while((c=getchar())!=EOF)\{ if(c== ' '||c== ' \\n '||c== ' \\t ')\{ if(flag)\{ putchar( ' \\n '); flag= 0; \} \} else if(!flag)\{ flag= 1; putchar(c); \} else\{ putchar(c); \} \} \} ![复制代码][copycode.gif] 习题1-13 编写一个程序,打印输入中单词长度的直方图。水平方向的直方图比较容易绘制,垂直方向的直方图则要困难写。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define MAXHIST 15 \#define MAXWORD 11 int word\_stats( int wl\[\])\{ int flag; int c,nc,i,ovflow; flag= 0; nc= 0; ovflow= 0; for(i= 0;i<MAXWORD;i++) wl\[i\]= 0; while((c=getchar())!=EOF)\{ if(c== ' '||c== ' \\n '||c== ' \\t ')\{ if(flag)\{ flag= 0; // if(nc>0) if(nc<MAXWORD) wl\[nc\]++; else ovflow++; nc= 0; \} \} else if(!flag)\{ flag= 1; nc= 1; \} else nc++; \} return ovflow; \} void hist\_h( int wl\[\])\{ int i; int maxvlaue= 0; int len; for(i= 1;i<MAXWORD;i++) if(wl\[i\]>maxvlaue) maxvlaue=wl\[i\]; for(i= 1;i<MAXWORD;++i)\{ printf( " %5d - %5d : ",i,wl\[i\]); if(wl\[i\]> 0)\{ if((len=wl\[i\]\*MAXHIST/maxvlaue)<= 0) len= 1; \} else len= 0; while(len> 0)\{ putchar( ' \* '); len--; \} putchar( ' \\n '); \} \} void hist\_v( int wl\[\])\{ int i,j; int maxvlaue= 0; int len; for(i= 1;i<MAXWORD;i++) if(wl\[i\]>maxvlaue) maxvlaue=wl\[i\]; for(i=MAXHIST;i> 0;i--)\{ for(j= 1;j<MAXWORD;j++) if(wl\[j\]\*MAXHIST/maxvlaue>=i) printf( " \* "); else printf( " "); putchar( ' \\n '); \} for(i= 1;i<MAXWORD;i++) printf( " %4d ",i); putchar( ' \\n '); for(i= 1;i<MAXWORD;i++) printf( " %4d ",wl\[i\]); putchar( ' \\n '); \} int main()\{ int wl\[MAXWORD\]; int ovflow; ovflow=word\_stats(wl); hist\_h(wl); hist\_v(wl); if(ovflow) printf( " Overflow: %d\\n ",ovflow); \} ![复制代码][copycode.gif] ![201208051119394360.png][] 下面是以上面的源文件为输入得到的运行结果: ![201208051119391295.png][] 习题1-18 编写一个程序,删除每个输入行末尾的空格及制表符,并删除完全是空格的行 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int getline\_( char s\[\], int lim)\{ int c; int i; i= 0; while(i<lim- 1&&(c=getchar())!=EOF&&c!= ' \\n ')\{ s\[i++\]=c; \} if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') s\[i++\]=c; s\[i++\]= ' \\0 '; return i; \} int remove\_( char s\[\])\{ int i; i= 0; while(s\[i\]!= ' \\n ') ++i; --i; while(i>= 0&&(s\[i\]== ' '||s\[i\]== ' \\t ')) --i; if(i>= 0)\{ s\[++i\]= ' \\n '; s\[++i\]= ' \\0 '; \} return i; \} int main()\{ char line\[ 256\]; while(getline\_(line, 256)> 0)\{ if(remove\_(line)> 0) printf( " %s ",line); \} \} ![复制代码][copycode.gif] 习题1-19 编写函数rverse(s)将字符串s中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒一个输入行中的字符顺序。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int getline\_( char s\[\], int lim)\{ int c; int i; i= 0; while(i<lim- 1&&(c=getchar())!=EOF&&c!= ' \\n ')\{ s\[i++\]=c; \} if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') s\[i++\]=c; s\[i++\]= ' \\0 '; return i; \} void reverse\_( char s\[\])\{ int i,j; char c; i= 0; while(s\[i\]!= ' \\0 ') i++; i--; if(s\[i\]== ' \\n ') i--; j= 0; while(j<i)\{ c=s\[i\]; s\[i\]=s\[j\]; s\[j\]=c; j++; i--; \} \} int main()\{ char line\[ 256\]; while(getline\_(line, 256)> 0)\{ reverse\_(line); printf( " %s ",line); \} \} ![复制代码][copycode.gif] 习题1-20 请编写程序detab,将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止的地方。假设制表符终止的位置是固定的,比如每隔n列就会出现一个制表符终止位。n应该作为变量还是常量呢? ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define TABINC 8 int main()\{ int c,nb,pos; nb= 0; pos= 1; while((c=getchar())!=EOF)\{ if(c== ' \\t ')\{ nb=TABINC-(pos- 1)%TABINC; while(nb> 0)\{ putchar( ' '); pos++; nb--; \} \} else if(c== ' \\n ')\{ putchar(c); pos= 1; \} else\{ putchar(c); pos++; \} \} \} ![复制代码][copycode.gif] ![201208051119396279.png][] 习题1-21 编写程序entab,将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变。假设制表符终止位的位置与练习1-20的detab程序的情况相同。当使用一个制表符或者一个空格都可以到达下一个制表符终止位时,选用那种替换字符比较好? ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define TABINC 8 int main()\{ int c,nb,nt,pos; nb= 0; nt= 0; pos= 1; while((c=getchar())!=EOF)\{ if(c== ' ')\{ if(pos%TABINC!= 0) ++nb; else\{ nb= 0; nt++; \} \} else\{ while(nt> 0)\{ putchar( ' \\t '); nt--; \} if(c== ' \\t ') nb= 0; else while(nb> 0)\{ putchar( ' '); nb--; \} putchar(c); if(c== ' \\n ') pos= 0; else if(c== ' \\t ') pos=pos+(TABINC-(pos- 1)%TABINC)- 1; \} pos++; \} \} ![复制代码][copycode.gif] ![201208051119394294.png][] 习题1-22 ![201208051119405689.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define MAXCOL 10 \#define TABINC 8 char line\[MAXCOL\]; int exptab( int pos); int findblnk( int pos); int newpos( int pos); void printl( int pos); int main()\{ int c,pos; pos= 0; while((c=getchar())!=EOF)\{ line\[pos\]=c; if(c== ' \\t ') pos=exptab(pos); else if(c== ' \\n ') \{ printl(pos); pos= 0; \} else if(++pos>=MAXCOL)\{ pos=findblnk(pos); printl(pos); pos=newpos(pos); \} \} \} void printl( int pos)\{ int i; for(i= 0;i<pos;i++) putchar(line\[i\]); if(pos> 0) putchar( ' \\n '); \} int exptab( int pos)\{ line\[pos\]= ' '; for(++pos;pos<MAXCOL&&pos%TABINC!= 0;++pos) line\[pos\]= ' '; if(pos<MAXCOL) return pos; else\{ printl(pos); return 0; \} \} int findblnk( int pos)\{ while(pos> 0&&line\[pos\]!= ' ') pos--; if(pos== 0) return MAXCOL; else return pos+ 1; \} int newpos( int pos)\{ int i,j; if(pos<= 0||pos>=MAXCOL) return 0; else\{ i= 0; for(j=pos;j<MAXCOL;++j)\{ line\[i\]=line\[j\]; ++i; \} return i; \} \} ![复制代码][copycode.gif] ![201208051119408164.png][] 习题1-23 编写一个删除C语言程序中所有的注释语句。要正确处理带银行的字符串与字符常量。在C语言中,注释不允许嵌套。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> void rcomment( int c); void in\_comment( void); void echo\_quote( int c); int main()\{ int c; while((c=getchar())!=EOF) rcomment(c); return 0; \} void rcomment( int c)\{ int d; if(c== ' / ') if((d=getchar())== ' \* ') in\_comment(); else if(d== ' / ')\{ putchar(c); rcomment(d); \} else\{ putchar(c); putchar(d); \} else if(c== ' \\' '||c== ' " ') echo\_quote(c); else putchar(c); \} void in\_comment( void)\{ int c,d; c=getchar(); d=getchar(); while(c!= ' \* '||d!= ' / ')\{ c=d; d=getchar(); \} \} void echo\_quote( int c)\{ int d; putchar(c); while((d=getchar())!=c)\{ putchar(d); if(d== ' \\\\ ') putchar(getchar()); \} putchar(d); \} ![复制代码][copycode.gif] ![201208051119409768.png][] 习题1-24 编写一个程序,检查C语言程序中的基本语法错误 ![201208051119401163.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int brace,brack,paren; void in\_quote( int c); void in\_comment( void); void search( int c); int main()\{ int c; while((c=getchar())!=EOF)\{ if(c== ' / ')\{ if((c=getchar())== ' \* ') in\_comment(); else search(c); \} else if(c== ' \\' '||c== ' " ') in\_quote(c); else search(c); if(brace< 0)\{ printf( " Unbalanced braces\\n "); brace= 0; \} else if(brack< 0)\{ printf( " Unbalanced brackets\\n "); brack= 0; \} else if(paren< 0)\{ printf( " Unbalanced parentheses\\n "); paren= 0; \} \} if(brace> 0) printf( " Unbalanced braces\\n "); if(brack> 0) printf( " Unbalanced brackets\\n "); if(paren> 0) printf( " Unbalanced parentheses\\n "); \} void search( int c)\{ if(c== ' \{ ') ++brace; else if(c== ' \} ') --brace; else if(c== ' \[ ') ++brack; else if(c== ' \] ') --brack; else if(c== ' ( ') ++paren; else if(c== ' ) ') --paren; \} void in\_comment( void)\{ int c,d; c=getchar(); d=getchar(); while(c!= ' \* '||d!= ' / ')\{ c=d; d=getchar(); \} \} void in\_quote( int c)\{ int d; while((d=getchar())!=c) if(d== ' \\\\ ') getchar(); \} ![复制代码][copycode.gif] ![201208051119414685.png][] 第2章 类型,运算符与表达式 1. const限定符 任何变量的声明都可以使用const限定符限定。该限定符指定变量的值不能被修改。对于数组而言,const限定符指定数组所有元素的值都不能被修改。 const char msg\[\]="warning:"; const限定符也可以配合数组参数使用,它表明函数不能修改该数组元素的值。 2. char类型 char类型是小整型 ![201208051119413016.png][] 3. 算术中的隐式类型转换 一般情况下,如果不含有unsigned类型,可以采用下面的方式: ![201208051119428523.png][] 注意float类型的特殊性: ![201208051119429046.png][] 当表达式中含有unsigned类型时: ![201208051119425981.png][] 函数参数中的类型转换: ![20120805111942965.png][] 4. 标准库中的伪随机数发生器函数:rand和srand 标准库中包含一个可移植的实现伪随机数发生器的函数rand以及一个初始化种子数的函数srand。rand函数中使用了强制类型转换: ![复制代码][copycode.gif] unsigned long int next= 1; /\* rand:return pseudo-random integer on 0..32767 \*/ int rand( void) \{ next=next\* 1103515245\+ 12345; return (unsigned int)(next/ 65536)% 32768; \} /\* srand:set seed for rand() \*/ void srand(unsigned int seed)\{ next=seed; \} ![复制代码][copycode.gif] 习题2-3 编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型数。字符串中允许包含的数字包括:0~9,a~f以及A-F ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#define YES 1 \#define NO 0 int htoi( char s\[\])\{ int hexd,i,inhex,n; i= 0; if(s\[i\]== ' 0 ')\{ ++i; if(s\[i\]== ' x '||s\[i\]== ' X ') ++i; \} n= 0; inhex=YES; while(inhex)\{ if(s\[i\]>= ' 0 '&&s\[i\]<= ' 9 ') hexd=s\[i\]- ' 0 '; else if(s\[i\]>= ' a '&&s\[i\]<= ' f ') hexd=s\[i\]- ' a '\+ 10; else if(s\[i\]>= ' A '&&s\[i\]<= ' F ') hexd=s\[i\]- ' A '\+ 10; else inhex=NO; if(inhex==YES) n= 16\*n+hexd; i++; \} return n; \} int main()\{ int count= 10; int i; char s\[ 100\]; for(i= 0;i< 10;i++)\{ int num=rand()% 10000; int n; sprintf(s, " %\#0x ",num); n=htoi(s); printf( " %\#0x %s %d %d \\n ",num,s,num,n); \} \} ![复制代码][copycode.gif] 一个运行结果展示: ![20120805111942409.png][] 习题2-4 重写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除 ![复制代码][copycode.gif] void squeeze( char s1\[\], char s2\[\])\{ int i,j,k; for(i=k= 0;s1\[i\]!= ' \\0 ';i++)\{ for(j= 0;s2\[j\]!= ' \\0 '&&s2\[j\]!=s1\[i\];j++); if(s2\[j\]== ' \\0 ') s1\[k++\]=s1\[i\]; \} s1\[k\]= ' \\0 '; \} ![复制代码][copycode.gif] ![201208051119428424.png][] 习题2-5 ![201208051119435359.png][] ![复制代码][copycode.gif] void any( char s1\[\], char s2\[\])\{ int i,j; for(i= 0;s1\[i\]!= ' \\0 ';i++) for(j= 0;s2\[j\]!= ' \\0 ';j++) if(s1\[i\]==s2\[j\]) return i; return - 1; \} ![复制代码][copycode.gif] 5. C语言中的位操作 getbits函数:返回x中从右边数第p位开始向右数n位的字段。这里假定最右边的一位是第0位,n与p都是合理的正值。 unsigned getbits(unsigned x, int p, int n)\{ return (x>>(p+ 1\-n))&~(~ 0<<n); \} ![20120805111943342.png][] ![复制代码][copycode.gif] unsigned sebits(unsgined x, int p, int n,unsigned y)\{ unsigned x1=x&(~ 0<<(p+ 1)); // 获取x的高32-(p+1)位 unsigned x2=x&(( 1<<(p-n+ 1))- 1); // 获取x的低p-n+1位 unsigned y1=(y&~(~ 0<<n))<<(p+ 1\-n); // 获得y的最低n位,并且移动到合适的位置 return x1|x2|y1; \} ![复制代码][copycode.gif] 可以换一种方式写: ![复制代码][copycode.gif] unsigned sebits(unsgined x, int p, int n,unsigned y)\{ unsigned m1= (~ 0<<(p+ 1))| (( 1<<(p-n+ 1))- 1); // 得到屏蔽码 unsigned x1=x&m1; unsigned y1=(y&~(~ 0<<n))<<(p+ 1\-n); // 获得y的最低n位,并且移动到合适的位置 return x1|y1; \} ![复制代码][copycode.gif] 下面是一个标准答案: ![20120805111944800.png][] 这儿比较难写是就是x的屏蔽码,下面的程序是对比两种方法产生的屏蔽码: ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> int main()\{ int i; for(i= 0;i< 10;i++)\{ int p=rand()% 32; int n=rand()%p+ 1; unsigned m1=(~ 0<<(p+ 1))|(( 1<<(p-n+ 1))- 1); unsigned m2=~(~(~ 0<<n)<<(p+ 1\-n)); printf( " p=%d n=%d: %\#0x %\#0x ",p,n,m1,m2); if(m1==m2) printf( " OK\\n "); else printf( " NO\\n "); \} \} ![复制代码][copycode.gif] 一个输出结果如下: ![20120805111944243.png][] ![201208051119445227.png][] ![复制代码][copycode.gif] unsigned invert(unsigned x, int p, int n)\{ unsigned x1=x&(~ 0<<(p+ 1)); // 获取x的高32-(p+1)位 unsigned x2=x&(( 1<<(p-n+ 1))- 1); // 获取x的低p-n+1位 unsigned x3=~x&(~(~ 0<<n)<<(p-n+ 1)); // 获取x的中间n位 return x1|x2|x3; \} ![复制代码][copycode.gif] 下面是一个标准答案 ![201208051119443765.png][] 下面是一个测试: ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> unsigned invert(unsigned x, int p, int n)\{ unsigned m1=(~ 0<<(p+ 1)); // 获取x的高32-(p+1)位 unsigned x1=x&m1; unsigned m2=(( 1<<(p-n+ 1))- 1); // 获取x的低p-n+1位 unsigned x2=x&m2; unsigned m3=(~(~ 0<<n)<<(p-n+ 1)); // 获取x的中间n位 unsigned x3=(~x)&m3; printf( " %\#0x %\#0x %\#0x\\n ",m1,m2,m3); return x1|x2|x3; \} unsigned invert2(unsigned x, int p, int n)\{ return x^(~(~ 0<<n)<<(p+ 1\-n)); \} int main()\{ int i; unsigned x=rand(); for(i= 0;i< 25;i++)\{ int p=rand()% 32; int n=rand()%p+ 1; int y1=invert(x,p,n); int y2=invert2(x,p,n); printf( " %\#0x %2d %2d %\#0x %\#0x ",x,p,n,y1,y2); if(y1==y2) printf( " OK\\n "); else printf( " NO\\n "); \} \} ![复制代码][copycode.gif] 输出如下: ![20120805111945701.png][] 可以看到当p=31时,第一种方法就出错了。主要是将一个无符号数进行右移32位(移出所有位)时,编译器会给出一个【 warning: right shift count >= width of type】的警告。然后返回原始值,而不是0 ![201208051119457320.png][] unsigned rightrot(unsigned x, int n)\{ unsigned x1=x>>n; // 左移得到高32-n位 unsigned x2=x<<( sizeof(x)\* 8\-n); // 右移得到低n位 return x1|x2; \} 下面标准答案给出的解释: ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> int wordlength() \{ int i; unsigned v=(unsigned)~ 0; for(i= 1;(v=v>> 1)> 0;i++) ; return 1; \} unsigned rightrot(unsigned x, int n)\{ int rbit; while(n--> 0)\{ rbit=(x& 1)<<(wordlength()- 1); x=x>> 1; x=x|rbit; \} return x; \} ![复制代码][copycode.gif] ![201208051119454256.png][] ![复制代码][copycode.gif] unsigned rightrot2(unsigned x, int n)\{ unsigned rbits; if((n-n%wordlength())> 0)\{ rbits=~(~ 0<<n)&x; rbits=rbits<<(wordlength()-n); x=x>>n; x=x|rbits; \} return x; \} ![复制代码][copycode.gif] ![201208051119457811.png][] 6. 统计整型数中二进制位1的个数: ![复制代码][copycode.gif] int bitcount(unsigned x)\{ int n= 0; while(x!= 0)\{ if(x& 0x1) n++; x>> 1; \} return n; \} ![复制代码][copycode.gif] 习题 2-9 在求对二的补码时,表达式x&(x-1)可以删除x中最右边为1的一个二进制位。请解释这样做的道理。用这一方法重写bitcount函数, 以加快其执行速度。 重写的代码如下: ![复制代码][copycode.gif] int bitcount(unsigned x)\{ int b; b= 0; while(x!= 0)\{ b++; x&=x- 1; \} return b; \} ![复制代码][copycode.gif] ![201208051119456698.png][]![201208051119466109.png][] 第3章 程序流控制 1. 折半查找 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int bin\_search( int x, int v\[\], int n)\{ int low,high,mid; low= 0; high=n- 1; while(low<=high)\{ mid=(low+high)>> 1; if(x<v\[mid\]) high=mid- 1; else if(x>v\[mid\]) low=mid+ 1; else return mid; \} return - 1; \} int bin\_search( int x, int v\[\], int n)\{ int low,high,mid; low= 0; high=n- 1; mid=(low+high)/ 2; while(low<=high&&x!=v\[mid\])\{ if(x<v\[mid\]) high=mid- 1; else low=mid+ 1; mid=(low+high)/ 2; \} if(x==v\[mid\]) return mid; else return - 1; \} ![复制代码][copycode.gif] ![201208051119466076.png][] 2. atoi函数 字符串转换为对应数值的函数atoi ![ContractedBlock.gif][] 测试输出如下: ![201208051119462695.png][] 希尔排序shell shell算法是D.L. Shell于1959年发明的,基本思想是:先比较近距离的元素,而不是像简单交换排序算法那样先比较相邻的元素。这样可以快速减少大量的无序情况,从而减轻后序的工作。被比较的元素之间的距离逐步减少,直到减少为1,这时编程了相邻元素的互换。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> void shellsort( int v\[\], int n)\{ int gap,i,j,temp; for(gap=n/ 2;gap> 0;gap/= 2) for(i=gap;i<n;i++) for(j=i-gap;j>= 0&&v\[j\]>v\[j+gap\];j-=gap)\{ temp=v\[j\]; v\[j\]=v\[j+gap\]; v\[j+gap\]=temp; \} \} void print\_arr( int v\[\], int n)\{ int i; for(i= 0;i<n;i++) printf( " %4d ",v\[i\]); printf( " \\n "); \} int main()\{ int i; for(i= 0;i< 10;i++)\{ int arr\[ 20\],j,b\[ 20\]; for(j= 0;j< 20;j++) \{ int val=rand()% 1000; arr\[j\]=val; b\[j\]=val; \} printf( " before: "); print\_arr(b, 20); shellsort(arr, 20); printf( " after : "); print\_arr(arr, 20); \} \} ![复制代码][copycode.gif] 测试输出如下: ![201208051119474614.png][] 习题 3-3 讲些函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc...xyz。该函数可以处理大小写字母和数字,并且可以处理a-b-c,a-z0-9与a-z等类似的情况。作为前导和尾随的字符原样复制。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> void expand( char s1\[\], char s2\[\])\{ char c; int i,j; i= 0; j= 0; while((c=s1\[i++\])!= ' \\0 ')\{ if(s1\[i\]== ' \- '&&s1\[i+ 1\]>=c)\{ i++; while(c<s1\[i\]) s2\[j++\]=c++; \} else s2\[j++\]=c; \} s2\[j\]= ' \\0 '; \} ![复制代码][copycode.gif] ![20120805111947993.png][] 函数itoa:将整型数转化为字符串 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> void itoa( int n, char s\[\])\{ int i,sign; int x,y; if((sign=n)< 0) n=-n; i= 0; do\{ s\[i++\]=n% 10\+ ' 0 '; \} while((n/= 10)> 0); if(sign< 0) s\[i++\]= ' \- '; s\[i\]= ' \\0 '; for(x= 0,y=i- 1;x<y;x++,y--) \{ char c=s\[x\]; s\[x\]=s\[y\]; s\[y\]=c; \} \} int atoi\_( char s\[\])\{ int i,n,sign; for(i= 0;isspace(s\[i\]);i++); sign=(s\[i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(n= 0;isdigit(s\[i\]);i++) n= 10\*n+(s\[i\]- ' 0 '); return sign\*n; \} int main()\{ int i; char s\[ 20\]; for(i= 0;i< 10;i++)\{ int val=rand(); int d; itoa(val,s); d=atoi\_(s); printf( " %12d %12s %12d ",val,s,d); if(val==d) printf( " OK\\n "); else printf( " NO\\n "); \} \} ![复制代码][copycode.gif] 测试结果如下: ![201208051119474025.png][] 习题3-4 ![201208051119477056.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] void itoa2( int n, char s\[\])\{ int i,sign; int x,y; sign=n; i= 0; do\{ s\[i++\]= ABS(n% 10)+ ' 0 '; \} while((n/= 10)!= 0); if(sign< 0) s\[i++\]= ' \- '; s\[i\]= ' \\0 '; for(x= 0,y=i- 1;x<y;x++,y--) \{ char c=s\[x\]; s\[x\]=s\[y\]; s\[y\]=c; \} \} ![复制代码][copycode.gif] ![201208051119484515.png][] 习题 3-5 编写函数itob(n,s,b),将整数n转换为以b为底的数,并将结果以字符的形式保存到字符串s中。例如,itob(n,s,16)把整数n格式化为十六进制整数保存在s中。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define ABS(x) ((x)<0?-(x):(x)) void itob( int n, char s\[\], int b)\{ int i,j,sign; int x,y; sign=n; i= 0; do\{ j=ABS(n%b); s\[i++\]=(j< 10)?j+ ' 0 ':j+ ' a '\- 10; \} while((n/=b)!= 0); if(sign< 0) s\[i++\]= ' \- '; s\[i\]= ' \\0 '; for(x= 0,y=i- 1;x<y;x++,y--) \{ char c=s\[x\]; s\[x\]=s\[y\]; s\[y\]=c; \} \} void test\_10()\{ int i; char s\[ 20\]; for(i= 0;i< 10;i++)\{ int val=rand(); int d; if(val& 0x1) val=-val; itob(val,s, 10); sscanf(s, " %d ",&d); printf( " %12d %12s %12d ",val,s,d); if(val==d) printf( " OK\\n "); else printf( " NO\\n "); \} \} void test\_8()\{ int i; char s\[ 20\]; for(i= 0;i< 10;i++)\{ int val=rand(); int d; if(val& 0x1) val=-val; itob(val,s, 8); // d=atoi\_(s); sscanf(s, " %o ",&d); printf( " %\#14o %14s %\#14o ",val,s,d); if(val==d) printf( " OK\\n "); else printf( " NO\\n "); \} \} void test\_16()\{ int i; char s\[ 40\]; for(i= 0;i< 10;i++)\{ int val=rand(); int d; if(val& 0x1) val=-val; itob(val,s, 16); sscanf(s, " %x ",&d); printf( " %\#14x %14s %\#14x ",val,s,d); if(val==d) printf( " OK\\n "); else printf( " NO\\n "); \} \} int main()\{ printf( " base-10\\n "); test\_10(); printf( " =========================\\n "); printf( " base-8\\n "); test\_8(); printf( " =========================\\n "); printf( " base-16\\n "); test\_16(); \} ![复制代码][copycode.gif] ![201208051119483402.png][] 我们在测试程序中进行8,10和16三种进制的测试。主要是C语言提供到这三种进制的转换,这样便于我们的测试。 测试结果如下: ![20120805111948338.png][] 函数trim:用于删除字符串尾部的空格、制表符与换行符。当发现最右边的字符为非空格符、非制表符、非换行符时,就使用break语句从循环中退出。 ![复制代码][copycode.gif] \#include <stdio.h> int trim( char s\[\])\{ int i; for(i=strlen(s)- 1;i>= 0;i--) if(s\[i\]!= ' '&&s\[i\]!= ' \\t '&&s\[i\]!= ' \\n ') break; s\[i+ 1\]= ' \\0 '; return i; \} ![复制代码][copycode.gif] 第4章 函数与程序结构 1. 实现类似UNIX系统上的grep类似的功能:strindex ![201208051119482497.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#define MAXLINE 1000 char pattern\[\]= " line "; int getline\_( char line\[\], int lim)\{ int i,c; i= 0; while(i<lim- 1&&((c=getchar())!=EOF)&&c!= ' \\n ') line\[i++\]=c; if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') line\[i++\]=c; line\[i\]= ' \\0 '; return i; \} int strindex( char src\[\], char itm\[\])\{ int i,j; // int len1=strlen(src); // int len2=strlen(itm); for(i= 0;src\[i\]!= ' \\0 ';i++)\{ int k; for(j= 0,k=i;itm\[j\]!= ' \\0 '&&itm\[j\]==src\[k\];j++,k++); if(itm\[j\]== ' \\0 ') return i; \} return - 1; \} int main()\{ char line\[MAXLINE\]; int found= 0; while(getline\_(line,MAXLINE)> 0) if(strindex(line,pattern)>= 0)\{ printf( " %s ",line); found++; \} \} ![复制代码][copycode.gif] 习题 4-1 编写函数strrindex(s,t),它返回字符串t在s中最右边出现的位置。如果s中不包含t,则返回-1 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int strrindex( char s\[\], char t\[\])\{ int i,j; int pos=- 1; for(i= 0;s\[i\]!= ' \\0 ';i++)\{ int k; for(j= 0,k=i;t\[j\]!= ' \\0 '&&t\[j\]==s\[k\];j++,k++); if(t\[j\]== ' \\0 ') pos=i; \} return pos; \} ![复制代码][copycode.gif] ![201208051119489432.png][] ![复制代码][copycode.gif] int strrindex2( char s\[\], char t\[\])\{ int i,j; int ls=strlen(s); int lt=strlen(t); for(i=ls-lt;i>= 0;i--)\{ int k; for(j= 0,k=i;t\[j\]!= ' \\0 '&&t\[j\]==s\[k\];j++,k++); if(t\[j\]== ' \\0 ') return i; \} return - 1; \} ![复制代码][copycode.gif] ![201208051119496368.png][] 函数atof:将字符串转换为浮点数 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <ctype.h> double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} int main()\{ int i; for(i= 0;i< 25;i++)\{ double val=rand()% 100000/ 100.0; char s\[ 20\]; double val2; sprintf(s, " %f ",val); val2=atof\_(s); printf( " %10.5f %12s %10.5f\\n ",val,s,val2); \} \} ![复制代码][copycode.gif] ![201208051119491351.png][] 习题4-2 对atof函数进行扩充,使他可以处理形如: 123.45e-6 的科学表示法,其中浮点数后面可能会紧跟一个e或E以及一个指数(可能有正负号)。 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} ![复制代码][copycode.gif] ![201208051119496335.png][] 4.3 外部变量 ![201208051119494350.png][] 一个简单的计算器程序 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#if 1 \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} \#define MAXOP 1000 \#define NUMBER '0' int getop( char s\[\])\{ int i,c; while((s\[ 0\]=c=getch())== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; if(!isdigit(c)&&c!= ' . ') return c; i= 0; if(isdigit(c)) while(isdigit(s\[++i\]=c=getch())) ; if(c== ' . ') while(isdigit(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); return NUMBER; \} int main()\{ int type; double op2; char s\[MAXOP\]; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) 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; \} \} \} ![复制代码][copycode.gif] ![201208051119501809.png][] ![201208051119503204.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include <math.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} \#define MAXOP 1000 \#define NUMBER '0' int getop( char s\[\])\{ int i,c; while((s\[ 0\]=c=getch())== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; if(!isdigit(c)&&c!= ' . '&&c!= ' \- ') return c; i= 0; if(c== ' \- ') if(isdigit(c=getch())||c== ' . ') s\[++i\]=c; else \{ if(c!=EOF) ungetch(c); return ' \- '; \} if(isdigit(c)) while(isdigit(s\[++i\]=c=getch())) ; if(c== ' . ') while(isdigit(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); return NUMBER; \} int main()\{ int type; double op2; char s\[MAXOP\]; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) push(pop()/op2); else printf( " error:zero divisor\\n "); break; case ' % ': op2=pop(); if(ABS(op2)>1e- 10) push(fmod(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; \} \} \} ![复制代码][copycode.gif] ![201208051119501776.png][] ![201208051119504807.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include <math.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} void clear( void)\{ sp= 0; \} \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} \#define MAXOP 1000 \#define NUMBER '0' int getop( char s\[\])\{ int i,c; while((s\[ 0\]=c=getch())== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; if(!isdigit(c)&&c!= ' . '&&c!= ' \- ') return c; i= 0; if(c== ' \- ') if(isdigit(c=getch())||c== ' . ') s\[++i\]=c; else \{ if(c!=EOF) ungetch(c); return ' \- '; \} if(isdigit(c)) while(isdigit(s\[++i\]=c=getch())) ; if(c== ' . ') while(isdigit(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); return NUMBER; \} int main()\{ int type; double op1,op2; char s\[MAXOP\]; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) push(pop()/op2); else printf( " error:zero divisor\\n "); break; case ' % ': op2=pop(); if(ABS(op2)>1e- 10) push(fmod(pop(),op2)); else printf( " error:zero divisor\\n "); break; case ' ? ': op2=pop(); printf( " \\t%.8g\\n ",op2); push(op2); break; case ' c ': clear(); break; case ' d ': op2=pop(); push(op2); push(op2); break; case ' s ': op1=pop(); op2=pop(); push(op1); push(op2); case ' \\n ': printf( " \\t%.8g\\n ",pop()); break; default: printf( " error: unknown command %s\\n ",s); break; \} \} \} ![复制代码][copycode.gif] ![201208051119507598.png][] ![201208051119502582.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include <math.h> \#include < string.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} void mathfnc( char s\[\])\{ double op2; if(strcmp(s, " sin ")== 0) push(sin(pop())); else if(strcmp(s, " cos ")== 0) push(cos(pop())); else if(strcmp(s, " exp ")== 0) push(exp(pop())); else if(strcmp(s, " pow ")== 0) \{ op2=pop(); push(pow(pop(),op2)); \} else printf( " error: %s not supported\\n ",s); \} \#define MAXOP 1000 \#define NUMBER '0' \#define NAME 'n' int getop( char s\[\])\{ int i,c; while((s\[ 0\]=c=getch())== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; i= 0; if(islower(c))\{ while(islower(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); if(strlen(s)> 1) return NAME; else return c; \} if(!isdigit(c)&&c!= ' . '&&c!= ' \- ') return c; if(c== ' \- ') if(isdigit(c=getch())||c== ' . ') s\[++i\]=c; else \{ if(c!=EOF) ungetch(c); return ' \- '; \} if(isdigit(c)) while(isdigit(s\[++i\]=c=getch())) ; if(c== ' . ') while(isdigit(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); return NUMBER; \} int main()\{ int type; double op1,op2; char s\[MAXOP\]; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case NAME: mathfnc(s); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) push(pop()/op2); else printf( " error:zero divisor\\n "); break; case ' % ': op2=pop(); if(ABS(op2)>1e- 10) push(fmod(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; \} \} \} ![复制代码][copycode.gif] ![201208051119517216.png][] ![201208051119518612.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include <math.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} \#define MAXOP 1000 \#define NUMBER '0' int getop( char s\[\])\{ int i,c; while((s\[ 0\]=c=getch())== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; if(!isdigit(c)&&c!= ' . '&&c!= ' \- ') return c; i= 0; if(c== ' \- ') if(isdigit(c=getch())||c== ' . ') s\[++i\]=c; else \{ if(c!=EOF) ungetch(c); return ' \- '; \} if(isdigit(c)) while(isdigit(s\[++i\]=c=getch())) ; if(c== ' . ') while(isdigit(s\[++i\]=c=getch())) ; s\[i\]= ' \\0 '; if(c!=EOF) ungetch(c); return NUMBER; \} int main()\{ int type,i, var= 0; double op2, v; char s\[MAXOP\]; double variable\[ 26\]; for(i= 0;i< 26;i++) variable\[i\]= 0.0; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) push(pop()/op2); else printf( " error:zero divisor\\n "); break; case ' % ': op2=pop(); if(ABS(op2)>1e- 10) push(fmod(pop(),op2)); else printf( " error:zero divisor\\n "); break; case ' \\n ': v=pop(); printf( " \\t%.8g\\n ",v); break; case ' = ': pop(); if( var>= ' A '&& var<= ' Z ') variable\[ var\- ' A '\]=pop(); else printf( " error: no variable name\\n "); break; default: if(type>= ' A '&&type<= ' Z ') push(variable\[type- ' A '\]); else if(type == ' v ') push(v); else printf( " error: unknown command %s\\n ",s); break; \} var=type; \} \} ![复制代码][copycode.gif] ![201208051119514675.png][] ![201208051119512483.png][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#define BUFSIZE 100 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} void ungets( char s\[\])\{ int len=strlen(s); while(len> 0) ungetch(s\[--len\]); \} ![复制代码][copycode.gif] ![201208051119523006.png][] ![201208051119526038.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] char buf= 0; int getch( void)\{ int c; if(buf!= 0) c=buf; else c=getchar(); buf= 0; return c; \} void ungetch( int c)\{ if(buf!= 0) printf( " ungetch:too many characters\\n "); else buf=c; \} ![复制代码][copycode.gif] ![201208051119529069.png][] ![201208051119536495.png][] ![201208051119537890.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include <math.h> \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} \#define MAXVAL 1000 int sp= 0; double val\[MAXVAL\]; void push( double f)\{ if(sp<MAXVAL) val\[sp++\]=f; else printf( " error:stack full\\n "); \} double pop( void)\{ if(sp> 0) return val\[--sp\]; else printf( " error:stack empty\\n "); return 0.0; \} // \#define BUFSIZE 100 // char buf\[BUFSIZE\]; // int bufp=0; // int getch(void)\{ // return bufp>0?buf\[--bufp\]:getchar(); // \} // void ungetch(int c)\{ // if(bufp>=BUFSIZE) // printf("ungetch: too many characters\\n"); // else // buf\[bufp++\]=c; // \} \#define MAXLINE 100 char line\[MAXLINE\]; int li= 0; int getline\_( char line\[\], int lim)\{ int i,c; i= 0; while(i<lim- 1&&((c=getchar())!=EOF)&&c!= ' \\n ') line\[i++\]=c; if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') line\[i++\]=c; line\[i\]= ' \\0 '; return i; \} \#define MAXOP 1000 \#define NUMBER '0' int getop( char s\[\])\{ int i,c; if(line\[li\]== ' \\0 ') if(getline\_(line,MAXLINE)==- 1) return EOF; else li= 0; while((s\[ 0\]=c=line\[li++\])== ' '||c== ' \\t ') ; s\[ 1\]= ' \\0 '; if(!isdigit(c)&&c!= ' . '&&c!= ' \- ') return c; i= 0; if(c== ' \- ') if(isdigit(c=line\[li++\])||c== ' . ') s\[++i\]=c; else \{ if(c!=EOF) li--; return ' \- '; \} if(isdigit(c)) while(isdigit(s\[++i\]=c=line\[li++\])) ; if(c== ' . ') while(isdigit(s\[++i\]=c=line\[li++\])) ; s\[i\]= ' \\0 '; li--; return NUMBER; \} int main()\{ int type; double op2; char s\[MAXOP\]; while((type=getop(s))!=EOF)\{ switch(type)\{ case NUMBER: push(atof\_(s)); break; case ' \+ ': push(pop()+pop()); break; case ' \- ': op2=pop(); push(pop()-op2); break; case ' \* ': push(pop()\*pop()); break; case ' / ': op2=pop(); if(ABS(op2)>1e- 10) push(pop()/op2); else printf( " error:zero divisor\\n "); break; case ' % ': op2=pop(); if(ABS(op2)>1e- 10) push(fmod(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; \} \} \} ![复制代码][copycode.gif] ![201208051119532841.png][] 快速排序 ![201208051119539776.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> // \#include <stdlib.h> void swap( int \*x, int \*y)\{ int temp=\*x; \*x=\*y; \*y=temp; \} void qsort( int v\[\], int left, int right)\{ int i,last; if(left>=right) return; swap(v+left,v+(left+right)/ 2); last=left; for(i=left+ 1;i<=right;i++) if(v\[i\]<v\[left\]) \{ last++; swap(v+last,v+i); \} swap(v+left,v+last); qsort(v,left,last- 1); qsort(v,last+ 1,right); \} void Qsort( int v\[\], int n)\{ qsort(v, 0,n- 1); \} void print\_arr( int v\[\], int n)\{ int i; for(i= 0;i<n;i++) printf( " %4d ",v\[i\]); printf( " \\n "); \} int main()\{ int i; for(i= 0;i< 10;i++)\{ int arr\[ 20\],j,b\[ 20\]; for(j= 0;j< 20;j++) \{ int val=rand()% 1000; arr\[j\]=val; b\[j\]=val; \} printf( " before: "); print\_arr(b, 20); Qsort(arr, 20); printf( " after : "); print\_arr(arr, 20); \} \} ![复制代码][copycode.gif] 测试结果如下: ![201208051119541379.png][] swap宏 ![201208051119549395.png][] 第5章 指针与数组 ![20120805111954790.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int strend( char \*s, char\*t)\{ char \*bs=s; char \*bt=t; while(\*s++); while(\*t++); while(\*--s==\*--t)\{ if(t==bt||s==st) break; \} if(\*s==\*t&&t==bt&&\*s!= ' \\0 ') return 1; else return 0; \} ![复制代码][copycode.gif] ![201208051119541837.png][] ![201208051119556264.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] void strncpy( char\* s, char \*t, int n)\{ while(\*t&&n--> 0) \*s++=\*t++; while(n--> 0) \*s++= ' \\0 '; \} void strncat( char \*s, char \*t, int n)\{ strncpy(s+strlen(s),t,n); \} int strncmp( char\* s, char\* t, int n)\{ for(;\*s==\*t;s++,t++) if(\*s== ' \\0 '||--n<= 0) return 0; return \*s-\*t; \} ![复制代码][copycode.gif] UNIX系统中sort程序的一个简单版本,实现对输入文本的排序。 ![201208051119552643.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <stdlib.h> \#define MAXLINES 5000 char \*lineptr\[MAXLINES\]; \#define MAXLEN 1000 int getline\_( char line\[\], int lim)\{ int i,c; i= 0; while(i<lim- 1&&((c=getchar())!=EOF)&&c!= ' \\n ') line\[i++\]=c; if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') line\[i++\]=c; line\[i\]= ' \\0 '; return i; \} char\* alloc( int len)\{ char \*p=( char\*)malloc(len\* sizeof( char)); return p; \} int readlines( char\* lineptr\[\], int maxlines)\{ int len,nlines; char \*p,line\[MAXLEN\]; nlines= 0; while((len=getline\_(line,MAXLEN))> 0) if(nlines>=maxlines||(p=alloc(len))==NULL) return - 1; else\{ line\[len- 1\]= ' \\0 '; strcpy(p,line); lineptr\[nlines++\]=p; \} return nlines; \} void writelines( char \*lineptr\[\], int nlines)\{ int i; for(i= 0;i<nlines;i++) printf( " %s\\n ",lineptr\[i\]); \} void swap( char \*\*x, char \*\*y)\{ char\*tmp; tmp=\*x; \*x=\*y; \*y=tmp; \} void qsort\_( char \*v\[\], int left, int right)\{ int i,last; if(left>=right) return ; swap(v+left,v+(left+right)/ 2); last=left; for(i=left+ 1;i<=right;i++) if(strcmp(v\[i\],v\[left\])< 0) \{ last++; swap(v+last,v+i); \} swap(v+left,v+last); qsort\_(v,left,last- 1); qsort\_(v,last+ 1,right); \} int main()\{ int nlines; int i; if((nlines=readlines(lineptr,MAXLINES))> 0)\{ qsort\_(lineptr, 0,nlines- 1); writelines(lineptr,nlines); for(i= 0;i<nlines;i++) free(lineptr\[i\]); return 0; \} else\{ printf( " error: input too big to sort\\n "); return 1; \} \} ![复制代码][copycode.gif] 根据日期计算是一年的第几天: ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] static int daytab\[\]\[ 13\]=\{ \{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31\} ,\{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31\}\}; int day\_of\_year( int year, int month, int day)\{ int i,leap; leap=year% 4== 0&&year% 100!= 0||year% 400== 0; if(month< 1||month> 12) return - 1; if(day< 1||day>daytab\[leap\]\[month\]) return - 1; for(i= 1;i<month;i++) day+=daytab\[leap\]\[i\]; return day; \} void month\_day( int year, int yearday, int \*pmonth, int \*pday)\{ int i,leap; if(year< 1)\{ \*pmonth=- 1; \*pday=- 1; return ; \} leap=year% 4== 0&&year% 100!= 0||year% 400== 0; for(i= 1;i<= 12&&yearday>daytab\[leap\]\[i\];i++) yearday-=daytab\[leap\]\[i\]; if(i> 12&&yearday>daytab\[leap\]\[ 12\])\{ \*pmonth=- 1; \*pday=- 1; \} else\{ \*pmonth=i; \*pday=yearday; \} \} ![复制代码][copycode.gif] 习题5-13 ![201208051119556754.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include < string.h> \#define DEFLINES 10 \#define MAXLINES 10 \#define MAXLEN 100 int getline\_( char line\[\], int lim)\{ int i,c; i= 0; while(i<lim- 1&&((c=getchar())!=EOF)&&c!= ' \\n ') line\[i++\]=c; if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') line\[i++\]=c; line\[i\]= ' \\0 '; return i; \} void error( char \*s)\{ printf( " %s\\n ",s); exit( 1); \} int main( int argc, char\* argv\[\])\{ char \*p,\*buf,\*bufend; char line\[MAXLEN\]; char \*lineptr\[MAXLINES\]; int first,i,last,len,n,nlines; if(argc== 1) n=DEFLINES; else if(argc== 2&&(\*++argv)\[ 0\]== ' \- ') n=atoi(argv\[ 0\]+ 1); if(n< 1||n>MAXLINES) n=MAXLINES; for(i= 0;i<MAXLINES;i++) lineptr\[i\]=NULL; if((p=buf=malloc(MAXLINES\*MAXLEN))==NULL) error( " tail:cannot allocate buf "); bufend=buf+MAXLINES\*MAXLEN; last= 0; nlines= 0; while((len=getline\_(line,MAXLEN))> 0)\{ if(p+len+ 1>=bufend) p=buf; lineptr\[last\]=p; strcpy(lineptr\[last\],line); if(++last>=MAXLINES) last= 0; p+=len+ 1; nlines++; \} if(n>nlines) n=nlines; first=last-n; if(first< 0) first+=MAXLINES; for(i=first;n--> 0;i=(i+ 1)%MAXLINES) printf( " %s ",lineptr\[i\]); free(buf); return 0; \} ![复制代码][copycode.gif] ![201208051119568117.png][] ![201208051119564180.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <stdlib.h> \#include <ctype.h> \#define NUMERIC 1 \#define DECR 2 \#define FOLD 4 \#define DIR 8 // \#define LINES 100 \#define MAXLINES 100 \#define MAXLEN 1000 char option= 0; int pos1= 0; int pos2= 0; int getline\_( char line\[\], int lim)\{ int i,c; i= 0; while(i<lim- 1&&((c=getchar())!=EOF)&&c!= ' \\n ') line\[i++\]=c; if(c==EOF&&i== 0) return - 1; if(c== ' \\n ') line\[i++\]=c; line\[i\]= ' \\0 '; return i; \} void error( char \*s)\{ printf( " %s\\n ",s); exit( 1); \} char\* alloc( int len)\{ char \*p=( char\*)malloc(len\* sizeof( char)); return p; \} int readlines( char\* lineptr\[\], int maxlines)\{ int len,nlines; char \*p,line\[MAXLEN\]; nlines= 0; while((len=getline\_(line,MAXLEN))> 0) if(nlines>=maxlines||(p=alloc(len))==NULL) return - 1; else\{ line\[len- 1\]= ' \\0 '; strcpy(p,line); lineptr\[nlines++\]=p; \} return nlines; \} void writelines( char \*lineptr\[\], int nlines, int decr)\{ int i; if(decr) for(i=nlines- 1;i>= 0;i--) printf( " %s\\n ",lineptr\[i\]); else for(i= 0;i<nlines;i++) printf( " %s\\n ",lineptr\[i\]); \} void swap( void\*\*x, void\*\*y)\{ void\*tmp; tmp=\*x; \*x=\*y; \*y=tmp; \} void qsort\_( void\*v\[\], int left, int right, int(\*comp)( void\*, void\*))\{ int i,last; if(left>=right) return ; swap(v+left,v+(left+right)/ 2); last=left; for(i=left+ 1;i<=right;i++) if(strcmp(v\[i\],v\[left\])< 0) \{ last++; swap(v+last,v+i); \} swap(v+left,v+last); qsort\_(v,left,last- 1,comp); qsort\_(v,last+ 1,right,comp); \} void readargs( int argc, char\*argv\[\])\{ int c; while(--argc> 0&&(c=(\*++argv)\[ 0\])== ' \- '||c== ' \+ ')\{ if(c== ' \- '&&!isdigit(\*(argv\[ 0\]+ 1))) while(c=\*++argv\[ 0\]) switch(c)\{ case ' d ': option|=DIR; break; case ' f ': option|=FOLD; break; case ' n ': option|=NUMERIC; break; case ' r ': option|=DECR; break; default: printf( " sort: illegal option %c\\n ",c); error( " usage: sort -dfnr \[+pos1\] \[-pos2\] "); break; \} else if(c== ' \- ') pos2=atoi(argv\[ 0\]+ 1); else if((pos1=atoi(argv\[ 0\]+ 1))< 0) error( " usage: sort -dfnr \[+pos1\] \[-pos2\] "); \} if(argc||pos1>pos2) error( " usage: sort -dfnr \[+pos1\] \[-pos2\] "); \} \#define MAXSTR 100 void substr( char \*s, char \*str)\{ int i,j,len; len=strlen(s); if(pos2> 0&&len>pos2) len=pos2; else if(pos2> 0&&len<pos2) error( " substr:string too short "); for(j= 0,i=pos1;i<len;i++,j++) str\[j\]=s\[i\]; str\[j\]= ' \\0 '; \} \#define ABS(x) ((x)<0?-(x):(x)) double atof\_( char s\[\])\{ double val,power; int i,sign; 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; \} val= sign\*val/power; if(s\[i\]== ' e '||s\[i\]== ' E ')\{ int exp; sign=(s\[++i\]== ' \- ')?- 1: 1; if(s\[i\]== ' \+ '||s\[i\]== ' \- ') i++; for(exp= 0;isdigit(s\[i\]);i++) exp= 10\*exp+(s\[i\]- ' 0 '); if(sign) while(exp--> 0) val\*= 10; else while(exp--> 0) val/= 10; \} return val; \} int numcmp( char \*s1, char \*s2)\{ double v1,v2; char str\[MAXSTR\]; substr(s1,str); v1=atof\_(str); substr(s2,str); v2=atof\_(str); if(v1<v2) return - 1; else if(v1>v2) return 1; else return 0; \} // \#define FOLD 4 // \#define DIR 8 int charcmp( char \*s, char \*t)\{ char a,b; int i,j,endpos; int fold=(option&FOLD)? 1: 0; int dir=(option&DIR)? 1: 0; i=j=pos1; if(pos2> 0) endpos=pos2; else if((endpos-strlen(s))>strlen(t)) endpos=strlen(t); do\{ if(dir)\{ while(i<endpos&&!isalnum(s\[i\])&& s\[i\]!= ' '&&s\[i\]!= ' \\0 ') i++; while(j<endpos&&!isalnum(t\[j\])&& t\[j\]!= ' '&&t\[j\]!= ' \\0 ') j++; \} if(i<endpos&&j<endpos)\{ a=fold?tolower(s\[i\]):s\[i\]; i++; b=fold?tolower(t\[j\]):t\[j\]; j++; if(a==b&&a== ' \\0 ') return 0; \} \} while(a==b&&i<endpos&&j<endpos); return a-b; \} int main( int argc, char\*argv\[\])\{ char \*lineptr\[MAXLINES\]; int nlines; int i; readargs(argc,argv); if((nlines=readlines(lineptr,MAXLINES))> 0)\{ if(option&NUMERIC) qsort\_(( void\*\*)lineptr, 0,nlines- 1, ( int(\*)( void\*, void\*))numcmp); else qsort\_(( void\*\*)lineptr, 0,nlines- 1, ( int(\*)( void\*, void\*))charcmp); writelines(lineptr,nlines,option&DECR); for(i= 0;i<nlines;i++) free(lineptr\[i\]); return 0; \} else\{ printf( " error: input too big to sort\\n "); return 1; \} \} ![复制代码][copycode.gif] ![201208051119568051.png][] dcl一个比较不错的程序:将声明转化为文字描述或将文字描述转化为声明 ![201208051119571921.png][] ![201208051119577985.png][] ![201208051119579031.png][] ![201208051119585967.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <ctype.h> \#define MAXTOKEN 100 enum\{NAME,PARENS,BRACKETS\}; int tokentype; char token\[MAXTOKEN\]; char name\[MAXTOKEN\]; char datatype\[MAXTOKEN\]; char out\[ 1000\]; \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} int gettoken()\{ char \*p=token; int c; while((c=getch())== ' '||c== ' \\t ') ; if(c== ' ( ')\{ if((c=getch())== ' ) ')\{ strcpy(token, " () "); return tokentype=PARENS; \} else\{ ungetch(c); return tokentype= ' ( '; \} \} else if(c== ' \[ ')\{ for(\*p++=c;(\*p++=getch())!= ' \] ';) ; \*p= ' \\0 '; return tokentype=BRACKETS; \} else if(isalpha(c))\{ for(\*p++=c;isalnum(c=getch());) \*p++=c; \*p= ' \\0 '; ungetch(c); return tokentype=NAME; \} else return tokentype=c; \} void dcl( void); void dirdcl( void)\{ int type; if(tokentype== ' ( ')\{ dcl(); if(tokentype!= ' ) ') printf( " error:missing )\\n "); \} else if(tokentype==NAME) strcpy(name,token); else printf( " error:expected name or (dcl)\\n "); while((type=gettoken())==PARENS||type==BRACKETS) if(type==PARENS) strcat( out, " function returning "); else\{ strcat( out, " array "); strcat( out,token); strcat( out, " of "); \} \} void dcl( void)\{ int ns; for(ns= 0;gettoken()== ' \* ';) ns++; dirdcl(); while(ns--> 0) strcat( out, " pointer to "); \} int main()\{ while(gettoken()!=EOF)\{ strcpy(datatype,token); out\[ 0\]= ' \\0 '; dcl(); if(tokentype!= ' \\n ') printf( " syntax error\\n "); printf( " %s: %s %s\\n ",name, out,datatype); \} return 0; \} ![复制代码][copycode.gif] ![201208051119581822.png][] ![201208051119581474.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int main()\{ int type; char temp\[MAXTOKEN\]; while(gettoken()!=EOF)\{ strcpy( out,token); while((type=gettoken())!= ' \\n ') if(type==PARENS||type==BRACKETS) strcat( out,token); else if(type== ' \* ')\{ sprintf(temp, " (\*%s) ", out); strcpy( out,temp); \} else if(type==NAME)\{ sprintf(temp, " %s %s ",token, out); strcpy( out,temp); \} else \{ printf( " invalid input at %s\\n ",token); \} \} printf( " %s\\n ", out); return 0; \} ![复制代码][copycode.gif] ![201208051119587329.png][] ![20120805111958361.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <ctype.h> \#define MAXTOKEN 100 enum\{NAME,PARENS,BRACKETS\}; enum\{NO,YES\}; int tokentype; char token\[MAXTOKEN\]; char name\[MAXTOKEN\]; char datatype\[MAXTOKEN\]; char out\[ 1000\]; int prevtoken=NO; \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} void errmsg( char \*msg)\{ printf( " %s ",msg); prevtoken=YES; \} int gettoken()\{ char \*p=token; int c; if(prevtoken==YES)\{ prevtoken=NO; return tokentype; \} while((c=getch())== ' '||c== ' \\t ') ; if(c== ' ( ')\{ if((c=getch())== ' ) ')\{ strcpy(token, " () "); return tokentype=PARENS; \} else\{ ungetch(c); return tokentype= ' ( '; \} \} else if(c== ' \[ ')\{ for(\*p++=c;(\*p++=getch())!= ' \] ';) ; \*p= ' \\0 '; return tokentype=BRACKETS; \} else if(isalpha(c))\{ for(\*p++=c;isalnum(c=getch());) \*p++=c; \*p= ' \\0 '; ungetch(c); return tokentype=NAME; \} else return tokentype=c; \} void dcl( void); void dirdcl( void)\{ int type; if(tokentype== ' ( ')\{ dcl(); if(tokentype!= ' ) ') printf( " error:missing )\\n "); \} else if(tokentype==NAME) strcpy(name,token); else errmsg( " error:expected name or (dcl)\\n "); while((type=gettoken())==PARENS||type==BRACKETS) if(type==PARENS) strcat( out, " function returning "); else\{ strcat( out, " array "); strcat( out,token); strcat( out, " of "); \} \} void dcl( void)\{ int ns; for(ns= 0;gettoken()== ' \* ';) ns++; dirdcl(); while(ns--> 0) strcat( out, " pointer to "); \} int main()\{ while(gettoken()!=EOF)\{ strcpy(datatype,token); out\[ 0\]= ' \\0 '; dcl(); if(tokentype!= ' \\n ') printf( " syntax error\\n "); printf( " %s: %s %s\\n ",name, out,datatype); \} return 0; \} ![复制代码][copycode.gif] ![201208051119584788.png][] ![201208051119593359.png][] ![201208051119598343.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] int nexttoken()\{ int type; type=gettoken(); prevtoken=YES; return type; \} int main()\{ int type; char temp\[MAXTOKEN\]; while(gettoken()!=EOF)\{ strcpy( out,token); while((type=gettoken())!= ' \\n ') if(type==PARENS||type==BRACKETS) strcat( out,token); else if(type== ' \* ')\{ if((type=nexttoken())==PARENS|| type==BRACKETS) sprintf(temp, " (\*%s) ", out); else sprintf(temp, " \*%s ", out); strcpy( out,temp); \} else if(type==NAME)\{ sprintf(temp, " %s %s ",token, out); strcpy( out,temp); \} else \{ printf( " invalid input at %s\\n ",token); \} \} printf( " %s\\n ", out); return 0; \} ![复制代码][copycode.gif] ![201208051119597197.png][] ![201208051120002147.png][] ![201208051120005179.png][] ![201208051120001242.png][] ![201208051120002605.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <ctype.h> \#define MAXTOKEN 100 enum\{NAME,PARENS,BRACKETS\}; enum\{NO,YES\}; int tokentype; char token\[MAXTOKEN\]; char name\[MAXTOKEN\]; char datatype\[MAXTOKEN\]; char out\[ 1000\]; int prevtoken=NO; \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} void errmsg( char \*msg)\{ printf( " %s ",msg); prevtoken=YES; \} int gettoken()\{ char \*p=token; int c; if(prevtoken==YES)\{ prevtoken=NO; return tokentype; \} while((c=getch())== ' '||c== ' \\t ') ; if(c== ' ( ')\{ if((c=getch())== ' ) ')\{ strcpy(token, " () "); return tokentype=PARENS; \} else\{ ungetch(c); return tokentype= ' ( '; \} \} else if(c== ' \[ ')\{ for(\*p++=c;(\*p++=getch())!= ' \] ';) ; \*p= ' \\0 '; return tokentype=BRACKETS; \} else if(isalpha(c))\{ for(\*p++=c;isalnum(c=getch());) \*p++=c; \*p= ' \\0 '; ungetch(c); return tokentype=NAME; \} else return tokentype=c; \} int compare( char \*\*s, char \*\*t)\{ return strcmp(\*s,\*t); \} int typespec( void)\{ static char \*types\[\]=\{ " char ", " int ", " void " \}; char \*pt=token; if(bsearch(&pt,types, sizeof(types)/ sizeof( char\*), sizeof( char\*),compare)==NULL) return NO; else return YES; \} int typequal( void)\{ static char \*typeq\[\]=\{ " const ", " volatile " \}; char \*pt=token; if(bsearch(&pt,typeq, sizeof(typeq)/ sizeof( char\*), sizeof( char\*),compare)==NULL) return NO; else return YES; \} void dcl( void); void dclspec( void)\{ char temp\[MAXTOKEN\]; temp\[ 0\]= ' \\0 '; gettoken(); do\{ if(tokentype!=NAME)\{ prevtoken=YES; dcl(); \} else if(typespec()==YES)\{ strcat(temp, " "); strcat(temp,token); gettoken(); \} else if(typequal()==YES)\{ strcat(temp, " "); strcat(temp,token); gettoken(); \} else errmsg( " unknown type in parameter list\\n "); \} while(tokentype!= ' , '&&tokentype!= ' ) '); strcat( out,temp); if(tokentype== ' , ') strcat( out, " , "); \} void parmdcl( void)\{ do\{ dclspec(); \} while(tokentype== ' , '); if(tokentype!= ' ) ') errmsg( " missing ) in parameter declaration\\n "); \} void dirdcl( void)\{ int type; if(tokentype== ' ( ')\{ dcl(); if(tokentype!= ' ) ') printf( " error:missing )\\n "); \} else if(tokentype==NAME) \{ if(name\[ 0\]== ' \\0 ') strcpy(name,token); \} else prevtoken=YES; while((type=gettoken())==PARENS||type==BRACKETS||type== ' ( ') if(type==PARENS) strcat( out, " function returning "); else if(type== ' ( ')\{ strcat( out, " function expecting "); parmdcl(); strcat( out, " and returning "); \} else\{ strcat( out, " array "); strcat( out,token); strcat( out, " of "); \} \} void dcl( void)\{ int ns; for(ns= 0;gettoken()== ' \* ';) ns++; dirdcl(); while(ns--> 0) strcat( out, " pointer to "); \} int main()\{ while(gettoken()!=EOF)\{ strcpy(datatype,token); out\[ 0\]= ' \\0 '; dcl(); if(tokentype!= ' \\n ') printf( " syntax error\\n "); printf( " %s: %s %s\\n ",name, out,datatype); \} return 0; \} ![复制代码][copycode.gif] ![201208051120019540.png][] 这个网站很不错的:[http://cdecl.org/][http_cdecl.org] 第6章 结构体 统计关键字出现的次数 ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include <ctype.h> \#include < string.h> \#define MAXWORD 1000 struct key \{ char \*word; int count; \} keytab\[\]=\{ " auto ", 0, " break ", 0, " case ", 0, " char ", 0, " const ", 0, " continue ", 0, " default ", 0, " do ", 0, " double ", 0, " else ", 0, " enum ", 0, " extern ", 0, " float ", 0, " for ", 0, " goto ", 0, " if ", 0, " int ", 0, " long ", 0, " register ", 0, " return ", 0, " short ", 0, " signed ", 0, " sizeof ", 0, " static ", 0, " struct ", 0, " switch ", 0, " typedef ", 0, " union ", 0, " unsigned ", 0, " void ", 0, " volatile ", 0, " while ", 0, \}; \#define NKEYS (sizeof keytab/sizeof(keytab\[0\])) \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} int binsearch( char \*word, struct key tab\[\], int n)\{ int cond; int low,high,mid; low= 0; high=n- 1; while(low<=high)\{ mid=(low+high)/ 2; if((cond=strcmp(word,tab\[mid\].word))< 0) high=mid- 1; else if(cond> 0) low=mid+ 1; else return mid; \} return - 1; \} int comment( void)\{ int c; while((c=getch())!=EOF) if(c== ' \* ') if((c=getch())== ' / ') break; else ungetch(c); return c; \} int getword( char \*word, int lim)\{ char \*w=word; int c,d; while(isspace(c=getch())) ; if(c!=EOF) \*w++=c; if(isalpha(c)||c== ' \- '||c== ' \# ')\{ for(;--lim> 0;w++) if(!isalnum(\*w=getch())&&\*w!= ' \- ')\{ ungetch(\*w); break; \} \} else if(c== ' \\' '||c== ' " ')\{ for(;--lim> 0;w++) if((\*w=getch())== ' \\\\ ') \*++w=getch(); else if(\*w==c)\{ w++; break; \} else if(\*w==EOF) break; \} else if(c== ' / ') if((d=getch())== ' \* ') c=comment(); else ungetch(d); \*w= ' \\0 '; return c; \} int main()\{ int n; char word\[MAXWORD\]; while(getword(word,MAXWORD)!=EOF) if(isalpha(word\[ 0\])) if((n=binsearch(word,keytab,NKEYS))>= 0) keytab\[n\].count++; for(n= 0;n<NKEYS;n++) if(keytab\[n\].count> 0) printf( " %4d %s\\n ", keytab\[n\].count,keytab\[n\].word); return 0; \} ![复制代码][copycode.gif] ![201208051120015603.png][] ![201208051120016999.png][] ![201208051120011982.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <ctype.h> \#include < string.h> \#include <stdlib.h> \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} int comment( void)\{ int c; while((c=getch())!=EOF) if(c== ' \* ') if((c=getch())== ' / ') break; else ungetch(c); return c; \} int getword( char \*word, int lim)\{ char \*w=word; int c,d; while(isspace(c=getch())) ; if(c!=EOF) \*w++=c; if(isalpha(c)||c== ' \- '||c== ' \# ')\{ for(;--lim> 0;w++) if(!isalnum(\*w=getch())&&\*w!= ' \- ')\{ ungetch(\*w); break; \} \} else if(c== ' \\' '||c== ' " ')\{ for(;--lim> 0;w++) if((\*w=getch())== ' \\\\ ') \*++w=getch(); else if(\*w==c)\{ w++; break; \} else if(\*w==EOF) break; \} else if(c== ' / ') if((d=getch())== ' \* ') c=comment(); else ungetch(d); \*w= ' \\0 '; return c; \} struct tnode\{ char \*word; int match; struct tnode \*left; struct tnode \*right; \}; \#define MAXWORD 100 \#define YES 1 \#define NO 0 int compare( char \*s, struct tnode \*p, int num, int \*found)\{ int i; char \*t=p->word; for(i= 0;\*s==\*t;i++,s++,t++) if(\*s== ' \\0 ') return 0; if(i>=num)\{ \*found=YES; p->match=YES; \} return \*s-\*t; \} struct tnode\* talloc( void)\{ return ( struct tnode\*)malloc( sizeof( struct tnode)); \} char \*strdup\_( char \*s)\{ char \*p; p=( char\*)malloc(strlen(s)+ 1); if(p!=NULL) strcpy(p,s); return p; \} struct tnode\* addtreex( struct tnode\*p, char \*w, int num, int \*found)\{ int cond; if(p==NULL)\{ p=talloc(); p->word=strdup\_(w); p->match=\*found; p->left=p->right=NULL; \} else if((cond=compare(w,p,num,found))< 0) p->left=addtreex(p->left,w,num,found); else if(cond> 0) p->right=addtreex(p->right,w,num,found); return p; \} void treeprint( struct tnode\* p)\{ if(p!=NULL)\{ treeprint(p->left); if(p->match) printf( " %s\]n ",p->word); treeprint(p->right); \} \} void freetree( struct tnode\*p)\{ if(p!=NULL)\{ freetree(p->left); freetree(p->right); free(p->word); \} \} int main( int argc, char \*argv\[\])\{ struct tnode \*root; char word\[MAXWORD\]; int found=NO; int num; num=(--argc&&(\*++argv)\[ 0\]== ' \- ')?atoi(argv\[ 0\]+ 1): 6; root=NULL; while(getword(word,MAXWORD)!=EOF)\{ if(isalpha(word\[ 0\])&&strlen(word)>=num) root=addtreex(root,word,num,&found); found=NO; \} treeprint(root); freetree(root); return 0; \} ![复制代码][copycode.gif] ![201208051120029441.png][] ![201208051120024425.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <ctype.h> \#include < string.h> \#include <stdlib.h> \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} int comment( void)\{ int c; while((c=getch())!=EOF) if(c== ' \* ') if((c=getch())== ' / ') break; else ungetch(c); return c; \} int getword( char \*word, int lim)\{ char \*w=word; int c,d; while(isspace(c=getch())) ; if(c!=EOF) \*w++=c; if(isalpha(c)||c== ' \- '||c== ' \# ')\{ for(;--lim> 0;w++) if(!isalnum(\*w=getch())&&\*w!= ' \- ')\{ ungetch(\*w); break; \} \} else if(c== ' \\' '||c== ' " ')\{ for(;--lim> 0;w++) if((\*w=getch())== ' \\\\ ') \*++w=getch(); else if(\*w==c)\{ w++; break; \} else if(\*w==EOF) break; \} else if(c== ' / ') if((d=getch())== ' \* ') c=comment(); else ungetch(d); \*w= ' \\0 '; return c; \} struct linklist\{ int lnum; struct linklist \*ptr; \}; struct tnode\{ char \*word; struct linklist \*lines; struct tnode \*left; struct tnode \*right; \}; \#define MAXWORD 100 \#define YES 1 \#define NO 0 struct tnode\* talloc( void)\{ return ( struct tnode\*)malloc( sizeof( struct tnode)); \} struct linklist \*lalloc( void)\{ return ( struct linklist\*)malloc( sizeof( struct linklist)); \} char \*strdup\_( char \*s)\{ char \*p; p=( char\*)malloc(strlen(s)+ 1); if(p!=NULL) strcpy(p,s); return p; \} void addln( struct tnode \*p, int linenum)\{ struct linklist \*temp; temp=p->lines; while(temp->ptr!=NULL&&temp->lnum!=linenum) temp=temp->ptr; if(temp->lnum==linenum)\{ temp->ptr=lalloc(); temp->ptr->lnum=linenum; temp->ptr->ptr=NULL; \} \} struct tnode\* addtreex( struct tnode\*p, char \*w, int linenum)\{ int cond; if(p==NULL)\{ p=talloc(); p->word=strdup\_(w); p->lines=lalloc(); p->lines->lnum=linenum; p->lines->ptr=NULL; p->left=p->right=NULL; \} else if((cond=strcmp(w,p->word))< 0) p->left=addtreex(p->left,w,linenum); else if(cond> 0) p->right=addtreex(p->right,w,linenum); else addln(p,linenum); return p; \} void treeprint( struct tnode\* p)\{ struct linklist \*temp; if(p!=NULL)\{ treeprint(p->left); printf( " %10s: ",p->word); for(temp=p->lines;temp!=NULL;temp=temp->ptr) printf( " %4d ",temp->lnum); printf( " \\n "); treeprint(p->right); \} \} void freetree( struct tnode\*p)\{ if(p!=NULL)\{ freetree(p->left); freetree(p->right); free(p->word); free(p->lines); \} \} int noiseword( char \*w)\{ static char \*nw\[\]=\{ " a ", " an ", " and ", " are ", " in ", " is ", " of ", " or ", " that ", " the ", " this ", " to " \}; int cond,mid; int low= 0; int high= sizeof(nw)/ sizeof( char\*)- 1; while(low<=high)\{ mid=(low+high)/ 2; if((cond=strcmp(w,nw\[mid\]))< 0) high=mid- 1; else if(cond> 0) low=mid+ 1; else return mid; \} return - 1; \} int main( int argc, char \*argv\[\])\{ struct tnode \*root; char word\[MAXWORD\]; int linenum= 1; root=NULL; while(getword(word,MAXWORD)!=EOF)\{ if(isalpha(word\[ 0\])&&noiseword(word)==- 1) root=addtreex(root,word,linenum); else if(word\[ 0\]== ' \\n ') linenum++; \} treeprint(root); freetree(root); return 0; \} ![复制代码][copycode.gif] ![201208051120021883.png][] 表查找程序核心代码: ![201208051120033802.png][] ![201208051120032374.png][] ![20120805112003945.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <stdlib.h> struct nlist\{ struct nlist \*next; char \*name; char \*defn; \}; \#define HASHSIZE 101 static struct nlist \*hashtab\[HASHSIZE\]; unsigned hash( char \*s) \{ unsigned hashval; for(hashval= 0;\*s!= ' \\0 ';s++) hashval=\*s+ 32\*hashval; return hashval%HASHSIZE; \} struct nlist \*lookup( char \*s)\{ struct nlist \*np; for(np=hashtab\[hash(s)\];np!=NULL;np=np->next) if(strcmp(s,np->name)== 0) return np; return NULL; \} struct nlist \*install( char \*name, char\*defn)\{ struct nlist \*np; unsigned hashval; if((np=lookup(name))==NULL)\{ np=( struct nlist \*)malloc( sizeof( struct nlist)); if(np==NULL||(np->name=strdup(name))==NULL) return NULL; hashval=hash(name); np->next=hashtab\[hashval\]; hashtab\[hashval\]=np; \} else free(( void\*)np->defn); if((np->defn=strdup(defn))==NULL) return NULL; return np; \} void undef( char\*s)\{ int h; struct nlist \*prev,\*np; prev=NULL; h=hash(s); for(np=hashtab\[h\];np!=NULL;np=np->next)\{ if(strcmp(s,np->name)== 0) break; prev=np; \} if(np!=NULL)\{ if(prev==NULL) hashtab\[h\]=np->next; else prev->next=np->next; free(np->name); free(np->defn); free(np); \} \} ![复制代码][copycode.gif] ![201208051120032341.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <stdlib.h> \#include <ctype.h> \#define BUFSIZE 10 char buf\[BUFSIZE\]; int bufp= 0; int getch( void)\{ return bufp> 0?buf\[--bufp\]:getchar(); \} void ungetch( int c)\{ if(bufp>=BUFSIZE) printf( " ungetch: too many characters\\n "); else buf\[bufp++\]=c; \} void ungets( char \*s)\{ int len=strlen(s); while(len> 0) ungetch(s\[--len\]); \} char \*strdup\_( char \*s)\{ char \*p; p=( char\*)malloc(strlen(s)+ 1); if(p!=NULL) strcpy(p,s); return p; \} int comment( void)\{ int c; while((c=getch())!=EOF) if(c== ' \* ') if((c=getch())== ' / ') break; else ungetch(c); return c; \} int getword( char \*word, int lim)\{ char \*w=word; int c,d; while(isspace(c=getch())) ; if(c!=EOF) \*w++=c; if(isalpha(c)||c== ' \- '||c== ' \# ')\{ for(;--lim> 0;w++) if(!isalnum(\*w=getch())&&\*w!= ' \- ')\{ ungetch(\*w); break; \} \} else if(c== ' \\' '||c== ' " ')\{ for(;--lim> 0;w++) if((\*w=getch())== ' \\\\ ') \*++w=getch(); else if(\*w==c)\{ w++; break; \} else if(\*w==EOF) break; \} else if(c== ' / ') if((d=getch())== ' \* ') c=comment(); else ungetch(d); \*w= ' \\0 '; return c; \} struct nlist\{ struct nlist \*next; char \*name; char \*defn; \}; \#define HASHSIZE 101 static struct nlist \*hashtab\[HASHSIZE\]; unsigned hash( char \*s) \{ unsigned hashval; for(hashval= 0;\*s!= ' \\0 ';s++) hashval=\*s+ 32\*hashval; return hashval%HASHSIZE; \} struct nlist \*lookup( char \*s)\{ struct nlist \*np; for(np=hashtab\[hash(s)\];np!=NULL;np=np->next) if(strcmp(s,np->name)== 0) return np; return NULL; \} struct nlist \*install( char \*name, char\*defn)\{ struct nlist \*np; unsigned hashval; if((np=lookup(name))==NULL)\{ np=( struct nlist \*)malloc( sizeof( struct nlist)); if(np==NULL||(np->name=strdup\_(name))==NULL) return NULL; hashval=hash(name); np->next=hashtab\[hashval\]; hashtab\[hashval\]=np; \} else free(( void\*)np->defn); if((np->defn=strdup\_(defn))==NULL) return NULL; return np; \} void undef( char\*s)\{ int h; struct nlist \*prev,\*np; prev=NULL; h=hash(s); for(np=hashtab\[h\];np!=NULL;np=np->next)\{ if(strcmp(s,np->name)== 0) break; prev=np; \} if(np!=NULL)\{ if(prev==NULL) hashtab\[h\]=np->next; else prev->next=np->next; free(np->name); free(np->defn); free(np); \} \} void error( int c, char \*s)\{ printf( " error:%s\\n ",s); while(c!=EOF&&c!= ' \\n ') c=getch(); \} void skipblanks()\{ int c; while((c=getch())== ' '||c== ' \\t ') ; ungetch(c); \} \#define MAXWORD 100 void getdef()\{ int c,i; char def\[MAXWORD\],dir\[MAXWORD\],name\[MAXWORD\]; skipblanks(); if(!isalpha(getword(dir,MAXWORD))) error(dir\[ 0\], " getdef:expecting a directive after \# "); else if(strcmp(dir, " define ")== 0)\{ skipblanks(); if(!isalpha(getword(name,MAXWORD))) error(name\[ 0\], " getdef:non-alpha -name expected "); else\{ skipblanks(); for(i= 0;i<MAXWORD- 1;i++) if((def\[i\]=getch())==EOF|| def\[i\]== ' \\n ') break; def\[i\]= ' \\0 '; if(i<= 0) error( ' \\n ', " getdef:incomplete define "); else install(name,def); \} \} else if(strcmp(dir, " undef ")== 0)\{ skipblanks(); if(!isalpha(getword(name,MAXWORD))) error(name\[ 0\], " getdef:non-alpha in undef "); else undef(name); \} else error(dir\[ 0\], " getdef:expecting a directive after \# "); \} int main()\{ char w\[MAXWORD\]; struct nlist \*p; while(getword(w,MAXWORD)!=EOF)\{ if(strcmp(w, " \# ")== 0) getdef(); else if(!isalpha(w\[ 0\])) printf( " %s ",w); else if((p=lookup(w))==NULL) printf( " %s ",w); else ungets(p->defn); \} return 0; \} ![复制代码][copycode.gif] ![201208051120035339.png][] 第7章 输入与输出 变长参数列表 ![201208051120046145.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdarg.h> void minprintf( char \*fmt,...)\{ va\_list ap; char \*p,\*sval; int ival; double dval; va\_start(ap,fmt); for(p=fmt;\*p;p++)\{ if(\*p!= ' % ')\{ putchar(\*p); continue; \} switch(\*++p)\{ case ' d ': ival=va\_arg(ap, int); printf( " %d ",ival); break; case ' f ': dval=va\_arg(ap, double); printf( " %f ",dval); break; case ' s ': for(sval=va\_arg(ap, char\*);\*sval;sval++) putchar(\*sval); break; default: putchar(\*p); break; \} \} va\_end(ap); \} int main()\{ int a= 3; double d= 8.7; minprintf( " %d %f\\n ",a,d); \} ![复制代码][copycode.gif] ![201208051120049177.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdarg.h> \#include <ctype.h> \#define LOCALFMT 100 void minprintf( char \*fmt,...)\{ va\_list ap; char \*p,\*sval; char localfmt\[LOCALFMT\]; int ival,i; unsigned uval; double dval; va\_start(ap,fmt); for(p=fmt;\*p;p++)\{ if(\*p!= ' % ')\{ putchar(\*p); continue; \} i= 0; localfmt\[i++\]= ' % '; while(\*(p+ 1)&&!isalpha(\*(p+ 1))) localfmt\[i++\]=\*++p; localfmt\[i++\]=\*(p+ 1); localfmt\[i\]= ' \\0 '; switch(\*++p)\{ case ' d ': case ' i ': ival=va\_arg(ap, int); printf(localfmt,ival); break; case ' x ': case ' X ': case ' u ': case ' o ': uval=va\_arg(ap,unsigned); printf(localfmt,uval); case ' f ': dval=va\_arg(ap, double); printf(localfmt,dval); break; case ' s ': sval=va\_arg(ap, char\*); printf(localfmt,sval); break; default: putchar(\*p); break; \} \} va\_end(ap); \} int main()\{ int a= 3; double d= 8.7; minprintf( " %d %f\\n ",a,d); \} ![复制代码][copycode.gif] ![201208051120047748.png][] ![201208051120042732.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdarg.h> \#include <ctype.h> \#define LOCALFMT 100 void minscanf( char \*fmt,...)\{ va\_list ap; char \*p,\*sval; char localfmt\[LOCALFMT\]; int c,i,\*ival; unsigned \*uval; double \*dval; va\_start(ap,fmt); for(p=fmt;\*p;p++)\{ if(\*p!= ' % ')\{ localfmt\[i++\]=\*p; continue; \} i= 0; localfmt\[i++\]= ' % '; while(\*(p+ 1)&&!isalpha(\*(p+ 1))) localfmt\[i++\]=\*++p; localfmt\[i++\]=\*(p+ 1); localfmt\[i\]= ' \\0 '; switch(\*++p)\{ case ' d ': case ' i ': ival=va\_arg(ap, int\*); scanf(localfmt,ival); break; case ' x ': case ' X ': case ' u ': case ' o ': uval=va\_arg(ap,unsigned\*); scanf(localfmt,uval); break; case ' f ': dval=va\_arg(ap, double\*); scanf(localfmt,dval); break; case ' s ': sval=va\_arg(ap, char\*); scanf(localfmt,sval); break; default: scanf(localfmt); break; \} \} \} ![复制代码][copycode.gif] ![201208051120059667.png][] ![201208051120053222.png][] 下面是标准库中对fgets和fputs函数的实现: ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] char \*fgets( char \*s, int n,FILE\*iop)\{ register int c; register char \*cs; cs=s; while(--n> 0&&(c=getc(iop))!=EOF) if((\*cs++=c)== ' \\n ') break; \*cs= ' \\0 '; return (c==EOF&&cs==s)?NULL:s; \} int fputs( char\*s ,FILE\*iop)\{ int c; while(c=\*s++) putc(c,iop); return ferror(ip)?EOF: 0; \} ![复制代码][copycode.gif] ![201208051120052666.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#include < string.h> \#define MAXLINE 100 void filecomp(FILE\*fp1,FILE\*fp2)\{ char line1\[MAXLINE\],line2\[MAXLINE\]; char\*lp1,\*lp2; do\{ lp1=fgets(line1,MAXLINE,fp1); lp2=fgets(line2,MAXLINE,fp2); if(lp1==line1&&lp2==line2)\{ if(strcmp(line1,line2)!= 0)\{ printf( " first difference in line\\n %s\\n ",line1); lp1=lp2=NULL; \} \} else if(lp1!=line1&&lp2==line2) printf( " end of first at line\\n%s\\n ",line2); else if(lp1==line1&&lp2!=line2) printf( " end of first at line\\n%s\\n ",line1); \} while(lp1==line1&&lp2==line2); \} int main( int argc, char \*argv\[\])\{ FILE \*fp1,\*fp2; if(argc!= 3)\{ fprintf(stderr, " comp:need two file names\\n "); exit( 1); \} else\{ if((fp1=fopen(\*++argv, " r "))==NULL)\{ fprintf(stderr, " comp:can't open %s\\n ",\*argv); exit( 1); \} else if((fp2=fopen(\*++argv, " r "))==NULL)\{ fprintf(stderr, " comp:can't open %s\\n ",\*argv); exit( 1); \} else\{ filecomp(fp1,fp2); fclose(fp1); fclose(fp2); exit( 0); \} \} \} ![复制代码][copycode.gif] ![201208051120057649.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <stdlib.h> \#define MAXLINE 1000 void fpat(FILE \*fp, char \*fname, char \*pattern, int except, int number); int main( int argc, char\*argv\[\])\{ char pattern\[MAXLINE\]; int c,except= 0,number= 0; FILE \*fp; while(--argc> 0&&(\*++argv)\[ 0\]== ' \- ') while(c=\*++argv\[ 0\]) switch(c)\{ case ' x ': except= 1; break; case ' n ': number= 1; break; default: printf( " find:illegal option %c\\n ",c); argc= 0; break; \} if(argc>= 1) strcpy(pattern,\*argv); else\{ printf( " Usage:find \[-x\] \[-n\] pattern \[file ..\]\\n "); exit( 1); \} if(argc== 1) fpat(stdin, "",pattern,except,number); else while(--argc> 0) if((fp=fopen(\*++argv, " r "))==NULL)\{ fprintf(stderr, " find: can't open %s\\n ",\*argv); exit( 1); \} else\{ fpat(fp,\*argv,pattern,except,number); fclose(fp); \} return 0; \} void fpat(FILE \*fp, char \*fname, char \*pattern, int except, int number)\{ char line\[MAXLINE\]; long lineno= 0; while(fgets(line,MAXLINE,fp)!=NULL)\{ ++lineno; if((strstr(line,pattern)!=NULL)!=except)\{ if(\*fname) printf( " %s - ",fname); if(number) printf( " %ld: ",lineno); printf( " %s ",line); \} \} \} ![复制代码][copycode.gif] ![201208051120058488.png][] ![201208051120061520.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include <stdlib.h> \#define MAXBOT 3 \#define MAXHDR 5 \#define MAXLINE 100 \#define MAXPAGE 66 int heading( char \*fname, int pageno)\{ int ln= 3; fprintf(stdout, " \\n\\n "); fprintf(stdout, " %s page %d\\n ",fname,pageno); while(ln++<MAXHDR) fprintf(stdout, " \\n "); return ln; \} void fileprint(FILE\*fp, char \*fname)\{ int lineno,pageno= 1; char line\[MAXLINE\]; lineno=heading(fname,pageno++); while(fgets(line,MAXLINE,fp)!=NULL)\{ if(lineno== 1)\{ fprintf(stdout, " \\f "); lineno=heading(fname,pageno++); \} fputs(line,stdout); if(++lineno>MAXPAGE-MAXBOT) lineno= 1; \} fprintf(stdout, " \\f "); \} int main( int argc, char \*argv\[\])\{ FILE \*fp; if(argc== 1) fileprint(stdin, " "); else while(--argc> 0) if((fp=fopen(\*++argv, " r "))==NULL)\{ fprintf(stderr, " print:can't open %s\\n ",\*argv); exit( 1); \} else\{ fileprint(fp,\*argv); fclose(fp); \} return 0; \} ![复制代码][copycode.gif] ![201208051120069535.png][] 随机数发生器,生成浮点数的方法 ![201208051120065599.png][] 第8章 UNIX系统接口 ![201208051120068389.png][] 利用低级的read和write函数来构造高级函数getchar,putchar等。 ![复制代码][copycode.gif] int getchar\_( void)\{ char c; return (read( 0,&c, 1)== 1)?(unsigned char)c:EOF; \} int getchar\_\_( void)\{ static char buf\[BUFSIZ\]; static char \*bufp=buf; static int n= 0; if(n== 0)\{ n=read( 0,buf, sizeof buf); bufp=buf; \} return (--n> 0)?(unsigned char )\*bufp++:EOF; \} ![复制代码][copycode.gif] ![201208051120071944.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <unistd.h> \#define NULL 0 \#define EOF (-1) \#define BUFSIZ 1024 \#define OPEN\_MAX 20 typedef struct \_iobuf\{ int cnt; char \*ptr; char \* base; int flag; int fd; \}FILE; extern FILE \_iob\[OPEN\_MAX\]; \#define stdin (&\_iob\[0\]) \#define stdout (&\_iob\[1\]) \#define stderr (&\_iob\[2\]) enum \_flags\{ \_READ = 01, \_WRITE = 02, \_UNBUF= 04, \_EOF = 010, \_ERR= 020 \}; int \_fillbuf(FILE\*); int \_flushbuf( int ,FILE \*); \#define feof(p) (((p)->flag&\_EOF)!=0) \#define ferror(p) (((p)->flag&\_ERR)!=0) \#define fileno(p) ((p)->fd) \#define getc(p) (--(p)->cnt>=0\\ ?(unsigned char)\*(p)->ptr++:\_fillbuf(p)) \#define putc(x,p) (--(p)->cnt>=0\\ ?\*(p)->ptar++=(x):\_flushbuf((x),p)) \#define getchar() getc(stdin) \#define putchar(x) putc(x,stdout) \#include <fcntl.h> \#define PERMS 0666 FILE \*fopen( char \*name, char \*mode) \{ int fd; FILE \*fp; if(\*mode!= ' r '&&\*mode!= ' w '&&\*mode!= ' a ') return NULL; for(fp=\_iob;fp<\_iob+OPEN\_MAX;fp++) if((fp->flag&(\_READ|\_WRITE))== 0) break; if(fp>=\_iob+OPEN\_MAX) return NULL; if(\*mode== ' w ') fd=creat(name,PERMS); else if(\*mode== ' a ')\{ if((fd=open(name,O\_WRONLY, 0))==- 1) fd=creat(name,PERMS); lseek(fd, 0L, 2); \} else fd=open(name,O\_RDONLY, 0); if(fd==- 1) return NULL; fp->fd=fd; fp->cnt= 0; fp-> base=NULL; fp->flag=(\*mode== ' r ')?\_READ:\_WRITE; return fp; \} int \_fillbuf(FILE\*fp)\{ int bufsize; if((fp->flag&(\_READ|\_EOF|\_ERR))!=\_READ) return EOF; bufsize=(fp->flag&\_UNBUF)? 1:BUFSIZ; if(fp-> base==NULL) if((fp-> base=( char\*)malloc(bufsize))==NULL) return EOF; fp->ptr=fp-> base; fp->cnt=read(fp->fd,fp->ptr,bufsize); if(--fp->cnt< 0)\{ if(fp->cnt==- 1) fp->flag|=\_EOF; else fp->flag|=\_ERR; fp->cnt= 0; return EOF; \} return (unsigned char)\*fp->ptr++; \} FILE \_iob\[OPEN\_MAX\]=\{ \{ 0,( char\*) 0,( char\*) 0,\_READ, 0 \}, \{ 0,( char\*) 0,( char\*) 0,\_WRITE, 1 \}, \{ 0,( char\*) 0,( char\*) 0,\_WRITE|\_UNBUF, 2 \}, \}; int \_flushbuf( int x,FILE\*fp)\{ unsigned nc; int bufsize; if(fp<\_iob||fp>=\_iob+OPEN\_MAX) return EOF; if((fp->flag&(\_WRITE|\_ERR))!=\_WRITE) return EOF; bufsize=(fp->flag&\_UNBUF)? 1:BUFSIZ; if(fp-> base==NULL)\{ if((fp-> base=( char\*)malloc(bufsize))==NULL)\{ fp->flag|=\_ERR; return EOF; \} \} else\{ nc=fp->ptr-fp-> base; if(write(fp->fd,fp-> base,nc)!=nc)\{ fp->flag|=\_ERR; return EOF; \} \} fp->ptr=fp-> base; \*fp->ptr++=( char)x; fp->cnt=bufsize- 1; return x; \} int fclose(FILE \*fp)\{ int rc; if((rc=fflush(fp))!=EOF)\{ free(fp-> base); fp->ptr=NULL; fp->cnt= 0; fp-> base=NULL; fp->flag&=(\_READ|\_WRITE); \} return rc; \} int fflush(FILE\*fp)\{ int rc= 0; if(fp<\_iob||fp>=\_iob+OPEN\_MAX) return EOF; if(fp->flag&\_WRITE) rc=\_flushbuf( 0,fp); fp->ptr=fp-> base; fp->cnt=(fp->flag&\_UNBUF)? 1:BUFSIZ; return rc; \} int fseek(FILE \*fp, long offset, int origin)\{ unsigned nc; long rc= 0; if(fp->flag&\_READ)\{ if(origin== 1) offset-=fp->cnt; rc=lseek(fp->fd,offset,origin); fp->cnt= 0; \} else if(fp->flag&\_WRITE)\{ if((nc=fp->ptr-fp-> base)> 0) if(write(fp->fd,fp-> base,nc)!=nc) rc=- 1; if(rc!=- 1) rc=lseek(fp->fd,offset,origin); \} return (rc==- 1)?- 1: 0; \} ![复制代码][copycode.gif] ![201208051120079403.png][] ![20120805112008766.png][] ![201208051120084877.png][] ![201208051120088224.png][] ![201208051120081223.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] \#include <stdio.h> \#include < string.h> \#include <fcntl.h> \#include <sys/types.h> \#include <sys/stat.h> \#include <dirent.h> // \#define NAME\_MAX 14 // typedef struct\{ // long ino; // char name\[NAME\_MAX+1\]; // \}Dirent; // typedef struct\{ // int fd; // Dirent d; // \}DIR; // DIR \*opendir(char \*dirname); // Dirent\* readdir(DIR\*dfd); // void closedir(DIR\* dfd); // char \*name; // struct stat stbuf; // int stat(char \*,struct stat\*); // \#define S\_IFMT 0160000 // \#define S\_IFDIR 0040000 // \#define S\_IFCHR 0020000 // \#define S\_IFBLK 0060000 // \#define S\_IFREG 001000 \#define MAX\_PATH 1024 void dirwalk( char \*dir, void(\*fcn)( char\*))\{ char name\[MAX\_PATH\]; struct dirent \*dp; DIR \*dfd; if((dfd=opendir(dir))==NULL)\{ fprintf(stderr, " dirwalk:can't open %s\\n ",dir); return; \} while((dp=readdir(dfd))!=NULL)\{ if(strcmp(dp->d\_name, " . ")== 0|| strcmp(dp->d\_name, " .. ")== 0) continue; if(strlen(dir)+strlen(dp->d\_name)+ 2> sizeof(name)) fprintf(stderr, " dirwalk:name %s %s too long\\n ", dir,dp->d\_name); else\{ sprintf(name, " %s/%s ",dir,dp->d\_name); fcn(name); \} \} closedir(dfd); \} void fsize( char \*name)\{ struct stat stbuf; if(stat(name,&stbuf)==- 1)\{ fprintf(stderr, " fsize:can't access %s\\n ",name); return ; \} if((stbuf.st\_mode&S\_IFMT)==S\_IFDIR) dirwalk(name,fsize); printf( " %5u %6o %3u %8ld %s\\n ",stbuf.st\_ino, stbuf.st\_mode,stbuf.st\_nlink,stbuf.st\_size,name); \} int main( int argc, char \*\*argv)\{ if(argc== 1) fsize( " . "); else while(--argc> 0) fsize(\*++argv); return 0; \} ![复制代码][copycode.gif] ![201208051120091713.png][] ![201208051120091680.png][] ![201208051120105551.png][] ![201208051120104646.png][] ![201208051120107121.png][] ![20120805112011992.png][] ![201208051120119563.png][] ![2012080511201187.png][] ![ExpandedBlockStart.gif][] ![复制代码][copycode.gif] typedef long Align; union header\{ struct \{ union header \*ptr; unsigned size; \}S; Align x; \}; typedef union header Header; static Header base; static Header \*freep=NULL; void \*malloc(unsigned nbytes)\{ Header \*p,\*prevp; Header \*moreroce(unsigned); unsigned nuints; nuints=(nbytes+ sizeof(Header)- 1)/ sizeof(header)+ 1; if((prevp=freep)==NULL)\{ base.s.ptr=freeptr=prevptr=& base; base.s.size= 0; \} for(p=prevp->s.ptr;;prevp=p,p=p->s.ptr)\{ if(p->s.size>=nuints)\{ if(p->s.size==nuints) prevp->s.ptr=p->s.ptr; else\{ p->s.size-=nuints; p+=p->s.size; p->s.size=nuints; \} freep=prevp; return ( void\*)(p+ 1); \} if(p==freep) if((p=moreroce(nuints))==NULL) return NULL; \} \} \#define NALLOC 1024 static Header \*moreroce(unsigned nu)\{ char \*cp,\*sbrk( int); Header \*up; if(nu<NALLOC) nu=NALLOC; cp=sbrk(nu\* sizeof(Header)); if(cp==( char\*)- 1) return NULL; up=(Header\*)cp; up->s.size=nu; free(( void\*)(up+ 1)); return freep; \} void free( void\*ap)\{ Header \*bp,\*p; bp=(Header\*)ap- 1; for(p=freep;!(bp>p&&bp<p->s.ptr);p=p->s.ptr) if(p>=p->s.ptr&&(bp>p||bp<p->s.ptr)) break; if(bp+bp->size==p->s.ptr)\{ bp->s.size+=p->s.ptr->s.size; bp->s.ptr=p->s.ptr->s.ptr; \} else bp->s.ptr=p->s.ptr; if(p+p->size==bp)\{ p->s.size+=bp->s.size; p->s.ptr=bp->s.ptr; \} else p->s.ptr=bp; freep=p; \} void \*calloc(unsigned n,unsigned size)\{ unsigned i,nb; char \*p,\*q; nb=n\*size; if((p=q=malloc(nb))!=NULL) for(i= 0;i<nb;i++) \*p++= 0; return q; \} ![复制代码][copycode.gif] [http_www.cnblogs.com_xkfz007_articles_2566424.html]: http://www.cnblogs.com/xkfz007/articles/2566424.html [copycode.gif]: /images/20220731/9c5b39f2d4584a3b94c010ebbc4f7ea7.png [201208051119386901.png]: /images/20220731/31cc0c934ecf4e5ebc7f1040fb2da39e.png [ExpandedBlockStart.gif]: /images/20220731/90419dd73dc341ae8cd634afe180eef6.png [201208051119395473.png]: /images/20220731/c6abe7f82e8243769a182cacc0356124.png [201208051119394360.png]: /images/20220731/96d7d9fc9f8a4903a72a593596bbdad1.png [201208051119391295.png]: /images/20220731/6933797fe3844352a00a9dd80e43f4c4.png [201208051119396279.png]: /images/20220731/5bbb6027156143968c26861fe8f7d45c.png [201208051119394294.png]: /images/20220731/f9f49ec6b0ca40b2bf509b4dbf045d87.png [201208051119405689.png]: /images/20220731/01d4434c579742c4a0e91f9181d91cbb.png [201208051119408164.png]: /images/20220731/1e527fca806a41469491ed44b845af38.png [201208051119409768.png]: /images/20220731/8f2172a58f0741b890815446bc503758.png [201208051119401163.png]: /images/20220731/f7bb80cf85534bef95760f4dd35ec1de.png [201208051119414685.png]: /images/20220731/43a5410456f74c238ab4e83c272e19c0.png [201208051119413016.png]: /images/20220731/c8ebec8c1aa24f40b5d7b162f68093dc.png [201208051119428523.png]: /images/20220731/e60d904406224b3f9a57ece298b7a2d2.png [201208051119429046.png]: /images/20220731/5d447eb77b89475bb0e3ba6dfafefe01.png [201208051119425981.png]: /images/20220731/9510006203df462e8c05f389bebdccbe.png [20120805111942965.png]: /images/20220731/60e9c1efc63143cb9121e09d3a4d3d68.png [20120805111942409.png]: /images/20220731/42342fe9fef5420a98463af6c2b97550.png [201208051119428424.png]: /images/20220731/d7d73b200403423e9ef693b111181602.png [201208051119435359.png]: /images/20220731/2d58975ec69c4ff697c4e6f65396c69c.png [20120805111943342.png]: /images/20220731/bc759e28aed746fea142aae28a1d4ff1.png [20120805111944800.png]: /images/20220731/b1600542905d4851867b3a47de2aa76d.png [20120805111944243.png]: /images/20220731/c323cc8badd741a5b33a98a0dca65366.png [201208051119445227.png]: /images/20220731/794545de51c54a54826a079bff0939ad.png [201208051119443765.png]: /images/20220731/703c5052024d452c8c2f8099779b00ff.png [20120805111945701.png]: /images/20220731/39dc9c2472814cc6b94276c4d010115d.png [201208051119457320.png]: /images/20220731/a0bb699de7c64cb7a5a3186ebaee1261.png [201208051119454256.png]: /images/20220731/3cc2300592d64729b50366816d154181.png [201208051119457811.png]: /images/20220731/a3999109ca5c416aa622c579abf77ebf.png [201208051119456698.png]: http://images.cnblogs.com/cnblogs_com/xkfz007/201208/201208051119456698.png [201208051119466109.png]: /images/20220731/d3b01d2719a441b79b26fa9678956ed8.png [201208051119466076.png]: /images/20220731/89fe90b6d2b14dfc915c17f70283f937.png [ContractedBlock.gif]: /images/20220731/3231071e8f18438e9611c83ae053aad9.png [201208051119462695.png]: /images/20220731/84ba0624b7ea4f6f9c79ae242265b627.png [201208051119474614.png]: /images/20220731/9523e94fc6a2460080ef8fa4013db3bb.png [20120805111947993.png]: /images/20220731/4b289367e88e4a8eaa910556ff002ce1.png [201208051119474025.png]: /images/20220731/bbee9c7dea334b7bb1a1130fcdd6f467.png [201208051119477056.png]: /images/20220731/8c008a314959438f845f2205a9b7cfdb.png [201208051119484515.png]: /images/20220731/4c01ae39de2843448949b3c4db3da142.png [201208051119483402.png]: /images/20220731/570ce7c451d449579e5fde7948730dd4.png [20120805111948338.png]: /images/20220731/553f20faca6346b0be8ce0ffd88aceeb.png [201208051119482497.png]: /images/20220731/f7db128cbfea42d7bedb32c37fc849d1.png [201208051119489432.png]: /images/20220731/e250d95aff9741ada03801cb255cc7af.png [201208051119496368.png]: /images/20220731/88fae79af20d438ab1f32f970f0525a5.png [201208051119491351.png]: /images/20220731/d1624fd4923d41fc8d8a7a16ccf244d7.png [201208051119496335.png]: /images/20220731/1b4bdece3e704c42b870a01e01f5a6da.png [201208051119494350.png]: /images/20220731/a6bcd805cd924f79b3fa2085e10abc94.png [201208051119501809.png]: /images/20220731/40b47facf86742b8aa363195f67de534.png [201208051119503204.png]: /images/20220731/fc0522ee1cb743c18e6675f7650afe6f.png [201208051119501776.png]: /images/20220731/b1c6ea068aa041d291f5c334feae8de7.png [201208051119504807.png]: /images/20220731/c30cf0c278954a2aa5975be19e848512.png [201208051119507598.png]: /images/20220731/220bf39d2af14cdf88c03e42077ce0a2.png [201208051119502582.png]: /images/20220731/455d21520d034e9eb1345921968d08e5.png [201208051119517216.png]: /images/20220731/63d4f60487f74c6bbb06510c69f5f2fd.png [201208051119518612.png]: /images/20220731/dfdab91002004307a979d3c5c669b165.png [201208051119514675.png]: /images/20220731/ff2dc600181544d3a02203bc9e595bcb.png [201208051119512483.png]: /images/20220731/0d75b8b20d264867a6e9c921dd68976a.png [201208051119523006.png]: /images/20220731/94ad72f65a75492182d05a3b5f0a60df.png [201208051119526038.png]: /images/20220731/ff506d205a704d8695900aa45c41800f.png [201208051119529069.png]: /images/20220731/f159f6f9a8b0432da1645510202ae078.png [201208051119536495.png]: /images/20220731/d0b116c9b070442aa28d16fb7e8bbc9b.png [201208051119537890.png]: /images/20220731/d7c268a4922141c1a2b3e821896559fe.png [201208051119532841.png]: /images/20220731/df0c09012058484abca4d342c20d078b.png [201208051119539776.png]: /images/20220731/ec0f110b8e1847368765e207ea982d82.png [201208051119541379.png]: /images/20220731/37a803313fe646448320b1f8838f19a5.png [201208051119549395.png]: /images/20220731/95f6a8366e25472aac5a88af0721f312.png [20120805111954790.png]: /images/20220731/ea18fac8c4ad46c29d0ca7c1318ddc02.png [201208051119541837.png]: /images/20220731/ebc5e86a59f54a70ba38256ec3f9114d.png [201208051119556264.png]: /images/20220731/c574700642e243aebe7d7050afc8b26e.png [201208051119552643.png]: /images/20220731/21c6438e9fcd4c9daf747fe67948e4cb.png [201208051119556754.png]: /images/20220731/053e4839e0a34509b26f464654070406.png [201208051119568117.png]: /images/20220731/eabd51b60d754bcbaf60b755a39bf314.png [201208051119564180.png]: /images/20220731/a028c10ae85045e3873c27424f2139f8.png [201208051119568051.png]: /images/20220731/a36e3d5e79fd4739914c8700425209d7.png [201208051119571921.png]: /images/20220731/8322dc3a8edf460ca498a2fd24fe8d7f.png [201208051119577985.png]: /images/20220731/6de436c8fe8447f9adba0d29cc842108.png [201208051119579031.png]: /images/20220731/120e140d1f5f42f8a582998a4431d121.png [201208051119585967.png]: /images/20220731/80ae3560b73348d8b465881a7e2e2bf0.png [201208051119581822.png]: /images/20220731/722d43084ddf4483b8219833f5d97bca.png [201208051119581474.png]: /images/20220731/d523ad83b99e4180a0ccbc2c4d2724b8.png [201208051119587329.png]: /images/20220731/8a013811b1104131a9fd97347dfdf005.png [20120805111958361.png]: /images/20220731/f80f1771454b47a79f81cf79de30bd9d.png [201208051119584788.png]: /images/20220731/6b7a98bd9cd84c739d4eab33ef2bd233.png [201208051119593359.png]: /images/20220731/4067aaab0fb84682b73dcd4063a0f2eb.png [201208051119598343.png]: /images/20220731/85df25422d164485b0ab1b6f6e80cbdd.png [201208051119597197.png]: /images/20220731/79809b9ee5aa40bb9095129bd7659a09.png [201208051120002147.png]: /images/20220731/65c879cc34054e9ba39cea5b20ed4b88.png [201208051120005179.png]: /images/20220731/e850d1fe8afc4acaac7737654381dc15.png [201208051120001242.png]: /images/20220731/0812704863144c94a59c3caed2710748.png [201208051120002605.png]: /images/20220731/8dc57b9e11a640a7a216188206f40a12.png [201208051120019540.png]: /images/20220731/63d9cc5c216740309be89a1a992b0805.png [http_cdecl.org]: http://cdecl.org/ [201208051120015603.png]: /images/20220731/ef9cf21ab5a94ee287cda5140d26d02f.png [201208051120016999.png]: /images/20220731/af381dc84a5242a18122ed9bda6ad8d5.png [201208051120011982.png]: /images/20220731/293a4be71b09403abb9062803fbd9131.png [201208051120029441.png]: /images/20220731/a51da3b3d8d04217abcb664d41d5f800.png [201208051120024425.png]: /images/20220731/9d38685dc5084a4ca00ef2ca33b8e2de.png [201208051120021883.png]: /images/20220731/ece700e504dc4afaaf0eea3fe2ef0e06.png [201208051120033802.png]: /images/20220731/bcd88b70f50546be96333d03e3922b63.png [201208051120032374.png]: /images/20220731/28bea6a5280b42a5a9175ea7dc1cb71c.png [20120805112003945.png]: /images/20220731/cc79d210c8374eada0c86f060b02d093.png [201208051120032341.png]: /images/20220731/d6afe2fbe8474300bc4bce66bc6264c7.png [201208051120035339.png]: /images/20220731/f786016c327b4b619d52b3e7fbceead6.png [201208051120046145.png]: /images/20220731/ec0f0d24e2a3410e833a1f76e6b373e2.png [201208051120049177.png]: /images/20220731/996e75324c4944cfbc1eedbe187263ad.png [201208051120047748.png]: /images/20220731/a1163d71f5f24866b079431c22f41200.png [201208051120042732.png]: /images/20220731/ecedcd9b05214aef9a9a529689e16917.png [201208051120059667.png]: /images/20220731/98f0d2e73d574a6f996326b6f42cf946.png [201208051120053222.png]: /images/20220731/8ae2170e812d49aa8f076cc854f8da2d.png [201208051120052666.png]: /images/20220731/4423a75ff9be4ae4948f268f8f54193c.png [201208051120057649.png]: /images/20220731/dcf78985058e48d9897c2c73ef36f6a1.png [201208051120058488.png]: /images/20220731/6c67b3525e8347c3bb6373ba3a4b0d67.png [201208051120061520.png]: /images/20220731/5ef8a44a6052448e990b12015fbeaed4.png [201208051120069535.png]: /images/20220731/ffb969a1269e47529956d204ed45a9d2.png [201208051120065599.png]: /images/20220731/4b70538aa07545d1b4afb17889106fe0.png [201208051120068389.png]: /images/20220731/fa5b2ecb6b254fc6b7e61af8e13e1efc.png [201208051120071944.png]: /images/20220731/a4788a1f5fcd441cabb1541ea148034d.png [201208051120079403.png]: /images/20220731/8f494a60a0e9495aa429350098872b15.png [20120805112008766.png]: /images/20220731/f1ab7b107aeb44d4a806746d43d21a64.png [201208051120084877.png]: /images/20220731/236d2e5f46a74c9183d8f3dbfef9e7f7.png [201208051120088224.png]: /images/20220731/aab3a7797ec643dbae4f90d145d507b6.png [201208051120081223.png]: /images/20220731/3609c55f160748c8ae3a15d37b9ccb65.png [201208051120091713.png]: /images/20220731/71d6e0d15a0c447082c5eac47fc765d6.png [201208051120091680.png]: /images/20220731/f946538b69bd4225af79790f0250c66b.png [201208051120105551.png]: /images/20220731/579caae8d05f40a8860194ae90bb3c58.png [201208051120104646.png]: /images/20220731/53a2cf4824734cf4823590f20e564a33.png [201208051120107121.png]: /images/20220731/4094ca17b30749c59f3c94f838af2d2a.png [20120805112011992.png]: /images/20220731/693ae91da01b4213bc6ad0d30c91e145.png [201208051120119563.png]: /images/20220731/bd142257ad3845a0a1747b2efbad36e8.png [2012080511201187.png]: /images/20220731/cd9cb514dc1544029ddd70d5210a4186.png
还没有评论,来说两句吧...