430 likes | 609 Views
Visual FoxPro 程序设计教程. 第 6 章. 数 组. 6.1 数组的概念. ● 数组与数组元素. ● 数组的维数. 6.2 使用数组. ● 数组的定义. 1. 数组的声明. 语法格式为: {DIMENSION | DECLEAR}〈 数组名 〉(〈 行数 〉[,〈 列数 〉] ). 教学进程. 2. 数组的赋值. 【 例 6-1】 随机产生 10 个两位整数,找出其最大值、最小值和平均值。. 设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。. (2) 编写代码。
E N D
第6章 数 组 6.1 数组的概念 ● 数组与数组元素 ● 数组的维数
6.2 使用数组 ●数组的定义 1. 数组的声明 语法格式为: {DIMENSION | DECLEAR}〈数组名〉(〈行数〉[,〈列数〉] ) 教学进程
2. 数组的赋值 【例6-1】随机产生10个两位整数,找出其最大值、最小值和平均值。 设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。 (2) 编写代码。 随机整数的生成由表单的Activate事件代码完成: PUBLIC a(14) ' 因为要在不同的过程中使用数组,故声明为PUBLIC p = "" FOR i = 1 TO 14 a(i) = INT(RAND() * 90) + 10 p = p + STR(a(i),3) + "," ENDFOR THISFORM.Label2.Caption = ALLT(LEFT(p, LEN(p) – 1)) THISFORM.Label3.Caption="最大值 = " THISFORM.Label4.Caption="最小值 = " THISFORM.Label5.Caption="平均值 = " 教学进程
求最大、最小以及平均值由“确定”按钮Command2的Click事件代码完成:求最大、最小以及平均值由“确定”按钮Command2的Click事件代码完成: min = 100 max = 10 s = 0 FOR i = 1 TO 14 IF a(i) > max max = a(i) ENDIF IF a(i) < min min = a(i) ENDIF s = s + a(i) 教学进程
Next THISFORM.Label3.Caption = "最大值 = " + STR(max,3) THISFORM.Label4.Caption = "最小值 = " + STR(min,3) THISFORM.Label5.Caption = "平均值 = " + STR(s / 14,6,2) “重置”按钮Command1的Click事件代码: THISFORM.Activate 最后是“关闭”按钮Command3的Click事件代码: RELEASE THISFORM 教学进程
● 数组的使用 1. 重新定义数组的维数 2. 数组变量的释放 使用RELEASE命令可以从内存中释放变量和数组。其语法是: RELEASE {〈变量列表〉|〈数组名列表〉} 教学进程
【例6-2】斐波那契(Fibonacci)数列问题。 Fibonacci数列问题起源于一个古典的有关兔子繁殖的问题:假设在第1个月时有一对小兔子,第2个月时成为大兔子,第3个月时成为老兔子,并生出一对小兔子(一对老,一对小)。 第4个月时老兔子又生出一对小兔子,上个月的小兔子变成大兔子(一对老,一对大,一对小)。第5个月时上个月的大兔子成为老兔子,上个月的小兔子变成大兔子,两对老兔子生出两对小兔子(两对老,一对中,两对小)… 这样,各月的兔子对数为:1,1,2,3,5,8,… 这就是Fibonacci数列。其中第n项的计算公式为: Fib(n) = Fib(n–1) + Fib(n–2) 教学进程
设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。 (2) 编写代码。 首先在表单的Load事件代码中声明全局变量数组F( ): PUBLIC F(1,2) F(1,1) = "Fib(1)" F(1,2) = 1 在表单的UnLoad事件代码中释放全局变量数组F( ): RELEASE F 在微调器控件Spinner1的InteractiveChange事件代码中改变数组的大小: n = THIS.Value DIME F(n,2) F(2,1) = "Fib(2)" F(2,2) = 1 FOR I = 3 TO n F(i,1) = "Fib(" + ALLT(STR(i)) + ")" F(i,2) = F(i–1,2) + F(i–2,2) ENDFOR THISFORM.List1.NumberOfElements = n 教学进程
表单运行结果如图6-5所示。 图6-5 求Fibonacci数列 教学进程
【例6-3】设有一个5×5的方阵,其中元素是由计算机随机生成的小于100的整数。求出:(1) 主对角线上元素之和;(2) 方阵中最大的元素。如图6-6所示。 图6-6 计算矩阵 教学进程
设计步骤如下: (1) 建立应用程序用户界面与设置对象属性 (2) 编写代码。 首先在表单的Load事件代码中声明数组: PUBLIC a(5,5) 方阵的生成由表单的Activate事件代码完成: FOR i = 1 TO 25 yes = 1 DO WHILE yes = 1 x = INT(RAND() * 100) yes = 0 FOR j = 1 TO i – 1 IF x = VAL(a(j)) yes = 1 && 如与前面的元素相同,则返回到Do循环 EXIT ENDIF 教学进程
ENDFOR ENDDO a(i) = STR(x,3) ENDFOR THISFORM.List1.NumberOfElements = 5 THISFORM.Text1.Value = "" THISFORM.Text2.Value = "" 在表单的UnLoad事件代码中释放全局变量数组a( ): RELEASE a 计算功能由“计算”按钮Command1的Click事件代码完成: s=0 FOR i=1 TO 5 s = s + VAL(a(i,i)) ENDFOR THISFORM.Text1.Value = s max = 0 教学进程
FOR I = 1 TO 5 FOR j = 1 TO 5 IF max < VAL(a(i,j)) max = VAL(a(i,j)) p = i q = j ENDIF ENDFOR ENDFOR THISFORM.Text2.Value = "A(" + STR(p,1) + "," + STR(q,1) + ")=" + STR(max,3) “重置”按钮Command2的Click事件代码: THISFORM.Activate 教学进程
● 数组数据的处理 1. 处理数组元素的函数 数组提供了一种快速排序数据的方法。如果数据保存在数组中,就可以很方便地对其进行检索、排序或其他各种操作。可以使用如下函数来处理数组元素: (1) 数组元素的排序——ASORT()。 (2) 数组元素的搜索——ASCAN()。 (3) 数组元素的删除——ADEL()。 (4) 数组元素的插入——AINS()。 (5) 数组元素的个数——ALEN()。 教学进程
【例6-4】由计算机随机生成10个互不相同的数,然后将这些数按由小到大的顺序显示出来。如图6-7所示。【例6-4】由计算机随机生成10个互不相同的数,然后将这些数按由小到大的顺序显示出来。如图6-7所示。 图6-7 排序 教学进程
设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。程序界面的建立与各控件属性的设置参见图6-7。 (2) 编写代码。 首先在表单的Load事件代码中声明数组: PUBLIC a(10) 随机整数的生成由表单的Activate事件代码完成: p="" FOR i = 1 TO 10 yes = 1 DO WHILE yes = 1 x = INT(RAND() * 100) yes = 0 FOR j = 1 TO i – 1 IF x = VAL(a(j)) yes = 1 && 如与前面的元素相同,则返回到Do循环 EXIT 教学进程
ENDIF ENDFOR ENDDO a(i) = STR(x,2) p = p + a(i) + ", " ENDFOR THISFORM.Label2.Caption = LEFT(p,LEN(p) –2) THISFORM.Label4.Caption = "" 编写“排序”按钮Command1的Click事件代码: asort(a) p="" FOR i = 1 TO 10 p = p + a(i) + ", " ENDFOR THISFORM.Label4.Caption = LEFT(p,LEN(p) –2) 编写“重置”按钮Command2的Click事件代码: THISFORM.Activate 教学进程
2. 与数据表记录进行数据交换的命令 用于数组与数据表记录之间进行数据交换的命令有: (1) SCATTER——将数据从当前记录复制到数组中去。 (2) GATHER——用来自数组的数据替换当前表中的数据。 (3) COPY TO ARRAY——从当前表向一个数组复制数据。 (4) APPEND FROM ARRAY——用来自数组的数据给当前表追加新记录。 教学进程
● 程序举例 【例6-5】使用数组来作为组合框的数据源。 设计步骤如下: (1) 设计表单界面。 选择新建表单,进入表单设计器。增加一个组合框Combo1、一个文本框Text1、一个复选框Check、两个标签和两个形状控件。 (2) 设置对象属性。 (3) 编写事件代码。 ● 编写表单事件代码: Load事件: PUBLIC a(9,3) a(1,1) = "曹植" a(1,2) = "三国" a(1,3) = "七步诗"+CHR(13)+CHR(13)+"煮豆燃豆萁,"+CHR(13)+"豆在釜中泣:"+CHR(13)+"‘本是同根生,"+CHR(13)+"相煎何太急!’" a(2,1) = "李白" a(2,2) = "唐代" 教学进程
a(2,3) = "望庐山瀑布"+CHR(13)+CHR(13)+"日照香炉生紫烟,"+CHR(13)+"遥看瀑布挂前川。"+CHR(13)+"飞流直下三千尺,"+CHR(13)+"疑是银河落九天。" a(3,1) = "杜甫" a(3,2) = "唐代" a(3,3) = "绝句"+CHR(13)+CHR(13)+"两个黄鹂鸣翠柳,"+CHR(13)+"一行白鹭上青天。"+CHR(13)+"窗含西岭千秋雪,"+CHR(13)+"门泊东吴万里船。" a(4,1) = "苏轼" a(4,2) = "宋代" a(4,3) = "题西林壁"+CHR(13)+CHR(13)+"横看成岭侧成峰,"+CHR(13)+"远近高低各不同。"+CHR(13)+"不识庐山真面目,"+CHR(13)+"只缘身在此山中。" a(5,1) = "李请照" a(5,2) = "宋代" a(5,3) = "绝句"+CHR(13)+CHR(13)+"生当作人杰,"+CHR(13)+"死亦为鬼雄。"+CHR(13)+"至今思项羽,"+CHR(13)+"不肯过江东。" 教学进程
a(6,1) = "林升" a(6,2) = "南宋" a(6,3) = "题临安邸"+CHR(13)+CHR(13)+"山外青山楼外楼,"+CHR(13)+"西湖歌舞几时休?"+CHR(13)+"暖风熏得游人醉,"+CHR(13)+"直把杭州当汴州。" a(7,1) = "马致远" a(7,2) = "元代" a(7,3) = "天净沙-秋思"+CHR(13)+CHR(13)+"枯藤老树昏鸦,"+CHR(13)+"小桥流水人家,"+CHR(13)+"古道西风瘦马。"+CHR(13)+"夕阳西下,"+CHR(13)+"断肠人在天涯。" a(8,1) = "于谦" a(8,2) = "明代" a(8,3) = "石灰咏"+CHR(13)+CHR(13)+"千锤万凿出深山,"+CHR(13)+"烈火焚烧若等闲。"+CHR(13)+"粉身碎骨浑不怕,"+CHR(13)+"要留清白在人间。" a(9,1) = "郑燮" a(9,2) = "清代" a(9,3) = "竹石"+CHR(13)+CHR(13)+"咬定青山不放松, 教学进程
"+CHR(13)+"立根原在破岩中。"+CHR(13)+"千磨万击还坚劲,"+CHR(13)+"任尔东西南北风。""+CHR(13)+"立根原在破岩中。"+CHR(13)+"千磨万击还坚劲,"+CHR(13)+"任尔东西南北风。" Activate事件: THISFORM.Combo1.Value = 1 THISFORM.Text1.Value = a(1,2) Destroy事件: RELEASE a ●编写Combo1的InteractiveChange事件代码: s = ASCAN(a,THIS.DisplayValue) THISFORM.Text1.Value = a(s+1) THISFORM.Refresh ●编写Check1的属性: THISFORM.Combo1.ColumnCount = IIF(THIS.Value=0,1,2) 教学进程
6.3 对象数组 ● 对象的引用与释放 【例6-6】在例3-7中使用对象变量。 在例3-7的基础上改写代码。 编写表单的Init事件代码: PUBLIC txt1,txt2 txt1 = THIS.Container1.Text1 txt2 = THIS.Container2.Text1 改写表单的Activate事件代码: txt1.SetFocus 编写表单的Destroy事件代码: txt1 = 0 txt2 = 0 RELEASE txt1, txt2 教学进程
●编写Command1的Click事件代码: txt2.Value=txt1.Value * ( 9 / 5 ) + 32 ●编写Command2的Click事件代码: txt1.Value = (txt2.Value - 32) * (5 / 9) ●编写文本框Text1的事件代码 GotFocus事件代码: THIS.SelStart = 0 THIS.SelLength = LEN(THIS.Text) InteractiveChange事件代码: txt2.Value = "" ●编写文本框Text2的事件代码 GotFocus事件代码: THIS.SelStart = 0 THIS.SelLength = LEN(THIS.Text) InteractiveChange事件代码: txt1.Value = ""
● 运行时创建对象 使用AddObject方法可以在程序的运行中向容器添加对象,其语法格式为: 〈容器对象名〉. AddObject(〈对象名〉,〈类名〉) 教学进程
● 程序举例 【例6-7】用“筛法”找1~100之间的全部素数。 “筛法”求素数表是由希腊著名数学家Eratost henes提出来的,其方法是:在纸上写出1~n的全部整数。如图6-10所示。 图6-10 1~100之间的全部整数
然后逐一判断它们是否素数,找出一个非素数就把它挖掉(筛掉),最后剩下的就是素数。具体做法是:然后逐一判断它们是否素数,找出一个非素数就把它挖掉(筛掉),最后剩下的就是素数。具体做法是: (1) 先将1挖掉; (2) 用2去除它后面的每个数,把能被2整除的数挖掉,即把2的倍数挖掉(如图6-11); 图6-11 开始用2作除数,将2的倍数挖掉
(3) 用3去除它后面的每个数,把3的倍数挖掉; (4) 分别用4,5…各数作为除数去除这些数后面的各数(4已被挖掉,不必再用4当除数,只需用未被挖掉的数作除数即可)。这个过程一直进行到除数为为止(如果不是整数就取其整数部分)。剩下的全是素数 设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。 (2) 编写程序代码。 编写表单的Destroy事件代码: Lab = 0 编写容器Container1的Init事件代码: PUBLIC Lab[10,10] FOR I = 1 TO 100 k = ALLT(STR(i)) THIS.AddObject('Lab&k','Label') Lab[i] = THIS.Lab&k ENDFOR
. FOR I = 1 TO 10 FOR j = 1 TO 10 WITH Lab[i,j] Left = 25*(j–1)+2 .Top = 20*(i–1)+2 .Height = 20 .Width = 25 .Visible = .T. .Caption = ALLT(STR((i–1)*10+j)) .Alignment = 2 .FontBold = .T. .FontName = 'garamond' ENDWITH ENDFOR ENDFOR
编写“开始”按钮Command1的Click事件代码: n = 100 Lab(1).Enabled = .F. FOR i = 2 TO SQRT(n) IF Lab(i).Enabled = .T. WAIT '现在开始将能被 '+ALLT(STR(i))+' 整除的整数筛去' ; WINDOW at 8,50 timeout 3 FOR j = I + 1 TO n IF Lab(j).Enabled = .T. IF j % I = 0 WAIT '将 '+ALLT(STR(j))+' 筛去' WINDOW at 8,50 timeout 0.3 Lab(j).Enabled = .F. ENDIF ENDIF ENDFOR ENDIF ENDFOR
a = MESSAGEBOX('剩下来的整数都是素数'+CHR(13)+'再作一遍吗?',4+48,'') IF a = 6 FOR I = 1 TO 100 Lab(i).Enabled = .T. ENDFOR ENDIF 编写“关闭”按钮Command2的Click事件代码: RELEASE THISFORM
【例6-8】奇数阶的幻方阵。如图6-14所示。 图6-14 3阶与7阶的幻方阵
设计步骤如下: (1) 建立应用程序用户界面。 (2) 设置对象属性。如表6-5所示。 (3) 编写程序代码。 首先在表单的Load事件代码中定义全局变量n用来存放所选择的幻方阵的阶数,定义全局变量数组Lab[1,1]用来存放显示幻方阵各个元素的标签组。 PUBLIC Lab(1,1), n 当然不能忘记在表单的DeSTORE事件代码中释放全局变量及数组: Lab = 0 RELEASE Lab, n 在表单的Activate事件代码中调用“布阵”按钮的Click事件代码: THISFORM.Command1.Click ●编写容器Container1的Init事件代码: n = THISFORM.Spinner1.Value dd = 230/n
dd = INT(dd+.5) DIME Lab[n,n] FOR i = 1 TO n*n k = ALLT(STR(i)) THIS.AddObject('label&k','Label') lab[i] = THIS.Label&k ENDFOR FOR i = 1 TO n FOR j = 1 TO n WITH lab[i,j] .Left = dd*(j–1)+2 .Top = dd*(i–1)+2 .Height = dd .Width = dd .Visible = .T. .Caption = "" .BackColor = RGB(255,255,255) .ForeColor = RGB(0,0,255)
.Alignment = 2 .BorderStyle = 1 .FontSize = dd*.6 ENDWITH ENDFOR ENDFOR THIS.Height = dd * n + 4 THIS.Width = dd * n + 4 ●编写“布阵”按钮Command1的Click事件代码: DIME a(n,n) STORE 0 TO a I = 1 j = (n+1)/2 a(i,j) = 1 lab[i,j].Caption=ALLT(STR(1)) FOR x=2 TO n*n IF a(i,j)%n = 0 I = I +1 ELSE
I = IIF(i=1,n,i–1) j = IIF(j=n,1,j+1) ENDIF a(i,j) = x lab[i,j].Caption = ALLT(STR(x)) ENDFOR ●编写Spinner1的InteractiveChange事件代码: FOR i = 1 TO n * n a1 = ALLT(STR(i)) THISFORM.Container1.RemoveObject('label&a1') ENDFOR n = THIS.Value THISFORM.Container1.Init ●编写“退出”按钮Command2的Click事件代码: THISFORM.Release
习题6 6.1 某数组有10个元素,要求将前5个元素与后5个元素对换。即第1个元素与第10个元素互换,第2个元素与第9个元素互换,…,第5个元素与第6个元素互换。输出数组对换后各元素的值。 6.2 修改上题,数组元素的值由计算机随机产生。 6.3 编写程序,建立并输出一个10×10的矩阵,该矩阵两条对角线元素为1,其余元素均为0。 6.4 有一个8×6的矩阵,各元素的值由由计算机随机产生,求全部元素的平均值,并输出高于平均值的元素以及它们的行、列号。 6.5 矩阵转置。即将矩阵行、列互换: 教学进程
6.6 求方阵的两个对角线元素和。 6.7 找出二维数组n×m中的“鞍点”。所谓鞍点是指它在本行中值最大,在本列中值最小。输出鞍点的行、列号,有可能在一个数组中找不到鞍点,如无鞍点则输出“无”。 6.8 矩阵的加法运算。两个相同阶数的矩阵A和B相加,是将相应位置上的元素相加后放到同阶矩阵C的相应位置。
6.9 矩阵的乘法运算。设A = (aij)为n×k矩阵,B = (bij)为k×m矩阵,则C = AB为n×m矩阵,C中元素: 6.10 设某班共10名学生,为了评定某门课程的奖学金,按规定超过全班平均成绩10%者发给一等奖,超过全班成绩5%者发给二等奖。试编制程序,输出应获奖学金的学生名单(包括姓名、学号、成绩、奖学金等级)。 6.11 为上题增加一个命令按钮,统计一个班学生0~9、10~19、20~29、…、90~99及100各分数段的人数。 6.12 利用随机函数,模拟投币结果。设共投币100次,求“两个正面”、“两个反面”、“一正一反”三种情况各出现多少次。
6.13 设计一个“通讯录”程序。当用户在下拉列表框中选择某一人名后,在“电话号码”文本框中显示出对应的电话号码。当用户选择或取消“单位”和“住址”复选框后,将打开或关闭“工作单位”或“家庭住址”文本框,如图6-17所示。 图6-17 “通讯录”程序
运动员号码 成绩 运动员号码 成绩 011 号 12.4 秒 476 号 14.9 秒 095 号 12.9 秒 201 号 13.2 秒 233 号 13.8 秒 171 号 11.9 秒 246 号 14.1 秒 101 号 13.1 秒 008 号 12.6 秒 138 号 15.1 秒 6.14 某校召开运动会。有10人参加男子100米短跑决赛,运动员号码和成绩如表6-6,试设计一程序,按成绩排名次。 表6-6 运动员号码和成绩 6.15 在上题中利用数组的排序函数ASORT()进行排序。
6.16 编写竞赛用评分程序:去掉一个最高分,去掉一个最低分,选手的得分最后为余下分数的平均分。如图6-18所示。 图6-18 竞赛用评分程序