《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();
}
}
分享到:
相关推荐
- **静态变量**: 在程序多次调用过程中保持原有的赋值状态不变。 - **变量作用范围**: 通过`static`关键字限定变量的可见性范围。 - **静态存储方式**: 改变变量的存储位置,使之在整个程序运行期间都存在。 - **...
c++例程:对局部静态变量有效域进行验证
经过长时间学习VB.NET局部静态变量,于是和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西。VB.NET能够实现很多C#不能做到的功能,如When语句、Optional参数、局部Static变量、对象实例访问静态...
- 设计和使用访问静态变量的函数时,需考虑重入问题,因为静态变量都位于静态数据存储区,全局可见。 - 需要一个可重入的函数时,应避免在函数中使用`static`变量,以免出现内部存储器问题。 - 当函数返回值为指针...
变量类型是编程语言中非常重要的一个概念,全局变量、局部变量、静态变量都是程序员经常使用的变量类型,但是这些变量类型之间的区别和联系却经常让人感到困惑。今天我们将详细地探讨这些变量类型之间的区别和联系,...
标题中的“1变量简单小程序VC局部静态变量”指的是在Visual C++(简称VC)编程环境中,使用C++语言编写的一个小型程序,该程序涉及到单个变量的运用,并且重点讲解了局部静态变量的概念和用法。局部静态变量是C++中...
全局变量、局部变量、静态全局变量、静态局部变量这四种变量类型,各自拥有不同的作用域和生命周期,它们之间的区别对于编写高效、可维护的代码至关重要。 ### 全局变量(Global Variable) 全局变量是在所有函数...
python局部变量全局变量-静态方法-实例变量静态变量代码解析。
### static静态局部变量的妙用 #### 一、引言 在软件开发和程序设计领域,合理运用各种语言特性能够显著提升代码的质量与效率。其中,`static`关键字就是一个非常实用的功能,在C/C++等语言中有着广泛的应用场景。...
3. 作用域:对于局部静态变量,其作用域仅限于定义它的函数内部;而对于全局静态变量,其作用域为整个源文件。 现在,让我们来看如何利用静态变量来计数函数的访问次数。假设我们有一个函数`countAccess()`,我们想...
本文将深入探讨静态变量(Static)和局部变量(Local Variable)的差异,通过实例帮助开发者更好地理解它们的用法和特性。 ### 1. 静态变量(Static) 静态变量在函数或过程中声明,其特点是即使函数或过程执行...
与常规的局部变量不同,静态变量的生命周期跨越整个过程或函数调用,而不是每次调用时重新初始化。例如: ```vb Sub MyProcedure() Static counter As Integer counter = counter + 1 Debug.Print "Counter: " &...
全局变量、局部变量、静态变量三者的区别。
C#中静态变量的使用 C# 中静态变量的使用是指在 C# 语言中使用静态变量的方法和技术。本文将详细介绍静态变量与非静态变量的区别、静态变量的使用方式、静态构造函数的使用等方面的知识点。 一、静态变量与非静态...
- **注意事项**: 静态变量有助于减少全局变量的使用,提高程序的可维护性。 #### 二、存储空间分配 - **全局变量**和**静态全局变量**: - **位置**: 静态存储区(数据段)。 - **特性**: 在程序的整个运行过程中都...
以下是关于Java成员变量、局部变量、静态变量以及成员方法和全局方法的基本概念和区别的详细阐述。 1. 成员变量(Member Variables): 成员变量是类的一部分,它们定义了对象的状态。它们可以是实例变量(非静态...
静态变量分为静态局部变量和静态全局变量。静态局部变量只在函数首次调用时初始化,之后每次调用函数时,其值会保留,不会被重置。静态全局变量只在定义它的源文件内可见,避免了全局变量的命名冲突,且其生命周期...
- **全局变量和静态变量**:如果未手动初始化,则由编译器自动初始化为0。 - **局部变量**:如果不进行初始化,则其值是不确定的,具体取决于编译器的实现细节。 #### 五、示例分析 下面通过一个具体的代码示例来...
相对于局部静态变量,全局静态变量指的是在函数外部定义的全局变量,它同样具有静态存储的特性,不过,全局静态变量的使用并不像局部静态变量那样频繁。原因在于: 1. 全局变量本身就具有静态存储特性,一旦创建,...