43
Visual FoxPro Visual FoxPro 程程程程程 程程程程程

Visual FoxPro 程序设计教程

  • Upload
    floria

  • View
    148

  • Download
    0

Embed Size (px)

DESCRIPTION

Visual FoxPro 程序设计教程. 第 6 章. 数 组. 6.1 数组的概念. ● 数组与数组元素. ● 数组的维数. 6.2 使用数组. ● 数组的定义. 1. 数组的声明. 语法格式为: {DIMENSION | DECLEAR}〈 数组名 〉(〈 行数 〉[,〈 列数 〉] ). 教学进程. 2. 数组的赋值. 【 例 6-1】 随机产生 10 个两位整数,找出其最大值、最小值和平均值。. 设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。. (2) 编写代码。 - PowerPoint PPT Presentation

Citation preview

Visual FoxPro Visual FoxPro 程序设计教程序设计教程程

第第 66 章章 数 组数 组

6.1 6.1 数组的概数组的概念念

● ● 数组与数组元素数组与数组元素

● ● 数组的维数数组的维数

教学进程教学进程

6.2 6.2 使用数组使用数组

●● 数组的定义数组的定义

1. 数组的声明 语法格式为:

{DIMENSION | DECLEAR} 〈数组名〉 ( 〈行数〉 [, 〈列数〉 ] )

教学进程教学进程

2. 数组的赋值【例 6-1 】随机产生 10 个两位整数,找出其最大值、最小值和平均值。

设计步骤如下: (1) 建立应用程序用户界面与设置对象属性。 (2) 编写代码。

随机整数的生成由表单的 Activate 事件代码完成:PUBLIC a(14) ' 因为要在不同的过程中使用数组,故声明为 PUBLICp = ""FOR i = 1 TO 14 a(i) = INT(RAND() * 90) + 10 p = p + STR(a(i),3) + ","ENDFORTHISFORM.Label2.Caption = ALLT(LEFT(p, LEN(p) – 1))THISFORM.Label3.Caption=" 最大值 = "THISFORM.Label4.Caption=" 最小值 = "THISFORM.Label5.Caption=" 平均值 = "

教学进程教学进程

求最大、最小以及平均值由“确定”按钮 Comma

nd2 的 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.ValueDIME F(n,2)F(2,1) = "Fib(2)"F(2,2) = 1FOR I = 3 TO n F(i,1) = "Fib(" + ALLT(STR(i)) + ")" F(i,2) = F(i–1,2) + F(i–2,2)ENDFORTHISFORM.List1.NumberOfElements = n

教学进程教学进程

表单运行结果如图 6-5 所示。

图图 6-5 6-5 求求 FibonacciFibonacci 数数列列

教学进程教学进程

【例 6-3 】设有一个 5×5 的方阵,其中元素是由计算机随机生成的小于 100 的整数。求出: (1) 主对角线上元素之和; (2) 方阵中最大的元素。如图 6-6 所示。

图图 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)ENDFORTHISFORM.List1.NumberOfElements = 5THISFORM.Text1.Value = ""THISFORM.Text2.Value = "" 在表单的 UnLoad 事件代码中释放全局变量数组 a( ) :RELEASE a 计算功能由“计算”按钮 Command1 的 Click 事件代码完成:s=0FOR i=1 TO 5 s = s + VAL(a(i,i))ENDFORTHISFORM.Text1.Value = smax = 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 ENDFORENDFORTHISFORM.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-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) + ", "ENDFORTHISFORM.Label2.Caption = LEFT(p,LEN(p) –2)THISFORM.Label4.Caption = "" 编写“排序”按钮 Command1 的 Click 事件代码:asort(a)p=""FOR i = 1 TO 10 p = p + a(i) + ", "ENDFORTHISFORM.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)+"任尔东西南北风。 "

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,txt2txt1 = THIS.Container1.Text1txt2 = THIS.Container2.Text1 改写表单的 Activate 事件代码:txt1.SetFocus 编写表单的 Destroy 事件代码:txt1 = 0txt2 = 0RELEASE txt1, txt2

●● 编写 Command1 的 Click 事件代码:txt2.Value=txt1.Value * ( 9 / 5 ) + 32 ●● 编写 Command2 的 Click 事件代码:txt1.Value = (txt2.Value - 32) * (5 / 9) ● ● 编写文本框 Text1 的事件代码 GotFocus 事件代码:THIS.SelStart = 0THIS.SelLength = LEN(THIS.Text) InteractiveChange 事件代码:txt2.Value = "" ●● 编写文本框 Text2 的事件代码 GotFocus 事件代码:THIS.SelStart = 0THIS.SelLength = LEN(THIS.Text) InteractiveChange 事件代码:txt1.Value = ""

