嵌套循环的控制变量——Ada应用实例之十三

时间:2022-03-20 20:31:09

嵌套循环的控制变量——Ada应用实例之十三

 

以下是解答HDU ACM 2019(判断回文串)的一个C程序:

(引自http://zhidao.baidu.com/question/217863132.html

#include<stdio.h>

#include<string.h>

int main()

{

 int n,i,k;

 char a[1000];

 while(scanf("%d",&n)!=EOF)

 {

  getchar();

  for(i=0;i<n;i++)

  {

   gets(a);

   k=strlen(a);

   for(i=0;i<k;i++)

   {

    if(a[i]!=a[k-i-1])

     break;

   }

   if(i==k)

    printf("yes/n");

   if(i!=k)

    printf("no/n");

  }

 }

return 0;

}

 

作者发现一个奇怪现象,当输入是:

4

hahah

haha

 

程序给出的输出是:

yes

yes

 

显然第2个输出是错的。原因是程序中2个嵌套的循环:

  for(i=0;i<n;i++)

   for(i=0;i<k;i++)

使用了同一个变量i来控制循环。以下分析出错过程:

a)      处理第1个输入“hahah”,内层循环“for(i=0;i<k;i++)”结束后i的值是5

b)      执行外层循环“for(i=0;i<n;i++)”的判断条件“i<n”,结果为假,退出循环;

c)      执行“while(scanf("%d",&n)!=EOF)”,由于此时输入是“haha”,未能读入;

d)      执行“getchar()”,读入‘h’

e)      执行gets(a)读入“aha”,这是回文串,所以输出“yes”。

 

变量i是在main中声明的,因此它的作用域包含2个嵌套的循环。如果在外层循环与内层循环之间再声明一个变量i,就可以避免混淆问题:

  for(i=0;i<n;i++)

  {

int i;

不过还是把外层循环改用另一个循环变量(例如,j,程序的可读性较好。

 

如果用Ada编写这个程序,就不会出现混淆问题。Adafor循环的控制变量有如下特点:

a)      它是隐含声明的;

b)      它的作用域限于该循环体;

c)      出了该循环体它就不存在了;

d)      编程者不能对它修改;

e)      它的值域是离散的。

 

以下例子中2循环控制变量i虽然同名,但有各自的作用域:

with Text_IO; use Text_IO;

procedure main is

begin

   for i in 1 .. 2

   loop

      put_line ("External i = " & Integer'Image (i));

      for i in 1 .. 2

      loop

         put_line ("Inner i = " & Integer'Image (i));

      end loop;

   end loop;

end main;

 

该程序输出:

External i =  1

Inner i =  1

Inner i =  2

External i =  2

Inner i =  1

Inner i =  2