这里用局部静态变量对吗?

《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();
    }

}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值