《C陷阱与缺陷》3.6节“边界计算与不对称边界”中最后一个例子(第52页至57页),按照书上的代码编译生成的程序不能正确实现“flush()”函数的功能。
本来期望打印内容是(以打印42个整数为例):
1 6 11
2 7 12
3 8 13
4 9 14
5 10 15
-----------------------------
16 21 26
17 22 27
18 23 28
19 24 29
20 25 30
-----------------------------
31 36 41
32 37 42
flush()...
33 38
34 39
35 40
-----------------------------
但是用书上的代码,会重复打印最后一页两行两列的内容:
31 36 41
32 37 42
31 36
32 37
33 38
34 39
35 40
-----------------------------
只要将print()中的 row 改为全局变量,并且把flush()中的row的声明和初始化为0的代码去掉才能实现期望的正确输出。
要按说,这本书是C语言经典之作,印刷次数很多,不可能有这种错误的。也许是我看走眼了?
不管了,先把我认为正确的代码记下来再说。
#include <stdio.h> #define NROWS 5 #define NCOLS 3 #define BUFSIZE (NROWS *(NCOLS - 1)) int buffer[BUFSIZE]; int *bufptr; static int row = 0; void printnum(int num); void printnl(void); void printpage(void); void print(int n); void flush(void); int main() { int i; int cnt= 42; bufptr = buffer; for(i=0; i<cnt; i++) print(i+1); //getch(); printf("\nflush()...\n"); flush(); return 0; } /********************************************/ void printnum(int num) { printf("%2d\t", num); } /********************************************/ void printnl(void) { printf("\n"); } /********************************************/ void printpage(void) { printf("\n-----------------------------\n"); } /********************************************/ void print(int n) { if(bufptr == &buffer[BUFSIZE]){ //static int row = 0; int *p; for(p = buffer+row; p < bufptr; p += NROWS) printnum(*p); printnum(n);//打印当前行的最后一个元素 printnl(); if(++row == NROWS){ printpage(); row = 0; bufptr = buffer; } } else{ *bufptr++ = n; //printf("[]=%d\n", n); } } /********************************************/ void flush(void) { //int row; int k = bufptr - buffer; if(k > NROWS) k = NROWS; if(k > 0){ for (/*row=0*/; row < k; row++){ int *p; for(p = buffer + row; p < bufptr; p += NROWS) printnum(*p); printnl(); } printpage(); } }