2_6_1.c #include main() { FILE *fp; int sid, cid, cnt, ln; char sname[20], buf[20]; if((fp=fopen("data.txt","r"))==NULL) { fprintf(stderr, "FILE OPEN ERROR\n"); } else { ln=fscanf(fp,"%d:%s", &cid, buf); while( ln != EOF ) { /** 学生毎の繰返し **/ sid=cid; strcpy(sname,buf); cnt=0; /** 学生の初期設定 **/ /** 科目毎の繰返し **/ while( (ln=fscanf(fp,"%d:%s", &cid, buf)) != EOF && isdigit(*buf) ) if(atoi(buf)>=60) cnt++; /** 成績チェック **/ /** 結果発表 **/ printf("%03d:%s\t%s\n",sid,sname, cnt>=10?"合格":"不合格"); } } } 2_6_2.c #include main() { FILE *fp; int cnt, sid, cid, first=1; char sname[20],buf[20]; if((fp=fopen("data.txt","r"))==NULL) { fprintf(stderr, "FILE OPEN ERROR\n"); } else { while( fscanf(fp,"%d:%s", &cid, buf) != EOF ) /** レコード繰返し **/ if( isdigit(*buf) ) { /** 成績レコード **/ if( atoi(buf) >= 60 ) cnt++; /** 成績チェック **/ } else { /** 学生IDレコード **/ if( first ) /** 最初は結果発表なし **/ first = 0; else /** 結果発表 **/ printf("%03d:%s\t%s\n",sid,sname, cnt>=10?"合格":"不合格"); sid=cid; strcpy(sname,buf); cnt=0; /** 学生の初期設定 **/ } if( !first ) /** 最後の学生の結果発表 **/ printf("%03d:%s\t%s\n",sid,sname, cnt>=10?"合格":"不合格"); } } 2_7.c #include /** ':1 ":2 /:3 *:4 \\:5 \n:6 other:0 **/ int chartype(int ch) { return ch=='\'' ? 1 : ch=='"' ? 2 : ch=='/' ? 3 : ch=='*' ? 4 : ch=='\\' ? 5 : ch=='\n' ? 6 : 0 ; } // action 実行命令 doAction(int actionNo, int c, int lnum) { switch(actionNo) { case 1: /** 通常コメント開始 **/ printf("%04d :/*", lnum); break; case 2: /** 行末コメント開始 **/ printf("%04d ://", lnum); break; case 3: /** 通常コメント終了 **/ printf("/\n"); break; case 4: /** 行末コメント終了 **/ case 5: /** コメント本体出力 **/ putchar(c); } } int STD[10][7][2]= /** other ' " / * \\ \n *******************/ { { {0,0},{1,0},{4,0},{6,0},{0,0},{0,0},{0,0} }, /* 0 初期状態 */ { {2,0},{10,0},{2,0},{2,0},{2,0},{3,0},{11,0} }, /* 1 '状態1 */ { {12,0},{0,0},{12,0},{12,0},{12,0},{12,0},{12,0} }, /* 2 '.状態2 */ { {2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0} }, /* 3 '\状態 */ { {4,0},{4,0},{0,0},{4,0},{4,0},{5,0},{4,0} }, /* 4 "状態 */ { {4,0},{4,0},{4,0},{4,0},{4,0},{4,0},{4,0} }, /* 5 "..\状態 */ { {0,0},{0,0},{0,0},{7,2},{8,1},{0,0},{0,0} }, /* 6 /状態 */ { {7,5},{7,5},{7,5},{7,5},{7,5},{7,5},{0,4} }, /* 7 //状態 */ { {8,5},{8,5},{8,5},{8,5},{9,5},{8,5},{8,5} }, /* 8 /*状態 */ { {8,5},{8,5},{8,5},{0,3},{9,5},{8,5},{8,5} } }; /* 9 /* .. *状態 */ char errmsg[5][20]={"空文字定数","開文字定数","1字以上の文字定数"}; #define ERRORSTATE 10 #define NEXTSTATE 0 #define ACTION 1 main(int argc, char *argv[]) { FILE *fp; int state=0, c, ln=1; if( argc != 2 ) { fprintf(stderr, "Usage: a.exe c_program_file_name\n"); exit(1); } if((fp=fopen(argv[1],"r"))==NULL) { fprintf(stderr, "FILE(%s) OPEN ERROR\n", argv[1]); exit(1); } while( (c=fgetc(fp)) != EOF && state < ERRORSTATE ) { if( c=='\n') ln++; doAction(STD[state][chartype(c)][ACTION], c, ln); state=STD[state][chartype(c)][NEXTSTATE]; } fclose(fp); if( state >= ERRORSTATE ) fprintf(stderr, "ERROR at %04d: %s\n", ln, errmsg[state-ERRORSTATE]); else if( state != 0 && state != 7 ) fprintf(stderr, "ERROR: 途中でEOFになった\n"); } 3_1.c // 語データ(語と行番号リスト)リスト(語でソート)を使ったソートの例 // リスト構造を使っているので、語数の上限を決めなくてもよい。 #include struct nlist { int num; struct nlist *next; }; struct wlist { char *wd; struct nlist *nh, *nt; struct wlist *next; }; struct nlist *newNum(int n) { struct nlist *np=(struct nlist *)malloc(sizeof(struct nlist)); np->num=n; np->next=NULL; return np; } struct wlist *newWord(char *wd, int n) { struct wlist *wp=(struct wlist *)malloc(sizeof(struct wlist)); wp->wd=(char *)malloc(strlen(wd)+1); strcpy(wp->wd, wd); wp->nh = wp->nt = newNum(n); wp->next=NULL; return wp; } main() { char word[300]; int n, cmp; struct wlist *whead=NULL, *wp1, *wp2, *newW; struct nlist *newN, *np; /*** input and sort ***/ while( scanf("%s %d", word, &n)!=EOF ) { for(wp1=NULL, wp2=whead; wp2; wp1=wp2, wp2=wp2->next) if( (cmp=strcmp(wp2->wd, word)) >= 0 ) break; if( wp2==NULL || cmp!=0 ) { /** new word **/ newW=newWord(word, n); newW->next=wp2; if(wp1==NULL) whead=newW; else wp1->next=newW; } else { /** old word **/ newN=newNum(n); wp2->nt->next = newN; wp2->nt = newN; } } /*** output ***/ for(wp1=whead; wp1; wp1=wp1->next) for(np=wp1->nh; np; np=np->next) printf("%s %d\n", wp1->wd, np->num); } 3_5_1.c #include #define SSIZE 20 typedef struct { int top; int elem[SSIZE]; } STACK; STACK *create(){ STACK *s; s=(STACK *)malloc(sizeof(STACK)); s->top=0; return s; } int IsEmpty(STACK *s){ return s->top==0; } int IsFull(STACK *s) { return s->top >= SSIZE; } int top(STACK *s) { return s->elem[s->top - 1]; } push(STACK *s, int e){ if(s->topelem[(s->top)++]=e; } int pop(STACK *s) { if(s->top>0) return s->elem[--(s->top)]; } int rank(int o){ if(o==';') return 0; if(o=='+' || o=='-') return 1; if(o=='*' || o=='/') return 2; return 3; } int compute(int n1, int op, int n2) { if(op=='+') return n1+n2; if(op=='-') return n1-n2; if(op=='*') return n1*n2; if(op=='/') return n1/n2; return 0; } main() { STACK *kou, *enzan; char buff[20]; int n, op, opS, n1, n2; kou=create(); enzan=create(); printf("式(空白で区切る)? "); while(1) { scanf("%s", buff); if( rank(buff[0]) < 3 ) { op=buff[0]; while(!IsEmpty(enzan) && rank(top(enzan))>=rank(op)) { opS=pop(enzan); if( !IsEmpty(kou) ) n2=pop(kou); else { printf("SYNTAX ERROR 1\n"); return; } if( !IsEmpty(kou) ) n1=pop(kou); else { printf("SYNTAX ERROR 2\n"); return; } push( kou, compute(n1, opS, n2) ); } if(op==';') break; push(enzan, op); } else if( buff[0]>='0' && buff[0]<='9' ) { push(kou, atoi(buff)); } else { printf("WORD ERROR\n"); return; } } if(!IsEmpty(kou)) printf("結果= %d\n", top(kou)); else printf("SYNTAX ERROR 3\n"); } 3_5_2.c #include #define SSIZE 20 typedef struct { int top; int elem[SSIZE]; } STACK; STACK *create(){ STACK *s; s=(STACK *)malloc(sizeof(STACK)); s->top=0; return s; } int IsEmpty(STACK *s){ return s->top==0; } int IsFull(STACK *s) { return s->top >= SSIZE; } int top(STACK *s) { return s->elem[s->top - 1]; } push(STACK *s, int e){ if(s->topelem[(s->top)++]=e; } int pop(STACK *s) { if(s->top>0) return s->elem[--(s->top)]; } int rankOp(int o){ if(o==';') return 0; if(o==')') return 1; if(o=='+' || o=='-') return 2; if(o=='*' || o=='/') return 3; if(o=='(') return 4; return 9; } int rankStk(int o){ /* stackには')',';'は入らない */ if(o=='(') return 0; if(o=='+' || o=='-') return 2; if(o=='*' || o=='/') return 3; return 9; } int compute(int n1, int op, int n2) { if(op=='+') return n1+n2; if(op=='-') return n1-n2; if(op=='*') return n1*n2; if(op=='/') return n1/n2; return 0; } main() { STACK *kou, *enzan; char buff[20]; int n, op, opS, n1, n2; kou=create(); enzan=create(); printf("式(空白で区切る)? "); while(1) { scanf("%s", buff); if( rankOp(buff[0]) < 9 ) { op=buff[0]; while(!IsEmpty(enzan) && rankStk(top(enzan))>=rankOp(op)) { opS=pop(enzan); if( !IsEmpty(kou) ) n2=pop(kou); else { printf("SYNTAX ERROR 1\n"); return; } if( !IsEmpty(kou) ) n1=pop(kou); else { printf("SYNTAX ERROR 2\n"); return; } push( kou, compute(n1, opS, n2) ); } if(op==';') break; if(op==')') pop(enzan); /* 対応する'('をpop */ else push(enzan, op); } else if( buff[0]>='0' && buff[0]<='9' ) { push(kou, atoi(buff)); } else { printf("WORD ERROR\n"); return; } } if(!IsEmpty(kou)) printf("結果= %d\n", top(kou)); else printf("SYNTAX ERROR 3\n"); } 3_7.c #include #define QSIZE 100 typedef struct { int type, num; } ELEM; typedef struct { int top, tail, num; ELEM *elem[QSIZE]; } QUEUE; QUEUE *createQ() { QUEUE *qp; qp=(QUEUE *)malloc(sizeof(QUEUE)); qp->top=qp->tail=qp->num=0; return qp; } ELEM *last(QUEUE *q) { return q->num==0 ? NULL : q->elem[q->top]; } ELEM *enqueue(QUEUE *q, ELEM *data) { if( q->num==QSIZE ) return NULL; q->elem[q->tail]=data; q->tail=(q->tail+1)%QSIZE; (q->num)++; return data; } ELEM *dequeue(QUEUE *q) { int oldtop=q->top; if( q->num==0 ) return NULL; q->top=(q->top+1)%QSIZE; (q->num)--; return q->elem[oldtop]; } ELEM *newElem(int type, int num) { ELEM *e=(ELEM *)malloc(sizeof(ELEM)); e->type=type; e->num=num; return e; } #define SSIZE 20 typedef struct { int top; int elem[SSIZE]; } STACK; STACK *create(){ STACK *s; s=(STACK *)malloc(sizeof(STACK)); s->top=0; return s; } int IsEmpty(STACK *s){ return s->top==0; } int IsFull(STACK *s) { return s->top >= SSIZE; } int top(STACK *s) { return s->elem[s->top - 1]; } push(STACK *s, int e){ if(s->topelem[(s->top)++]=e; } int pop(STACK *s) { if(s->top>0) return s->elem[--(s->top)]; } int rank(int o){ if(o=='+' || o=='-') return 1; if(o=='*' || o=='/') return 2; return 0; } int compute(int n1, int op, int n2) { if(op=='+') return n1+n2; if(op=='-') return n1-n2; if(op=='*') return n1*n2; if(op=='/') return n1/n2; return 0; } main() { QUEUE *words; ELEM *e; STACK *kou, *enzan; char buff[20]; int n, op, opS, n1, n2, c, rankop; words=createQ(); /*** 文字列の読み込み ***/ printf("式(ctl-dで終了)? "); while( (c=getchar())!=EOF ) { if( c=='(' ) enqueue(words, newElem('(', 0) ); else if( c==')' ) enqueue(words, newElem(')', 0) ); else if( c=='+' ) enqueue(words, newElem('+', 0) ); else if( c=='-' ) enqueue(words, newElem('-', 0) ); else if( c=='*' ) enqueue(words, newElem('*', 0) ); else if( c=='/' ) enqueue(words, newElem('/', 0) ); else if( isdigit(c) ) { n=c-'0'; while( isdigit(c=getchar()) ) n=n*10+(c-'0'); ungetc(c, stdin); enqueue(words, newElem('0', n) ); } } kou=create(); enzan=create(); while(1) { e=dequeue(words); if( e && e->type=='0' ) push(kou, e->num); else { rankop = e ? rank(e->type) : 0; while(!IsEmpty(enzan) && rank(top(enzan))>=rankop) { opS=pop(enzan); if( !IsEmpty(kou) ) n2=pop(kou); else { printf("SYNTAX ERROR 1\n"); return; } if( !IsEmpty(kou) ) n1=pop(kou); else { printf("SYNTAX ERROR 2\n"); return; } push( kou, compute(n1, opS, n2) ); } if(e==NULL) break; push(enzan, e->type); } } if(!IsEmpty(kou)) printf("結果= %d\n", top(kou)); else printf("SYNTAX ERROR 3\n"); } 5_10.c #include /** Bubble sort **/ void mysort(void *v[], int size, int(*comp)(void*,void*)) { int i, j; void *tmp; for(i=0; i<=size-2; i++) for(j=size-2; j>=i; j--) if( (*comp)(v[j],v[j+1])>0 ) { tmp=v[j]; v[j]=v[j+1]; v[j+1]=tmp; } } struct member { int age; char name[20]; }; int agecmp(struct member *a, struct member *b) { return a->age > b->age ? 1 : 0 ; } int namecmp(struct member *a, struct member *b) { return strcmp(a->name, b->name); } print_all(struct member *v[], int size, char *msg){ int i; printf("%s\n", msg); for(i=0;iage, v[i]->name); } main() { FILE *fp; int n=0, i; struct member *st[200]; struct member tmp; char *nms[]={"taro","jiro","hanako","kenta"}; mysort((void **)nms, 4, (int(*)(void*,void*))strcmp ); for(i=0;i<4;i++) printf("%s ", nms[i]); printf("\n"); if( (fp=fopen("data","r"))==NULL ) { perror("data file"); exit(1); } while( fscanf(fp,"%d %s", &(tmp.age), tmp.name)!=EOF ) { st[n]=(struct member *)malloc(sizeof(struct member)); *st[n]=tmp; n++; } print_all(st, n, "no sort"); mysort( (void **)st, n, (int(*)(void*,void*))agecmp ); print_all(st, n, "age sort"); mysort( (void **)st, n, (int(*)(void*,void*))namecmp ); print_all(st, n, "name sort"); } 5_12.c #include int pascal(i,j) { if(j==0) return 1; if(i==j) return 1; return pascal(i-1,j-1) + pascal(i-1,j); } printsp(int n){ while(n--) printf(" "); } main() { int n=5, i, j; for(i=0;i<=n;i++) { printsp(n-i); for(j=0;j<=i;j++) { printf("%3d", pascal(i,j)); printsp(1); } printf("\n"); } } 6_7.c // 6-7 統合プログラムの例 // @語分割(getwd)で、インバージョンを利用している。 // 語分割では、コメントや文字(列)定数中の語は省く処理を、状態遷移表 // によって行っている。 // Aソートは、語と行数をリスト構造にしてソート登録し、登録後に結果を //  出力する方式を使った。 // B全体のリスト構造は、語データのリストからなり、語データは1つの語 // と行番号のリストからなる。語データは語の大小でソートされている。 #include /************ get word in c source file ****************/ int ctype(int c) { return isalpha(c) ? 0 : isdigit(c) ? 1 : c=='/' ? 2 : c=='*' ? 3 : c=='"' ? 4 : c=='\'' ? 5 : c=='\n' ? 6 : c=='\\' ? 7 : c=='#' ? 8 : /* other */ 9 ; } int nextst(int st, int c) { int STD[10][10]={/*0 1 2 3 4 5 6 7 8 9 */ /* alpa */ { 1, 1, 1, 3, 4, 4, 6, 7, 6, 7 }, /* dig */ { 0, 1, 0, 3, 4, 4, 6, 7, 6, 7 }, /* / */ { 2, 2, 3, 3, 4, 0, 6, 7, 6, 7 }, /* * */ { 0, 0, 4, 3, 5, 5, 6, 7, 6, 7 }, /* " */ { 6, 6, 6, 3, 4, 4, 0, 7, 6, 7 }, /* ' */ { 7, 7, 7, 3, 4, 4, 6, 0, 6, 7 }, /* \n */ { 0, 0, 0, 0, 4, 4, 6, 7, 6, 7 }, /* \ */ { 0, 0, 0, 3, 4, 4, 8, 9, 6, 7 }, /* # */ { 3, 0, 0, 3, 4, 4, 6, 7, 6, 7 }, /* else */ { 0, 0, 0, 3, 4, 4, 6, 7, 6, 7 } }; return STD[ctype(c)][st]; } struct wd { char word[100]; int num; }; struct wd *getwd() { static int c, st=0, oldst, wpos=0, ln=1; static struct wd wdata; /**/ static int S=0; /**/ /**/ if(S==1) goto L; /**/ while((c=getchar())!=EOF) { oldst=st; st=nextst(st, c); if( st==1 ) wdata.word[wpos++]=c; else if(oldst==1 && st!=1) { wdata.word[wpos]='\0'; wdata.num=ln; wpos=0; /******* put &wdata ***********/ /**/ S=1;return &wdata; L:; /**/ /******************************/ } if(c=='\n') { ln++; } } return NULL; } /************ read c reserved word *************/ char *reserved[200]; int rnum; int readresword(char *fname) { FILE *fp; char rword[100]; if( (fp=fopen(fname, "r"))==NULL ) { perror("reserved file not found"); return -1; } rnum=0; while( fscanf(fp,"%s",rword)!=EOF && rnum < 200 ) { reserved[rnum]=(char *)malloc(strlen(rword)+1); strcpy(reserved[rnum], rword); rnum++; } fclose(fp); return rnum; } int isReserved(char *word) { int i; for(i=0;inum=n; np->next=NULL; return np; } struct wlist *newWord(char *wd, int n) { struct wlist *wp=(struct wlist *)malloc(sizeof(struct wlist)); wp->wd=(char *)malloc(strlen(wd)+1); strcpy(wp->wd, wd); wp->nh = wp->nt = newNum(n); wp->next=NULL; return wp; } /************** main program ********************/ main() { char word[300]; int n, cmp; struct wlist *whead=NULL, *wp1, *wp2, *newW; struct nlist *newN, *np; struct wd *w; /*** read reserved word ***/ if( readresword("res.txt") < 0 ) exit(1); /*** input and sort ***/ while( w=getwd() ) { for(wp1=NULL, wp2=whead; wp2; wp1=wp2, wp2=wp2->next) if( (cmp=strcmp(wp2->wd, w->word)) >= 0 ) break; if( wp2==NULL || cmp!=0 ) { /** new word **/ newW=newWord(w->word, w->num); newW->next=wp2; if(wp1==NULL) whead=newW; else wp1->next=newW; } else { /** old word **/ newN=newNum(w->num); wp2->nt->next = newN; wp2->nt = newN; } } /*** output ***/ printf("word\tline number\n----\t-----------\n"); for(wp1=whead; wp1; wp1=wp1->next) if( ! isReserved(wp1->wd) ) { printf("%s\t", wp1->wd); for(np=wp1->nh; np; np=np->next) printf("%d%c", np->num, (np->next ? ',' : '\n')); } } 6_7_1.c // 語分解 #include int ctype(int c) { return isalpha(c) ? 0 : isdigit(c) ? 1 : c=='/' ? 2 : c=='*' ? 3 : c=='"' ? 4 : c=='\'' ? 5 : c=='\n' ? 6 : c=='\\' ? 7 : c=='#' ? 8 : /* other */ 9 ; } int nextst(int st, int c) { int STD[10][10]={/*0 1 2 3 4 5 6 7 8 9 */ /* alpa */ { 1, 1, 1, 3, 4, 4, 6, 7, 6, 7 }, /* dig */ { 0, 1, 0, 3, 4, 4, 6, 7, 6, 7 }, /* / */ { 2, 2, 3, 3, 4, 0, 6, 7, 6, 7 }, /* * */ { 0, 0, 4, 3, 5, 5, 6, 7, 6, 7 }, /* " */ { 6, 6, 6, 3, 4, 4, 0, 7, 6, 7 }, /* ' */ { 7, 7, 7, 3, 4, 4, 6, 0, 6, 7 }, /* \n */ { 0, 0, 0, 0, 4, 4, 6, 7, 6, 7 }, /* \ */ { 0, 0, 0, 3, 4, 4, 8, 9, 6, 7 }, /* # */ { 3, 0, 0, 3, 4, 4, 6, 7, 6, 7 }, /* else */ { 0, 0, 0, 3, 4, 4, 6, 7, 6, 7 } }; return STD[ctype(c)][st]; } main() { int c, st=0, oldst; while((c=getchar())!=EOF) { oldst=st; st=nextst(st, c); if( st==1 ) putchar(c); else if(oldst==1 && st!=1) putchar('\n'); if(c=='\n') printf("#\n"); } } 6_7_2.c // ページNo生成 #include main() { int n=1; char buff[200]; while( gets(buff) ) { if(buff[0]=='#') n++; else printf("%s %d\n", buff, n); } } 6_7_3.c // ソート #include #define MAX 10000 swap(char *v[], int i, int j) { char *tmp; tmp=v[i]; v[i]=v[j]; v[j]=tmp; } int comp(char *v1, char *v2) { for(; *v1==*v2 && *v1!=' '; v1++, v2++); if(*v1==*v2) { int n1=atoi(v1), n2=atoi(v2); return n1==n2 ? 0 : n1>n2 ? 1 : -1 ; } return *v1>*v2 ? 1 : -1; } qsort(char *v[], int left, int right) { int i, last; if(left>=right) return; swap(v, left, (left+right)/2); last=left; for(i=left; i<=right; i++) if( comp( v[i], v[left]) < 0 ) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); } main() { int n=0, i; char *vec[MAX], line[200]; while(gets(line) && n < MAX) { vec[n]=(char *)malloc(strlen(line)+1); strcpy(vec[n], line); n++; } qsort(vec, 0, n-1); for(i=0;i char *reserved[200]; int rnum; int readresword(char *fname) { FILE *fp; char rword[100]; if( (fp=fopen(fname, "r"))==NULL ) { perror("reserved file not found"); return -1; } rnum=0; while( fscanf(fp,"%s",rword)!=EOF && rnum < 200 ) { reserved[rnum]=(char *)malloc(strlen(rword)+1); strcpy(reserved[rnum], rword); rnum++; } fclose(fp); return rnum; } int isReserved(char *word) { int i; for(i=0;i main() { int n; char w[100], ow[100]=""; printf("word\tline number\n----\t-----------"); while(scanf("%s %d", w, &n)!=EOF) { if(strcmp(w,ow)) { printf("\n%s\t%d", w, n); strcpy(ow, w); } else { printf(",%d", n); } } printf("\n"); } 6_8.txt // もとのインバージョンによるプログラム(図6.11(d)) void out(int c) { static int ln=0, cl, n; if(ln != 0) goto L; while(c != NULL) { printf("%3d", ++ln); cl=0; while(cl<4) { putchar(' '); putchar(' '); n=0; while(n<3) { putchar(c); return; L: n++; } cl++; } printf("\n"); } printf("\n"); } // outの変形:初期の場合(ln==0)とそうでない場合の区別して繰返しを開く void out1(int c) { static int ln=0, cl, n; // 初期値として0を設定 if(ln==0) { if(c==NULL) { printf("\n"); return; } printf("%3d", ++ln); cl=0; /*** cl<4だから ***/ putchar(' '); putchar(' '); n=0; /*** n<3だから ***/ putchar(c); return; } else { /*** L:から開始 ***/ n++; if(n<3) { putchar(c); return; } cl++; if(cl<4) { putchar(' '); putchar(' '); n=0; /*** n<3だから ***/ putchar(c); return; } printf("\n"); if(c==NULL) { printf("\n"); return; } printf("%3d", ++ln); cl=0; /*** cl<4だから ***/ putchar(' '); putchar(' '); n=0; /*** n<3だから ***/ putchar(c); return; } } // out1の変形:文の移動、条件の反転等 void out2(int c) { static int ln=0, cl=0, n=0; // 初期値として0を設定しln==0のときのcl=0;n=0を削除 if(ln==0) { if(c==NULL) { printf("\n"); return; } printf("%3d", ++ln); // 空白を2個追加して2つのputchar(' ');を削除 } else { n++; if(n>=3) { // 条件を反対にしてputchar(c); return;は最後の処理に移す cl++; if(cl>=4) { // 条件を反対にしてputchar(c); return;は最後の処理に移す printf("\n"); if(c==NULL) { printf("\n"); return; } printf("%3d", ++ln); cl=0; } putchar(' '); putchar(' '); // cl<4とcl>=4の両方ででてくる n=0; // 処理をif文の外に出す。 } } putchar(c); // putchar(c); return;をここに移す } // out2の変形:c==NULLの判定を先頭で行うように変換。 // c==NULLなら以降の処理はなされないので、先頭に移せる。 void out3(int c) { static int ln=0, cl=0, n=0; if(c==NULL) { printf("\n"); return; } if(ln==0) printf("%3d", ++ln); else { n++; if(n>=3) { cl++; if(cl>=4) { printf("\n"); printf("%3d", ++ln); cl=0; } putchar(' '); putchar(' '); n=0; } } putchar(c); } // out3のn++; を 最後のputchar(c);の直前に移したものが // 次の図6.9(d)のプログラムout4と等しい。 // 但し、最初(in==0)のときはn==0なので、 // if(ln==0){xxx} else {if(n>=3){yyy}} は // if(ln==0){xxx} if(n>=3){yyy} と等価になる。 // out3とout4では、nの判断をするときのnの値は同じになるから // (out3では2回目以降の呼出しでの直前に加算し、out4では // 1回目以降の呼出しの最後に加算するため、nの判断(いずれも // 2回目以降)時点でのnの値はどちらも同じである。 // // 従って、out3とout4は等価である。 void out4(int c) { static int ln=0, cl=0, n=0; if(c==NULL) { printf("\n"); return; } if(ln==0) printf("%3d ", ++ln); if(n>=3) { cl++; if(cl>=4) { printf("\n%3d", ++ln); cl=0; } putchar(' '); putchar(' '); n=0; } n++; putchar(c); } // 以上