教学进程教学进程

● ● 运行时创建对象运行时创建对象

使用 AddObject 方法可以在程序的运行中向容器添加对象,其语法格式为:

〈容器对象名〉 . AddObject( 〈对象名〉 , 〈类名〉 )

● ● 程序举例

【例 6-7 】用“筛法”找 1~ 100 之间的全部素数。 “筛法”求素数表是由希腊著名数学家 Eratost henes 提出来的,其方法是:在纸上写出 1~ n 的全部整数。如图 6-10 所示。

图图 6-10 16-10 1~~ 100100 之间的全部整之间的全部整数数

然后逐一判断它们是否素数,找出一个非素数就把它挖掉(筛掉),最后剩下的就是素数。具体做法是: (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&kENDFOR

. 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 ENDFORENDFOR

编写“开始”按钮 Command1 的 Click 事件代码:n = 100Lab(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 ENDIFENDFOR

a = MESSAGEBOX(' 剩下来的整数都是素数 '+CHR(13)+' 再作一遍吗? ',4+48,'')IF a = 6 FOR I = 1 TO 100 Lab(i).Enabled = .T. ENDFORENDIF 编写“关闭”按钮 Command2 的 Click 事件代码:RELEASE THISFORM

【例 6-8 】奇数阶的幻方阵。如图 6-14 所示。

图图 6-14 36-14 3 阶与阶与 77 阶的幻方阵阶的幻方阵

设计步骤如下: (1) 建立应用程序用户界面。 (2) 设置对象属性。如表 6-5 所示。

(3) 编写程序代码。 首先在表单的 Load 事件代码中定义全局变量 n 用来存放所选择的幻方阵的阶数,定义全局变量数组 Lab[1,1] 用来存放显示幻方阵各个元素的标签组。PUBLIC Lab(1,1), n 当然不能忘记在表单的 DeSTORE 事件代码中释放全局变量及数组:Lab = 0RELEASE Lab, n 在表单的 Activate 事件代码中调用“布阵”按钮的 Click 事件代码:THISFORM.Command1.Click ● ● 编写容器 Container1 的 Init 事件代码:n = THISFORM.Spinner1.Valuedd = 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&kENDFORFOR 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 ENDFORENDFORTHIS.Height = dd * n + 4THIS.Width = dd * n + 4 ● ● 编写“布阵”按钮 Command1 的 Click 事件代码:DIME a(n,n)STORE 0 TO aI = 1j = (n+1)/2a(i,j) = 1lab[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')ENDFORn = THIS.ValueTHISFORM.Container1.Init ● ● 编写“退出”按钮 Command2 的 Click 事件代码:THISFORM.Release

习题习题 66

教学进程教学进程

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 矩阵转置。即将矩阵行、列互换:

876543218765432198765432 转置

8

7

6

5

4

3

2

1

8

7

6

5

4

3

2

1

9

8

7

6

5

4

3

2

6.6 求方阵的两个对角线元素和。6.7 找出二维数组 n×m 中的“鞍点”。所谓鞍点是指它在本行中

值最大,在本列中值最小。输出鞍点的行、列号,有可能在一个数组中找不到鞍点,如无鞍点则输出“无”。

6.8 矩阵的加法运算。两个相同阶数的矩阵 A 和 B 相加,是将相应位置上的元素相加后放到同阶矩阵 C 的相应位置。

13

32

34

7

3

51

4

24

34

1

23

12

37

12

3

25

43

1

24

41

4

81

43

2

50

44

37

32

46

52

28

65

38

82

66

14

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 “ 通讯录”程序

6.14 某校召开运动会。有 10人参加男子 100米短跑决赛,运动员号码和成绩如表 6-6 ,试设计一程序,按成绩排名次。

运动员号码 成绩 运动员号码 成绩

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.15 在上题中利用数组的排序函数 ASORT() 进行排序。

表 6-6 运动员号码和成绩

图 6-18 竞赛用评分程序

6.16 编写竞赛用评分程序:去掉一个最高分,去掉一个最低分,选手的得分最后为余下分数的平均分。如图 6-18 所示。