设为首页 加入收藏

TOP

C语言语句及流程控制(三)
2014-04-06 17:41:38 来源: 作者: 【 】 浏览:473
Tags:语言 语句 流程 控制

 

  今天是星期二,谢耳朵在控制台上输入了2.这个时候,整型变量day的值就是2.现在我们进入switch:很显然,case 2匹配上了我们的day,因此我们跳到case 2开始执行里面的语句:

  case 2:

  printf("汉堡\n");

  break;

  我们首先执行printf:在控制台上,我们输出了"汉堡",这一句完成。接下来,我们遇到了一个break.按照我们刚刚的讲解,遇到break之后我们就跳出整个switch语句,这一部分就结束了。

  所以,当谢耳朵输入了2之后,整个switch语句的执行效果就是:在屏幕上打印了一句

  "汉堡",然后结束。谢耳朵输入其他case的值(1,3,4,5,6)效果是类似的。

  如果今天是星期天,谢耳朵输入了7,此时day的值是7,那么在switch中我们挨个遍历所有的case,发现和day的值都不符合,于是我们最后就落脚在default上,执行printf,输出一句"谢耳朵要自己做饭",然后switch这一段结束。

  好,截止到目前为止,这个程序应该还是很清晰的。接下来我们来对谢耳朵的程序做一些小改动来说明break的作用:

  int day;

  scanf("%d", &day);

  switch(day)

  {

  case 1:

  printf("燕麦粥\n");

  break;

  case 2:

  printf("汉堡\n");

  case 3:

  printf("奶油土豆汤\n");

  case 4:

  printf("披萨\n");

  break;

  case 5:

  printf("法式面包\n");

  break;

  case 6:

  printf("中餐\n");

  default:

  printf("谢耳朵要自己做饭\n");

  }

  如果谢耳朵输入了1,那么结果和之前一样--在屏幕上打印一句"燕麦粥",结束。

  如果,谢耳朵输入的是2,这个时候程序的结果就不一样了--首先,我们会跳到case 2当中,在屏幕上输出"汉堡".执行完了这句printf之后,我们发现没有break,于是程序会接着跳到case 3中,执行"奶油土豆汤".接下来由于case 3中也没有break,于是程序继续向下执行,进入case,输出"披萨",终于我们这次看到了break,于是执行完了case 4之后,跳出switch,结束。所以这时如果谢耳朵输入了2,他看到的结果将是:

  2

  汉堡

  奶油土豆汤

  披萨

  :动手体验:

  加上main函数和必要的头文件,在你的电脑上实现上一节的程序,输入6,猜猜输出会是什么?输出和你预想的一致吗?

  循环结构

  介绍完了顺序和选择结构之后。我们在本节向大家介绍循环结构。顾名思义,循环结构就是一遍又一遍地做重复的事情。我们还是用开车的例子来说明:在F1比赛中,10只车队的20位车手们驾驶着各自的赛车在一条数公里的环形赛道上风驰电掣,每场比赛中选手需要环绕赛道数十圈,最先跑完全程的车手获得冠军。假设在一次比赛中,车手们需要跑完50圈,利用此前学习的顺序和选择结构,我们可以用如下方式表示这个过程:

  int count = 0;

  if (count < 50)

  {

  printf ("我跑了一圈\n");

  count++;//count = 1

  }

  if (count < 50)

  {

  printf ("我跑了一圈\n");

  count++;//count = 2

  }

  …

  当然,这样手工写50遍if语句是非常非常不可取的。幸运的是,C语言的表达能力不会如此低下,循环语句就可以帮助我们简化上述过程。

  在本节中,我们首先向大家介绍for循环,它特别适合循环次数已知的情况;随后我们将介绍while循环和do while循环,这两种循环都比较适合应用在循环次数未知的情况。

  for循环结构

  for循环有可能是最常见的循环了,我们以后会经常和它打交道。for循环的语法如下:

  for (表达式1;条件判断;表达式3)

  {

  表达式2;

  }

  for循环的执行过程是这样的:

  1. 首先计算表达式1;

  2. 判断条件是否为真,如果为假,跳出循环不再执行;

  3. 如果条件判断为真,进入循环,执行表达式2;

  4. 执行表达式3,转到步骤2.

  我们来看一个具体的例子:

  int sum = 0;

  for (int i = 1; i <= 100; i++)

  {

  sum += i;

  }

  上述循环完成了求前100个自然数和的工作。如果你还没有反应过来,没有关系,我们可以把它拆开来一步一步执行:

  1. 首先,i被赋值为1;

  2. 条件判断:i<=100吗?正确,继续执行;

  3. 执行sum+=i,此时sum=1;

  4. 执行i++,此时i=2;

  5. 再次进行条件判断:i<=100正确;

  6. 执行sum+=i,此时sum=1+2;

  7. 执行i++,此时i=3;

  等等。我们跳过中间的过程,直接观察这个循环什么时候结束:假设某一次循环执行完i++之后i=100,我们进行条件判断i<=100为真,开始执行sum+=i,这时sum里面保存了1加到100的值。接下来,执行i++,i被修改为101了,此时不满足i<=100了,因此跳出循环。最终sum中的值为前100个自然数的和。

  需要强调的是,如果在表达式1中定义了新变量i,那么这个变量只在循环内是可见的,也就是说只有在这个循环内可以使用变量i,当我们跳出了这个循环之后,程序就不认识i是什么了。如果你在循环外使用i的话:

  int sum = 0;

  for (int i = 1; i <= 100; i++)

  {

  sum += i;

  }

  printf("%d\n", i);

  你会发现编译无法通过--你的编译器不认识printf中的i是什么。当然如果你事先在循环体外部声明了i的话:

  int sum = 0;

  int i;

  for (i = 1; i <= 100; i++)

  {

  sum += i;

  }

  printf("%d\n", i);

  那printf就能够认出需要输出的i是一个int类型的变量。

  如果循环体当中只有一条语句,那么循环体的花括号可以省略。在上面的例子中,我们也可以把它精简成如下形式:

  int sum = 0;

  for (int i = 1; i <= 100; i++)

  sum += i;

  当然是否省略花括号只反映了不同的编程风格,并不会影响程序的结果。读者可以根据自己的喜好选择适合自己的编程风格。

  M脚下留心:为什么我的循环程序不对?

  如果一切正常的话,上述循环的执行结果是5050.然而,假设有一个粗心的程序员把代码敲成了这样:

  int sum = 0;

  for (int i = 1; i <= 100; i++);

  {

  sum += i;

  }

  你会发现你的程序编译无法通过了。我们查看VS的报错,发现是sum+=i当中的i没有定义。这说明sum+=i根本就不在循环体内--循环究竟在哪里呢?答案是:这是一个空循环!注意我们加在for语句后面的分号事实上形成了一条什么都不干的空语句:

  for (int i = 1; i <= 100; i++)

  {

  ;

  }

  {

  sum += i;

  }

  所以整个for循环空转了100次,跟在最后的sum+=i只执行了一遍,而且还不知道i是个什么值,自然编译器就报错了。

  while循环结构

  我们之前说过for循环特别适合已知循环次数的情况。正如同上面求前100个自然数的和,我们知道循环100次就可以完成这件事。然而,在有些情况下我们事先无法知道循环次数,这时候使用for循环就不太自然(当然,并不是说for循环不可以完成这样的工作):

  :动手体验:前多少个自然数的和大于1000

  我们已经学会了利用for循环求解前N个自然数的和,其中N是给定的整数。现在假设有某一个N满足前N个自然数的和大于1000,但是前N-1个自然数的和小于等于1000(你可以想象成当我们求和时,加到了N的时候,和刚刚好超过了1000)。你能用for循环实现这个程序吗?

  :动手体验:猜数字

  假设Foo和Bar两个人在玩猜数字的游戏。Foo在心中想了一个0到1000的整数(包括0和1000),Bar每次可以向Foo提问"你心里想的数大于XXX吗?",Foo会给出真实的回答。假设Bar每次都采用二分的策略来提问,即每次都将Foo心中的数所在区间缩小一半。举个例子:

  Bar:这个数大于500吗?Foo:对 ([501, 1000])

  Bar:这个数大于750吗?Foo:错([501, 750])

  Bar:这个数大于625吗?Foo:对([626, 750])

  等等。如果我们用C语言来模拟上述过程的话,循环的次数(Bar猜测的次数)和Foo心中一开始想的数字有关,我们根本无法事先得知循环的次数。

  对于上面这些不知道循环次数的情况,C语言提供了比for更合适的while语句来解决这个问题:

  while (条件判断)

  {

  表达式;

  }

  while语句看上去要比for简洁不少:首先while会进行条件判断,如果为假就跳出循环,如果为真就进入循环体执行表达式,执行完之后继续条件判断,如果为假跳出,为真则进入循环体继续执行,等等。可以看出,while循环和下面的for循环是一致的:

  for (;条件判断;)

  {

  表达式;

  }

  在这个特殊的for循环中,初始化语句为空,每次循环结束的更新语句也为空。

  我们用本节开头的第一个例子来展示while循环的用法:

  int sum = 0;

  int i = 1;

  while (sum <= 1000)

  {

  sum += i;

  i++;

  }

  printf("%d\n", i-1);

  我们来顺着while循环的执行过程将上述程序走一遍:

  1. 初始化sum和i;

  2. 判断sum<=1000,正确;

  3. sum+= i;此时sum=1;

  4. i++;此时i=2;即下一次要加的数;

  5. 判断sum<=1000,正确;

  6. sum+=i,此时sum=1+2;

  7. i++;此时i=3;

  等等。这里跳出循环时i的值需要我们稍微推敲一下:当使得sum恰好超过1000的那个N出现时(即i=N时),此时sum保存了1到N-1的和,它是小于等于1000的,因此下一次循环开始时可以正常进入循环体。接下来sum加上了N(超过1000了),i被修改成了N+1,因此下一次条件判断就失败了,跳出循环。此时i中保存的是N+1的值,为了得到N我们需要输出i-1.

  do-while循环

  do-while循环是while循环的一种变体:

  do

  {

  表达式;

  }while(条件判断);

  稍有不同的是,在do-while循环中,首先执行表达式,然后进行条件判断,如果为真,就回头继续执行表达式,否则就跳出。我们可以把do-while循环改写成如下的for循环:

  for (表达式;条件判断;)

  {

  表达式;

  }

  do-while循环不像前两种循环那么常见,读者如果要使用do-while循环的话,请留心这一点:循环体中的表达式至少会被执行一次。

  continue,break与return

  在循环结构的最后,我们介绍continue,break和return,它们可以大大扩展循环结构的表达能力。

  continue,break和return的直接作用都是中断当前的循环,不同的是,在此之后,continue会开始下一次循环;break会跳出循环,而return会直接跳出当前函数(我们目前的循环都是在main函数中,在main函数中执行return就相当于整个程序结束了)。我们以表达能力最丰富的for循环来举例:continue的作用如下:

  for (表达式1;条件判断;表达式3)

  {

  表达式2-1;

  continue;

  表达式2-2;//不会被执行!

  }

            

首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言单元测试 下一篇C语言main函数生成可执行法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: