文件管理 · 2022年9月16日

设计型文件编程1|C语言课程设计写一个“文件型数据库”的分析和设计咋写从何下手写些什么

1. 帮忙用C语言遍一个大型程序设计,要求如下:

对我来说也太难了

2. 设计一个程序,要求新建一个文件“hello”,利用write函数将“linux下c软件设计”字符串写入该文件。

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>int main(){ int len = 0; int fp = 0; char text[ 20 ] = {'\0'}; char list[ 121 ] = "Linux下c软件设计"; fp = open( "hello", O_WRONLY ); len = sprintf( text, "%s" , list ); write( fp, text, len ); close( fp ); return 0;}———-谢谢采纳

3. C++语言程序设计(编程)

计算函数(递归)如下void fu(int *a,int i){ if (i>3) { fu(a,i-1); } else if (i==3) { a[i]=a[0]+a[1]+a[2]; }a[i]=a[i-1]+a[i-2]+a[i-3];}

4. 《设计文档》怎么写

1.设计目的:求素数素数就是仅能衩1和它自身整除的整数。判定一个整数n是否为素数就是要判定整数n能否被除1和它自身之外的任意整数整除,若都不能整除,则n为素数。程序设计时i可以从2开始,到该整数n的1/2为止,用i依次去除需要判定的整数,只要存在可以整除该数的情况,即可确定要判断的整数不是素数,否则是素数。2.参数设置:(1)范围:1000以内(2)3.设计步骤:(1)编程、调试实现设计要求(2)运行,观察显示结果(3)验算4.操作方法:(1)(2)5.预期结果:显示1-1000内的所有素数//求素数#include<stdio.h>void main(){ int i,j,sum=0; for(i=2;i<=1000;i++) { for(j=2;j<i;j++) if(i%j==0) break; if(i==j) printf("%5d",i); }}

5. 如何自己编写一个程序

编程是一项系统而繁琐的工作,不仅需要程序员有一定的基础,还需要良好的编程习惯和风格。良好的编程习惯和风格不仅可以使程序代码更容易阅读和修改,更重要的是可以使程序结构更加合理,有助于提高程序的执行效率。下面是我编程的一些经验,供大家参考。

设计顺序

我们刚开始学编程的时候,要写一个程序,总是先做一些思路,然后边写代码边调试。这种方法一般只适用于非常小的程序。根据软件工程的特点,按照这种方法设计所有的程序是不合理的。

其实设计过程就像我们盖高楼一样。首先,我们要设计图纸,然后开始施工。因此,对于个人编写程序,应该遵循以下步骤:

1.问题分析:通过编程的方式系统地分析我们想要解决的问题,了解程序是做什么的,想要达到什么样的效果。

2.结构设计:即设计程序的整体框架,设计我们需要使用的模块,绘制流程图。

3.用户界面设计:在这里,我们应该设计一个输入输出界面,用于与用户进行交互。

4.代码设计:在这一步,我们将编写代码。

5.调试:处理程序中正在发生或可能发生的各种错误。

6.维护:一般来说,维护就是升级程序,修改原来的错误。

对于上面的步骤,我想大部分人都认为代码设计是最重要的,但是如果程序的结构还没有明确,我们写代码的时候就会出现混乱。一个程序的性能主要取决于它的合理结构。因此,在程序设计中,我们应该尽可能地注意这一点,从而使我们的程序更加完善。

设计环境

好的编程环境可以防止我们写程序时各种资源的无序,避免资源的流失。建议您在存放源程序的目录下建立一个“程序”文件夹;然后用你要写的程序名和版本名创建一个文件夹,用来存放整个源程序和各种资源;最后分别建立几个文件夹,“文档”:用来存放程序文档,包括流程图等。“资源”:用于存储图片、声音、电影等资源;“调试”:用于存储调试程序。“版本”:用于存储最终版本的程序。

例如,如果我们要制作一个名为“english”的1.0版英语学习软件,那么我们的编程环境中应该存在以下文件夹:

[drive]:\?\程序 英语1 调试

[驱动器]:\?\程序 英语1 文档

[驱动器]:\?\程序 英语1 资源

[驱动器]:\?\程序 英语1 发布

另外,最好建立一个专门的文件夹来存放各种模块,这样代码就可以重用了。这样我们每次写程序都不用重写所有模块,编程速度会大大提高。

设计技巧

如果代码写得乱七八糟,程序就不容易被阅读和修改。因此,编写代码时应注意以下几点:

(1)注释:虽然写注释需要一定的时间,但是在阅读和修改代码的时候会节省很多时间。所以建议你在定义函数的时候,把函数写在函数的第一行,把函数的参数解释在一行,在每个变量的定义语句后面给函数加注释。

(2)变量和函数的命名:每个程序都会用到大量的变量和函数。如果随意给变量和函数命名,每次使用时都必须在变量或函数的定义语句中找出变量和函数的数据类型和名称,随意命名会导致变量和函数的重复定义。

建议您使用匈牙利命名法。方法是:每个变量或函数的开头以其数据类型的缩写命名,然后加上代表这个变量或函数的功能的英文单词缩写,形成变量或函数的名称。比如定义整数变量count进行计数,其定义语句为C c++:inti count;基本:dim icount为整数.这种定义既能有效避免变量和函数的混淆和重复定义,又能保证数据类型的匹配。

(3)控件命名:如果在windows下编程,可能会用到很多控件。如果不严格管理控件名,会造成很大程度的混乱。因此,建议在给控件命名时,使用控件类型的缩写和表示该控件功能的英文单词的缩写来构成该控件的名称。例如,如果要命名一个要删除的按钮控件,控件名称可以命名为cmddel。

不是每个人都能成为顶尖的程序员,但我们都在程序员的道路上不断进步,追求更完美、更专业的程序。你不妨改革一下你的程序,你会从中感受到很多好处。

6. C语言程序设计 设计一个程序,输入三个整数,求它们的和及平均数。

运行结果

7. 如何设计一个小型文件系统,提供创建、打开、读、写、关闭、删除文件的功能。

这是一个简单的程序设计问题,学过c的人都会。在c 里面提供了功能强大的文件管理函数,fopen ,fread,fwrite,fclose,等,多看一下,自己就会了

8. C语言程序设计

(一)“项目驱动”式教学目前最著名、最有影响、应用最广泛的windows、linux和UNIX三个操作系统都是用C语言编写的。0S是计算机系统(由软硬件两个子系统构成)的核心和灵魂,它是软件中最庞大最复杂的系统软件。既然如此庞大复杂的0S都可以用c语言编写,从狭义而言,还有什么系统软件和应用软件不能用c语言编写呢?由此可以肯定的说,c语言是一门十分优秀而又重要的语言。c语言程序设计是过程性程序设计语言,它的发展贯穿了计算机发展的历程,它蕴含了程序设计的基本思想,囊括了程序设计的基本概念,所以它是理工科高等院校的一门基础课程。从市面上有关c语言的书籍和高等院校采用的教材来看,它们有一个共性,那就是:脱离了实际应用(全是小打小闹的小例子),纯粹的过程性程序设计,没有软件工程思想的体现,没有一定程序设计风格,仅仅是为了让大家明白什么是c语言而已。高等院校开设c语言程序设计的目的是让学生对程序设计有个入门,有个直观的理解,同时为其他后续课程作铺垫。但是如果教学仅仅以此为目的,那么教学本身就效果而言是个大大的失败。大家知道,在商业上讲究唯利是图,“利”是商业追求的目标,离开了“利”经商,则商无动力,其结果是必败无疑。在c语言程序设计教学当中,教师应该把“唯用是图”作为教学的首要目标。如果抛开了实际应用进行程序设计教学,就是纸上谈兵,就是“说明书”式的教学。印度的程序设计课程采用“事件驱动式”教学,我认为在中国的c语言程序设计教学中应该采用“项目驱动式”教学。“项目驱动式”教学就是以项目为目的,以c语言理论教学为过程,最终能用c语言设计项目,实现项目的要求。“项目驱动式”教学的关键在于培养学生“如何做什么”和“可以干什么”。一个项目就是一个工程,在“项目驱动式”教学中,首先应该让学生简单了解什么是软件工程思想,其次在c语言理论教学过程中,让学生懂得面向对象的程序设计的风格,最后引导他们来设计项目。(二)“项目驱动”式教学应注意的问题1.c语言程序设计教学要帮助学生树立面向工程的观点在计算机行业中,软件是通过人们的智力活动、把知识与技术转化成信息的一种产品。软件的设计已经用工程的观念来进行管理。软件设计工作被当作一项系统工程来对待。软件的的生存周期一般可分为以下阶段:问题定义、可行性研究、需求分析、概要设计、详细设计、编码、测试、运行与维护。我们不难看出软件工程的复杂程度是很大的。理工科高等院校把c语言作为一门基础课程,也是为了给社会培养信息技术人才。众所周知,养成一个好的习惯是非常重要的,所以c语言程序设计作为大多数工科院校学生接触的第一门程序设计语言(有的院校讲pascal),就应该让学生树立正确的观点。那么当前的程序设计教学也必须以切合将来软件工程开发的实际需要为第一目标,使学生在学习程序设计的初级阶段就树立正确的软件工程观点。这样做不仅可以为学生将来从事计算机应用设计打下良好的基础,而且有利于培养学生分析问题的完备性,以及统筹全局,协调关系的基本素质。2.理论教学应从单一的“结构化程序设计”向“结构化与面向对象并举”转变“结构化程序设计”方法是程序设计的基础,必须让学生掌握得坚实可靠。结构化程序设计的过程是培养学生思维能力的过程,在教学中经常发现有些学生的思维混乱。这些都是缺乏思维训练的结果。结构化程序设计的训练不仅可以让学生养成良好的程序设计习惯,而且可以有效地培养学生思维的条理性和逻辑性。所以在授课过程中要注意讲解结构化程序设计的思想时应突出两点:(1)程序的质量首先取决于它的结构。(2)程序设计的基本方法是自顶向下地逐步求精和模块化。在c程序教学过程中,越到后面的章节,学生越会产生设计程序逐渐变难的感觉,这是不符合逻辑的一种怪现象。按照常理,C语言学的越多,说明你的程序设计知识越多,设计起程序来应该更加得心应手,那么出现这种现象的原因何在呢?当然该问题的出现的原因是多方面的,但是其中最重要的一点就是长期以来程序设计的观念不是以如何处理好对象为出发点,而是以如何使用好语言为基本点。受这种思想的影响,我们的程序设计教学大多数不是以如何解决好问题为重点,而是以讲解语法规则和语句格式为重点,是“说明书”式的教学。这样做造成的结果就是见到一个程序后学生首先想到是该用哪条语句,而不是思考怎样合理的解析。要切实解决这个问题,首先应该改变程序设计的观念。“面向对象程序设计”思想是目前最为流行、极为实用的一种程序设计方法,但是让学生直接接触“面向对象程序设计”,肯定不能对程序设计打下牢固的基础。“结构化与面向对象并举”是现代计算机程序设计的发展趋势,应该认真探索研究,让学生有一个较为轻松的学习过程。程序设计的实质就是编写处理对象的过程,所以将c与c++有机的融为一体的教材应该是首选教材,在教学过程中,我们应该从社会发展的角度进行探索研究,将目前最为流行又极为实用“面向对象程序设计”思想融合到c语言教学中。3.c语言教学应培养学生良好的程序设计风格具有良好的设计风格应该是程序员所具备的基本素质,在实际的项目中程序员往往都有自己的一些编程风格。目前95%以上的程序设计书籍不注重程序设计风格问题,这导致了很多学生没有良好的程序设计风格,在他们刚刚毕业踏入社会时,如果周围的同事没有良好的编程风格,那么很难通过环境来使自己提高这方面的素质,即使有提高也不容易比较全面的提高。因此在学生接触的第一门程序设计语言教学中,就应该培养学生良好的程序设计风格,使他们一进工作环境就具备这个素质。Pascal设计者N.Writh教授十分重视程序设计风格的养成,他坚信“教给学生们以表达他们思维的语言会深深地影响他们思维和创造发明的习惯,而正是这些语言本身的混乱直接影响着学生们的程序设计的风格”,他这里所指的“这些运用”是当时那些主要用于程序设计教学的计算机语言。对学生来讲,一开始就强调程序设计风格很有必要,良好的程序设计风格不仅有助于提高程序的可靠性、可理解性、可测试性、可维护性和可重用性,而且也能够促进技术的交流,改善软件的质量。所以培养良好的程序设计风格对于初学者来说非常重要。程序设计风格,实际上是指的是编码风格。在教学过程中应从源程序文档化,数据说明的原则,输入/输出方法这三个方面培养学生的编码风格,进而从编码原则探讨提高程序的可读性、改善程序质量的方法。(1)源程序文档化。编码的目的是产生程序,但是为了提高程序的可维护性。源代码是需要实现文档化的。源程序文档化包括选择标识符(变量和标号)的名字、安排注释以及标准的书写格式等。①选择标识符的命名规则。标识符包括模块名、变量名、常量名、标号名、子程序名等。这些名字应能反映它所代表的实际东西,应有一定实际意义,使其能顾名思义。另外在模块名、变量名、常量名、标号名、子程序名中使用下划线是一种风格。使用这一技术的一种广为人知的命名规则就是匈牙利命名法(变量类型由一个或两个字符表示,并且这些字符将作为变量名的前缀)。当然使用匈牙利命名法与否都没有错误,重要的是要保持一致性——在整个程序中使用相同的命名规则。这就是说,如果你在一个小组环境中编程,你和其他小组成员应该制定一种命名规则。并自始至终使用这种规则。如果有人使用了别的命名规则,那么集成的程序读起来将是很费劲的。此外,你还要与程序中用到的第三方库(如果有的话)所使用的风格保持一致。如果可能的话,你应该尽量使用与第三方库相同的命名规则,这将加强你的程序的可读性和一致性。②注释。程序中的注释是程序设计者与程序阅读者之间通信的重要手段。注释能够帮助读者理解程序,并为后续测试维护提供明确的指导信息。因此,注释是十分重要的,大多数程序设计语言提供了使用自然语言来写注释的环境,为程序阅读者带来很大的方便。注释分为功能性注释和序言性注释。a.功能性注释。功能性注释在源程序中,用以描述其后的语句或程序段是在做什么工作,也就是解释下面要“做什么”,而不是解释下面怎么做。对于书写功能性注释,要注意以下几点:第一描述一段程序,而不是每一个语句。第二利用缩进和空行,使程序与注释容易区别。第三注释要准确无误。b.序言性注释。序言性注释通常位于每个程序模块的开头部分,它给出程序的整体说明,对于理解程序具有引导作用。有些软件开发部门对序言性注释做了明确而严格的规定,要求程序编制者逐项列出。有关内容包括:程序标题;有关该模块功能和目的的说明;主要算法;接口说明:包括调用形式,参数描述,子程序清单;有关数据描述;模块位置(在哪一个源文件中,或隶属于哪一个软件包);开发简历:模块设计者、复审考、复审日期。③用标准的书写格式。源程序清单的书写建议采用以下几点:a.每行只写一条语句;b.用分层缩进的写法显示嵌套结构层次,这样可使程序的逻辑结构更加清晰,层次更加分明。c.书写表达式时适当使用空格或圆括号作隔离符。d.在注释段周围加上边框;e.注释段与程序段、以及不同的程序段之间插入字行;(2)数据说明采用的原则。在编写程序时,要注意数据说明的风格。数据说明的次序如果规范,将有利于测试,排错和维护。首先说明的先后次序要固定,例如,按常量说明、简单变量类型说明、数组说明用数据块说明、所有的文件说明的顺序说明。当然在类型说明中还可进一步要求,例如按如下顺序排列:整型量说明、实型量说明、字符量说明、逻辑说明。其次当用一个语句说明多个变量名时,应当对这些变量按字母的顺序排列。最后对于复杂数据结构,应利用注释说明实现这个数据结构的特点。(3)输入/输出方法。输入/输出的方式和格式应当尽量避免因设计不当给用户带来的麻烦。这就要求,源程序的输入/输出风格必须满足能否为用户接受这一原则。所以在设计程序时,应考虑以下原则:输入数据时,要使输入的步骤和操作尽可能简单,应允许使用自由格式输入;应允许缺省值;对输入的数据要进行检验,以保证每个数据的有效性。(三)结束语在教学过程中,我们让学生设计一个程序模拟体育彩票的销售与对奖的过程,取得了良好的效果。他不仅启发和诱导了学生独立思考、积极思维的主动性,而且充分调动了学生学习的自觉性和积极性,使学生融会贯通地掌握了所学知识,提高了分析问题和解决实际问题的能力。搞好c程序设计的教学工作涉及的因素很多,如果以项目来驱动教学,首先让学生树立面向工程的思想,其次把教学从单一的“结构化程序设计”向“结构化与面向对象并举”转变,最后特别要培养学生养成良好的编码风格,从而使他们学会能够“干什么”,那么我们认为教学目的就达到了。 我可以帮助你,你先设置我最佳答案后,我网络Hii教你。

9. C语言课程设计。写一个“文件型数据库”的分析和设计。咋写从何下手写些什么

文件型数据库,通常用文本文件实现。只要是些字符串,里面的结构自己定义。比如一个人名,年龄,性别。里面文本文件可以是。张三,21,男李四,20,女到你读文本时,就可以通过检测 ‘,’ 号,识别单个人的信息, 检测 分行符“\n”,识别下一个人的信息,,,具体结构可以自己写,,你知道结构后,编程时识别一下就行了

10. 急!关于VB,简单的程序设计

分类:电脑IT 四、数组中常见错误和注意事项1.静态数组声明下标出现变量 n = InputBox("输入数组的上界") Dim a(1 To n) As Integer2.数组下标越界 引用的下标比数组声明时的下标范围大或小。 Dim a(1 To 30) As Long, I as integer a(1) = 1: a(2) = 1 For i = 3 To 30 a(i) = a(i – 2) + a(i – 1) Next I3.数组维数错 数组声明时的维数与引用数组元素时的维数不一致。 Dim a(3, 5) As Long a(I)=104.Aarry函数使用问题 只能对Variant 的变量或动态数组赋值。5.获得数组的上界、下界 UBound 、Lbound函数1.Dim数组声明有时用户为了程序的通用性,声明数组的上界用变量来表示,如下程序段: n=InputBox("输入数组的上界") Dim a(1 To n)As Integer程序运行时将在Dim语句处显示"要求常数表达式"的出错信息。即Dim语句中声明的数组上、下界必须是常数,不能是变量。解决程序通用的问题,一是将数组声明的很大,这样浪费一些存储空间;二是利用动态数组,将上例改变如下: Dim a()As Integer n=InputBox ("输入数组的上界") ReDim a(1 To n) As Integer2.数组下标越界引用了不存在的数组元素,即下标比数组声明时的下标范围大或小。例如,要形成有如下30项的斐波那契数列:1,1,2,3,5,8,13,21,34,…,317811,514229,832040正确的程序段如下: Dim a(1 To 30) As Long, i%若将For i=3 To 30改为For i=1 To 30,程序运行时会显示"下标越界"的出错信息,因为开始循环时i=l,执行到循环体语句a(i)=a(i-2)+a(i-1),数组下标i-2、i-1均小于下界1。同样若将上例:a(i)=a(i-2)+a(i-1)语句改为:a(i+2)=a(i)+a(i+1)。程序运行时也会显示"下标越界"的出错信息,这时是数组下标大于上界30。3.数组维数错数组声明时的维数与引用数组元素时的维数不一致。例如,下程序段为形成和显示3×5的矩阵: Dim a(3,5) As Long For i=1 To 3 For j=1 To 5 a(i)=i*j Print a(i);""; Next j Print Next i程序运行到a(i)=i*j语句时出现"维数错误"的信息,因为在Dim声明时是二维数组,引用时的一个下标。4.Array函数使用问题Array函数可方便地对数组整体赋值,但此时只能声明Variant的变量或仅由括号括起的动态数组。赋值后的数组大小由赋值的个数决定。例如,要将1,2,3,4,5,6,7这些值赋值给数组a,表2.5.1列出了三种错误及相应正确的赋值方法。表2.5.1 Array函数表示方法错误的Array函数赋值 改正的Aarry函数赋值 Dim a(1 To 8)a=Array(1,2,3,4,5,6,7,8) Dim a( ) a=Array(1,2,3,4,5,6,7) Dim a As Integer a=Array(1,2,3,4,5,6,7) Dim a a=Array(1,2,3,4,5,6,7) Dim aa()=Array(1,2,3,4,5,6,7) Dim a a=Array(1,2,3,4,5,6,7)5.如何获得数组的上界、下界Array函数可方便地对数组整体赋值,但在程序中如何获得数组的-上界、下界,以保证访问的数组元素在合法的范围内,可使用UBound和LBound函数来决定数组访问。在上例中,若要打印a数组的各个值,可通过下面程序段实现:For i=Lbound(A) To Ubound(A) Print a(i)Next i6.给数组赋值VB6.0提供了可对数组整体赋值的新功能,方便了数组对数组的赋值操作。但真正使用不那么方便,有不少限制。数组赋值形式如下:数组名2=数组名1我们就此形式作讨论:这里的数组名2,实际上在前面的数组声明时,只能声明为Variant的变量,赋值后的数组2的大小、维数、类型同数组名1;否则,若声明成动态或静态的数组,例如:Dim数组名2()或Dim数组名2 (下标)程序在运行到上述赋值语句时显示"不能给数组赋值"的出错信息。所以,为了程序的安全、可靠,建议读者还是忍痛割爱,少用VB6.0的这一新功能,使用传统的循环结构来给数组赋值。基于此原因,我们也就在教程中不作展开。五、过程中常见错误和注意事项1.程序设计算法问题该章程序编写难度较大,主要是算法的构思有困难,这也是程序设计中最难学习的阶段。经验告诉每一位程序设计的初学者,没有捷径可走,多看、多练、知难而进。上机前一定要先编写好程序,仔细分析、检查,才能提高上机调试的效率。每当一个程序通过艰苦的努力调试通过时,那苦尽甘来的喜悦令你一言难尽。2.确定自定义的过程是子过程还是函数过程实际上过程是一个具有某种功能的独立程序单位,供多次调用。子过程与函数过程的区别是前者子过程名无值,后者函数过程名有值。若过程有一个返回值,则习惯使用函数过程;若过程无返回值,则使用子过程,若过程返回多个值,一般使用子过程,通过实参与形参的结合带回结果,当然也可通过函数过程名带回一个,其余结果通过实参与形参的结合带回。3.过程中形参的个数和传递方式的确定对初学者,在定义过程时不能确定形参的个数和传递方式。过程中参数的作用是实现过程与调用者的数据通信。一方面,调用者为子过程或函数过程提供初值,这是通过实参传递给形参实现的,另一方面,子过程或函数过程将结果传递给调用者,这是通过地址传递方式实现的,因此,决定形参的个数就是由上述两方面决定的。对初学者,往往喜欢把过程体中用到的所有变量作为形参,这样就增加了调用者的负担和出错概率,也有的初学者全部省略了形参,则无法实现数据的传递,既不能从调用者得到初值,也无法将计算结果传递给调用者。VB中形参与实参的结合有传值和传地址两种方式。区别如下:(1)在定义形式上前者在形参前加即ByVal关键字。(2)在作用上值传递只能从外界向过程传入初值,但不能将结果传出,而地址传递既可传入又可传出。 (3)如果实参是数组、自定义类型、对象变量等,形参只能是地址传递。4.实参与形参类型对应问题在地址传递方式时,调用过程实参与形参类型要一致。例如:函数过程定义如下: Public Function f!(x!) f=x+x End Function主调程序如下: Privme Sub Commandl_Click() Dim y% y=3 Print f(y) End Sub上例形参x是单精度型、实参y是整型,程序运行时会显示"ByRef参数类型不符"的编译出错信息。在值传递时,若是数值型,则实参按形参的类型将值传递给形参。例如:函数过程定义如下: Public Function f!(ByVal x%) f=x+x End Function主调程序如下: Priva~SubCommandI_Click() Dim y! Y=3.4 Print f(y) End Sub程序运行后显示的结果是6。5.变量的作用域问题局部变量,在对该过程调用时,分配该变量的存储空间,当过程调用结束,回收分配的存储空间,也就是调用一次,初始化一次,变量不保值,窗体级变量,当窗体装入,分配该变量的存储空间,直到该窗体从内存卸掉,才回收该变量分配的存储空间。例如,要通过文本框输入若干个值,每输入一个按Eeter键,直到输入的值为9999,输入结束,求输入的数的平均值。Private Sub Textl_Key Press(Key Ascii As Integer)Dim sum!,n%If KeyAscii=13 Then If Val(Text1)=9999 Then sum=sum/n Print sum Else Sum=sum+Text1 n=n+1 Text1=""End IfEnd IfEnd Sub该过程没有语法错,运行程序可输入若干个数,但当输入9999时,程序显示"溢出"的错误。原因sum和n是局部变量,每按一个键,局部变量初始化为0,所以会有上述错误产生。改进方法:将要保值的局部变量声明为Static静态变量或声明为窗体级变量。也可将要保值的变量在通用声明段进行声明为窗体级变量。6.递归调用出现"栈溢出"如下求阶乘的递归函数过程:Public Functionfac(n As Integer)As integerIf n=1 Then fac=1Else fac=n*fac(n-1)End IfEnd FunctionPrivate Sub Commandl_Click() '调用递归函数,显示出fac(5)=120Print "fac(5)";fac(5)End Sub当主调程序调用时,n的值为5时,显示120结果;当n的值为-5时,显示"溢出堆栈空间"的出错信息。实际上每递归调用一次,系统将当前状态信息(形参、局部变量、调用结束时的返回地址)压栈,直到到达递归结束条件。上例当n=5时,每递归调用一次,参数n-l,直到n=l递归调用结束,然后不断从栈中弹出当前参数,直到栈空。而当n=-5时,参数n-1为-6、压栈,再递归调用、n-1永远到不了n=l的终止条件,直到栈满,产生栈溢出的出错信息。所以设计递归过程时,一定要考虑过程中有终止的条件和终止时的值或某种操作,而且每递归调用一次,其中的参数要向终止方向收敛,否则就会产生栈溢出。六、常用控件常见错误和难点分析1.遗漏对象名称在VB程序设计时,初学者常犯的一个错误是遗漏对象名称,特别是在使用列表框时。例如,如果要引用列表框(List1)中当前选定的项目,Listl.list(Listlndex)是错误的。即使当前焦点在Listl上,VB也不是认为Listlndex是List l的属性,而是一个变量。所以正确的引用方式是:Listl. 1ist(Listl.Listlndex)。2.列表框的Columns属性列表框的Columns属性决定列表框是水平还是垂直滚动以及如何显示列中的项目。如果水平滚动,则Columns属性决定显示多少列,如表2.7.2所示。图2.7.1是一个水平滚动两列显示的列表框。在程序运行期间,该属性是只读的,也就是说,不能在运行时,将多列列表框变为单列列表框或将单列列表框变为多列列表框。表2.7.2 列表框的Columns属性列数 属 性0(默认值)1到n 项目安排在一列中,且列表框竖直滚动项目安排在多个列中,先填第一列,再填第二列……列表框水平滚动并显示指定数目的列3.域级验证域级验证是指输入到某独立域的数据的验证,在域级验证的过程中一般不考虑窗体一般其他域的内容。进行域级验证的合适时间是:(1)当往某域中输入某个键时,此时涉及键盘事件(KeyDown、KeyUp和KeyPress)。(2)当用户企图离开某域时,此时涉及CansesValidate属性和Validate事件。(3)当某域的内容发生变化时,此时涉及Change事件。CausesValidation属性和Validate事件通常是协同工作的。CausesValidate属性决定Validate事件是否发生。如果控件的CausesValidate属性为False,该控件的Validate事件永远不会发生。如果控件的CausesValidate属性为Tree,当焦点企图移到(还没有离开,也可以说离开之前)另一个CausesValidate属性为True的控件时,原控件的Validate事件发生:当焦点企图移到另一个CausesValidate属性为False的控件时,原控件的Validate事件暂时不发生,什么时候发生?直到焦点移到一个CausesValidate属性为True的控件上时才发生。例如,假定有如图2.7.2所示的程序。当焦点企图从Textl移到Text2时,Textl的Validate事件发生,同样当焦点企图从Text2移到Textl时,Text2的Validate事件发生。当焦点企图从Textl移到Text3时,TextI的Validate事件暂时没有发生,因为Text3的CausesValidate为False,然后如果焦点企图继续移动到Text2时,Textl的Validate事件才发生。图2.7.2 CausesValidate属性和Validate事件CausesValidate属性和Validate事件的这一特性常常应用在如图2.7.3所示的程序中。当在文本框中输入了无效数据时而又不知道如何输入有效数据时,用户往往选择Help命令寻求帮助或选择Cancel命令结束数据输入,此时不希望执行验证程序。因为如果执行验证程序且发现了无效数据,则无法选择Help或Cancel了,用户就这样被套住了。现在只要将文本框的CausesValidate属性设为True,命令按钮的CausesValidate属性为False,验证程序放在 Validate过程中,问题就解决了。在默认情况下,所有控件的CausesValidation属性都为Tree。图2.7.3 命令按钮的CausesValidate属性和Validate事件并不是所有的控件都有Validate事件。只有那些能用于输入数据的控件(如文本框、复选框、滚动条等)才有这个事件。Validate事件过程如下: Privme Sub object_Validate(Cancel As Boolean) … EndSub其中,当参数Cancel被设为Tree后,焦点将不会离开对象。如果要将实验七第1题改用Validate事件和CausesValidation属性实现数据验证,则应有如下的程序。Sub txtMath_Validate(Cancel As Boolean)If Val(txtMath.Text)<0 Or _Val(txtMath.Text)>100 Then Cancel=True End If End Sub1.窗体顶部菜单栏中的菜单项与子菜单中的菜单项的区别窗体顶部菜单栏中的菜单项与子菜单中的菜单项都是在菜单编辑器中定义的,但是它们是有区别的。(1)窗体顶部菜单栏中的菜单项不能定义快捷键,而子菜单中的菜单项可以有快捷键。(2)当有热键字母(菜单标题中"&"后的字母)时,按Alt+热键字母选择窗体顶部菜单栏中的菜单项,按热键字母选择子菜单中的菜单项(当子菜单打开时)。子菜单没有打开时,按热键字母无法选择其中的菜单项。(3)尽管所有的菜单项都能响应Click事件,但是窗体顶部菜单栏中的菜单项不需要编写事件过程。2.在程序中对通用对话框的属性设置不起作用在程序中对通用对话框的属性设置不起作用,多数情况是因为在弹出对话框后才进行属性设置。例如,下面的程序代码就存在这样的问题,改正方法是将弹出对话框语句放到最后,即把CommonDialogl.Action=l放在所有属性设置语句的后面。 CommonDialog1.Action=1 ConmaonDialog1.FileName="*.Bmp" CommonDialogl.InitDir="C:\Windows"CommonDialog1.Filter="Pictures(*.Bmp)|*.Bmp|All Files(*.*)|*.*"CommonDialog1.FilterIndex=13.在工程中添加现有窗体时发生加载错误在使用"工程"菜单中的"添加窗体"命令添加一个现存的窗体时经常发生加载错误,绝大多数是因为窗体名称冲突的缘故。例如,假定当前打开了一个含有名称为Forml的工程,如果想把属于另一个工程的Forml窗体装入则肯定会出错。[注意]窗体名与窗体文件名的区别。在一个工程中,可以有两个窗体文件名相同的窗体(分布在不同的文件夹中),但是绝对不能同时出现两个窗体名相同的窗体。4.实时菜单的创建实时菜单是由应用程序根据需要动态创建的。在VB中,常见的实时菜单是"文件"菜单,该菜单显示了最近所使用的工程。创建实时菜单必须结合控件数组,用Load语句创建菜单项,用UnLoad清除菜单项。创建实时菜单的步骤:(1)在菜单编辑器中建立样本菜单项样本菜单项的属性设置见表2.8.4所示。设置Index为0,表明样本菜单项是控件数组的一个元素,其下标为0。样本菜单项的Name属性是必须的,它将作为控件数组的名称。在下面假定数组名为NameArray。Visible可以设为True,设为False表示初始时该菜单项不可见。表2.8.4 实时菜单样本菜单项属性 Name Caption Index Visible设置值 必需的 可以没有 0 False(2)在程序中用Load语句创建菜单项例如,Load NameArray(1)创建一个新的菜单项(在控件数组中的下标为1,然后将其 Visible属性设置True,同时设置Caption属性。动态创建的菜单项继承了除了Index之外的绝大部分属性,所以要对Caption和Visible属性进行设置。另外,样本菜单项在菜单系统中的位置决定了新菜单项出现的位置。(3)为实时菜单项编写代码每个实时菜单项都是控件数组的一个成员,具有相同的名称,并且共享事件过程。下面是一个实时菜单项代码示例:SubNameArray_Click(Index As Integer)Select Case Index Case 0MsgBox("NameArmy(0)(样本菜单项) is clicked!") Case 1MsgBox("NameArray(1)(第一个实购菜单项) is clicked!") Case 2MsgBox("NameArray(2)(第二个实时菜单项) is clicked!")End SelectEnd Sub(4)删除实时菜单项尽管把Visible设为False,程序运行时实时菜单项不会显示,然而有时还是需要把实时菜单项从内存中销毁。删除实时菜单使用UnLoad语句。例如,LoadNameArray(1)。有关建立实时菜单的详细内容请参阅教程第4.3节。5.通用对话框的CancelError属性和Err对象当通用对话框的CancelError属性为True时,无论何时选择"取消"按钮,均产生 32755(cdlCancel)号错误,即将Err的Number属性设置为32755。Err是VB的一个系统对象,它记录了程序运行期间所发生的错误。Err对象的重要属性有Number(默认属性)和Description。当错误发生后,错误的生成者把错误号和有关错误的说明分别存放在Number和Description属性中。例如,当在 CancelError属性为True的通用对话框中选择"取消"按钮时,产生一个错误,Err对象的Number和Description属性将被设置为32755和"选择'取消'"。在程序运行期间,经常会发生各种各样的错误。有关错误处理的详细内容请参阅教程第 9.6节。下面是当程序产生cdlCancel错误时结束程序的运行。SubForm_ClickO CommonDialogl.CancelError=True On Error GoTo ErrorHandler CommonDialogl.Action=l ' 处理文件的语句 ErrorHandler: If Err.Number=cdlCancel Then End EndlfEnd Sub6.与窗体有关的事件在首次用Load语句将窗体(假定该窗体在内存中还没有创建)调入内存之时依次发生 Initialize和Load事件。再用UnLoad将窗体从内存中卸载时依次发生QueryUnLoad和Unload事件,再使用Set窗体名=Nothing语句解除初始化时发生Terminate事件。Initialize是在窗体创建时发生的事件。在窗体的整个生命周期中,Initialize事件只触发一次。用户可以将一个窗体装入内存或从内存中删除很多次,但窗体的建立只有一次。也就是说,在用Load语句将窗体装入内存时会触发Load事件,但并不一定触发Initialize事件。在用UnLoad语句卸载窗体后,如果没有使用Set窗体名=Nothing解除初始化,则在下次使用Load语句时不会触发Initialize事件,否则会引起Initialize事件。假定有Forml和Form2两个窗体,并且有下列事件过程:' Forml窗体事件过程Sub Form_Click()Debug.Print"窗体首次装入内存时发生的事件:"Load Form2Debug.Print"用Unload卸载窗体时发生的事件:"UnloadForm2Debug.Print "窗体第二次装入内存时发生的事件:"Load Form2Debug.Print "用Unload卸载窗体时发生的事件:"Unload Form2Debug.Print "用Set窗体名=Nothing语句解除初始化时发生的事件:"Set Form2=NothingDebug.Print "窗体第三次(解除初始化后)装入内存时发生的事件:"Load Form2End Sub'Form2窗体事件过程Sub Form_Initialize() Debug.Print"Initialize事件"End SubSub Form_Lond() Debug.Pnnt"Load事件"End SubSub Form_QueryUnload(Cancel As hteger, UnloadMode As Integer) Debug.Print"QueryUnload"End SubSub Form_Unlond(Cancel As Integer) Debug.Print"Unload"End SubSub Form_Terminate() Debug.Print"Terminate"End Sub当用户在Form1上单击时,在Debug窗口显示下列信息: 窗体首次转入内存时发生的事件: Initialize事件 Load事件 用Unload卸载窗体时发生的事件: Query Unload Unload 窗体第二次装入内存时发生的事件: Load事件 用Unload卸载窗体时发生的事件: QueryUnload Unload 用Set窗体名=Nothing语句解除初始化时发生的事件:Terminate 窗体第三次(解除初始化后)装入内存时发生的事件: Initialize事件 Load事件7.MouseDown、MOUSeUp和C1ick事件发生的次序当用户在窗体或控件上按下鼠标按钮时MouseDown事件被触发,MouseDown事件肯定发生在MouseUp和C1ick事件之前。但是,MouseUp和Click事件发生的次序与单击的对象有关。当用户在标签、文本框或窗体上作单击时,其顺序为:(1)MouseDown(2)MouseUp(3)Click当用户在命令按钮上作单击时,其顺序为:(1)MouseDown(2)Click(3)MouseUp当用户在标签或文本框上作双击时,其顺序为:(1)MouseDown(2)MOuseUp(3)Click(4)DblCUck(5)MouseUp七、文件常见错误和难点分析1.文件系统的三个控件不能产生关联也就是当驱动器改变时,目录列表框不能跟着相应改变;或者当目录列表框改变时,文件列表框不能跟着相应改变。要三个控件产生关联,使用下面两个事件过程: Private Sub Drivel_Change() Dirl.Path=Drivel.Drive End Sub Private Sub Dirl_Change() Filel.Path=Dirl.Path End Sub2.如何在目录列表框表示当前选定的目录在程序运行时双击目录列表框的某目录项,则将该目录项改变为当前目录,其Diirl. Path的值作相应的改变。而当单击选定该目录项时,Diirl. Path的值并没有改变。有时为了对选定的目录项进行有关的操作,与ListBox控件中某列表项的选定相对应,表示如下:Dirl.List(Dirl.Listlndex)3.当使用文件系统控件对文件进行打开操作时,显示"文件未找到"出错信息。例如,如下语句:Open Filel.Path+Filel.File Name For Input As#1当选定的目录是根目录,上述语句执行正确,而当选定的目录为子目录,上述语句执行时显示"文件末找到"出错信息。其中:Filel.Path表示当前选定的路径,Filel.File Name表示当前选定的文件,合起来表示文件的标识符。当选定的文件在根目录下(假定驱动器为C),Filel.Path的值为"C:\1",假定选定的文件名为"t1.txt",则Filel.Path+Filel.FileName的值为"C:\t1.txt"为合法的文件标识符。当选定的文件在子目录下(假定驱动器为C,子目录为my),Filel.Path的值为"C:\my" Filel.Path+Filel.FileName的值为"C:\my tl.txt",子目录与文件名之间少了一个"\"分隔符。为了保证程序正常运行,Open Filel.Path+Filel.FileNameForlnput As #1改为:Dun F$If Right(Filel.Path,1)"\" Then ' 表示选定的足根目录F=Filel.Path+Filel.FileNameElse ' 表示选定的是子目录,子目录与文件名之间加"\"F=Filel.Path+"\"+Filel.FileNameEnd IfOpen F For Input As # 14.Open语句中欲打开的名是常量也可以是字符串变量,但使用者概念不清,导致出现"文件未找到"出错信息如在从盘上读入文件名为"C:\my\t1.txt",正确的常量书写如下:Open "C:\my\t1.txt"For Input As#1 ' 错误的书写常量两边少双引号或正确的变量书写如下:Dim F$F="C:\my\t1.txt"Open F For Input As #1 ' 错误的书写变量F两边多了双引号5.文件没有关闭又被打开,显示"文件已打开"的出错信息如下语句:Open"C:\my\t1.txt" For Input As #1Print FOpen "C:\my\t1.txt" For Input As #1Print "2";F执行到第二句Open语句时显示"文件已打开"的出错信息。6.如何读出随机文件中的所有记录,但又不知道记录号。不知道记录号而又要全部读出记录,则只要同顺序文件的读取相似,采用循环结构加无记录号的Get语句即可,程序段如下: Do While Not EOF(1) Get #1, , j Print j; Loop随机文件读写时可不写记录号,表示读时自动读下一条记录,写时插入到当前记录后。