C语言回顾day6 (C控制语句:分支 跳转)

心已赠人 2023-07-03 08:05 75阅读 0赞

文章目录

  • 分支
    • if else
      • 示例1
    • getchar() putchar()
      • 示例
        • 可以把while的条件改为赋值表达式的值,进一步缩短程序
    • ctype.h头文件中包含了原型的函数
      • 示例2 电费
      • 示例 判断是不是素数
      • 示例 统计输入字符数,单词数,行数
    • 条件运算符
      • 示例 油漆需要几桶
    • continue
      • 示例 求多个分数的均值,用continue跳过不合法输入,也用了条件运算符
      • 示例 continue;和空语句一样效果,跳过某些输入
      • 示例 break
    • switch
      • 示例 对应不同输入给不同输出
      • 示例 switch的多重标签 投票(同一个字母的大小写识别为同样输入)
  • 跳转
    • goto语句(不用!!!)
  • 练习
    • ‘b’>’a’ 是true
    • switch(i++)
    • 把==写成=,结果就是 will never end···

前面学了用循环重复执行任务,现在学习用分支根据测试条件执行相应行为

分支

if else

示例1

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int cold_days = 0, all_days = 0;
  5. const double FREEZING = 0.0;
  6. double temp;
  7. printf("Enter the list of daily temperatures:(enter q to quit)\n");
  8. while(scanf("%lf", &temp)==1)
  9. {
  10. all_days++;
  11. if(temp<FREEZING)
  12. cold_days++;
  13. }
  14. if(all_days)
  15. printf("%d days total, and %4.2f%% were below freezing.\n", all_days, (double)cold_days/all_days*100.0);
  16. else if(all_days==0)
  17. printf("No data entered.\n");
  18. return 0;
  19. }
  20. Enter the list of daily temperatures:(enter q to quit)
  21. 1.2 3.4 -2 -4
  22. q
  23. 4 days total, and 50.00% were below freezing.

getchar() putchar()

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

示例

  1. #include <stdio.h>
  2. #define SPACE ' '
  3. int main()
  4. {
  5. char ch;
  6. ch = getchar();
  7. while(ch != '\n')
  8. {
  9. if(ch==SPACE)
  10. putchar(ch);//printf(" ");
  11. else
  12. putchar(ch+1);//printf(ch+1);
  13. ch = getchar();
  14. }
  15. putchar(ch);//打印换行符
  16. return 0;
  17. }
  18. asdfghjkl;
  19. bteghiklm<

可以把while的条件改为赋值表达式的值,进一步缩短程序

在这里插入图片描述在这里插入图片描述

  1. #include <stdio.h>
  2. #define SPACE ' '
  3. int main()
  4. {
  5. char ch;
  6. while((ch = getchar()) != '\n')
  7. {
  8. if(ch==SPACE)
  9. putchar(ch);//printf(" ");
  10. else
  11. putchar(ch+1);//printf(ch+1);
  12. }
  13. putchar(ch);//打印换行符
  14. return 0;
  15. }

ctype.h头文件中包含了原型的函数

在这里插入图片描述在这里插入图片描述

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. int main()
  4. {
  5. char ch;
  6. while(scanf("%c", &ch)==1)
  7. {
  8. if(isalpha(ch))
  9. {
  10. if(islower(ch))
  11. {
  12. ch = toupper(ch);
  13. putchar(ch);
  14. putchar('\n'); // 极易写双引号!!!
  15. }
  16. }
  17. if(isblank(ch))
  18. putchar(' ');
  19. if(isdigit(ch))
  20. putchar(ch+1);
  21. }
  22. putchar('\n');
  23. return 0;
  24. }
  25. a
  26. A
  27. e
  28. E
  29. 2
  30. 3

示例2 电费

  1. #include <stdio.h>
  2. #define RATE1 0.13230
  3. #define RATE2 0.15040
  4. #define RATE3 0.30025
  5. #define RATE4 0.34025
  6. #define BREAK1 360.0
  7. #define BREAK2 468.0
  8. #define BREAK3 720.0
  9. #define BASE1 (RATE1*BREAK1)
  10. #define BASE2 (BASE1+RATE2*(BREAK2-BREAK2))
  11. #define BASE3 (BASE2+(BREAK3-BREAK2)*RATE3)
  12. int main()
  13. {
  14. double kwh=0, bill=0;
  15. printf("enter the kwh used:\n");
  16. scanf("%lf", &kwh);
  17. if(kwh<BREAK1)
  18. bill = kwh*RATE1;
  19. else if(kwh>=BREAK1 & kwh<BREAK2)
  20. bill = BASE1 + (kwh-BREAK1)*RATE2;
  21. else if(kwh>=BREAK2 & kwh<BREAK3)
  22. bill = BASE2 + (kwh-BREAK2)*RATE3;
  23. else if(kwh>=BREAK3)
  24. bill = BASE3 + (kwh-BREAK3)*RATE4;
  25. printf("The bill is $%4.3f.\n", bill);
  26. return 0;
  27. }
  28. enter the kwh used:
  29. 500
  30. The bill is $57.236.

我觉得书上这个地方不对,不用再加BASE1
在这里插入图片描述

示例 判断是不是素数

  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. int main()
  4. {
  5. unsigned int num;
  6. _Bool isPrime = true;
  7. int i;
  8. //只需要循环检测到输入数字的平方根,不需要检测平方根后面的数字
  9. while(scanf("%u", &num)==1)
  10. {
  11. for(i=2, isPrime=true;i*i<=num;i++)
  12. {
  13. if(num%i==0)
  14. {
  15. isPrime = false;
  16. if(i*i==num)
  17. printf("%u is divisible by %u.\n", num, i);
  18. else
  19. printf("%u is divisible by %u and %u.\n", num, i, num/i);
  20. }
  21. }
  22. if(isPrime)
  23. printf("%u is prime.\n", num);
  24. else
  25. printf("%u is not prime.\n", num);
  26. printf("enter another positive integer to decide if it is prime(enter q to quit):\n");
  27. }
  28. return 0;
  29. }
  30. 1
  31. 1 is prime.
  32. enter another positive integer to decide if it is prime:
  33. 2
  34. 2 is prime.
  35. enter another positive integer to decide if it is prime:
  36. 3
  37. 3 is prime.
  38. enter another positive integer to decide if it is prime:
  39. 4
  40. 4 is divisible by 2.
  41. 4 is not prime.
  42. enter another positive integer to decide if it is prime:
  43. 5
  44. 5 is prime.
  45. enter another positive integer to decide if it is prime:
  46. 6
  47. 6 is divisible by 2 and 3.
  48. 6 is not prime.
  49. enter another positive integer to decide if it is prime:
  50. 7
  51. 7 is prime.
  52. enter another positive integer to decide if it is prime:
  53. 8
  54. 8 is divisible by 2 and 4.
  55. 8 is not prime.
  56. enter another positive integer to decide if it is prime:
  57. 9
  58. 9 is divisible by 3.
  59. 9 is not prime.
  60. enter another positive integer to decide if it is prime:
  61. 11
  62. 11 is prime.
  63. enter another positive integer to decide if it is prime:
  64. 45273892785
  65. 2324219825 is divisible by 5 and 464843965.
  66. 2324219825 is divisible by 25 and 92968793.
  67. 2324219825 is not prime.
  68. enter another positive integer to decide if it is prime:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

示例 统计输入字符数,单词数,行数

  1. /*wordcnt.c*/
  2. #include <stdio.h>
  3. #include <stdbool.h> // bool, true, false
  4. #include <ctype.h> //isspace(),isalpha()原型
  5. #define STOP '|'
  6. int main()
  7. {
  8. char c;
  9. //n_lines完整的行(只要有换行符就认为是完整行)
  10. //p_lines不完整的行(最后一个字符不是换行符)
  11. int n_words=0, n_lines=0, p_lines=0, n_chars=0;
  12. //inword指输入的字符是一个单词的一部分,第一个字母和最后一个字母的inword是true
  13. bool inword = false;
  14. printf("enter text to be analyzed(| to terminate):\n");
  15. while((c = getchar())!=STOP){
  16. n_chars++;
  17. if(c=='\n')
  18. n_lines++;
  19. //只要输入字符不是空格并且inword现在是false,则认为开始一个新单词
  20. //(单引号双引号逗号等也会触发inword变为true,不过这个无所谓,因为并不影响最终单词总数)
  21. if(c!=' ' && !inword)
  22. {
  23. inword = true;
  24. n_words++;
  25. }
  26. //相当于只有遇到空格就认为开始新单词,因为空格使单词之间断开
  27. if(c==' ' && inword)
  28. inword = false;
  29. }
  30. if(c!='\n')
  31. p_lines++; //最后一个输入字符
  32. printf("characters:%d\nwords:%d\nlines:%d\npartial lines:%d\n.",
  33. n_chars, n_words, n_lines, p_lines);
  34. return 0;
  35. }

但是这个程序有个问题:一行结束后输入换行符之前要先输入一个空格(即先敲空格再敲回车换行),这样新一行的第一个单词才会被检测到,否则Word数目就比真实数目少了完整行数个。

  1. enter text to be analyzed(| to terminate):
  2. I have a pen.
  3. sd|
  4. characters:17
  5. words:5
  6. lines:1
  7. partial lines:1

但这样做的好处是一行没写完的单词不会被识别为两个词,而是仍然被识别为一个词。

  1. enter text to be analyzed(| to terminate):
  2. I have a p
  3. en.|
  4. characters:14
  5. words:4
  6. lines:1
  7. partial lines:1

条件运算符

在这里插入图片描述在这里插入图片描述在这里插入图片描述

示例 油漆需要几桶

在这里插入图片描述
用while和scanf一起则可以一直输入新的值来使用程序,而不需要重新启动程序。很好。

  1. while(scanf("%d", &square_feet)==1)
  2. #include <stdio.h>
  3. #define COVERAGE 350
  4. int main()
  5. {
  6. int square_feet, cans;
  7. printf("enter the square feet you need to paint:\n");
  8. while(scanf("%d", &square_feet)==1)
  9. {
  10. cans = square_feet/COVERAGE;
  11. cans += (square_feet%COVERAGE==0)?0:1;
  12. printf("you need %d %s of paint.\n", cans, (cans==1)?"can":"cans");
  13. }
  14. return 0;
  15. }
  16. enter the square feet you need to paint:
  17. 349
  18. you need 1 can of paint.
  19. 351
  20. you need 2 cans of paint.
  21. 700
  22. you need 2 cans of paint.
  23. 701
  24. you need 3 cans of paint.

continue

在这里插入图片描述在这里插入图片描述

示例 求多个分数的均值,用continue跳过不合法输入,也用了条件运算符

  1. #include <stdio.h>
  2. #define MIN 0.0f
  3. #define MAX 100.0f
  4. int main()
  5. {
  6. float score, max=MIN, min=MAX, total=0.0;
  7. int n = 0;//分数的个数
  8. printf("enter the first score:\n");
  9. while(scanf("%f", &score)==1)
  10. {
  11. if(score < MIN || score > MAX)
  12. {
  13. printf("The input score is invalid.\n");
  14. continue;
  15. }
  16. max = (score>max)?score:max;
  17. min = (score<min)?score:min;
  18. total += score;
  19. n++;
  20. printf("enter next score(enter q to end the input):\n");
  21. }
  22. if(n>0)
  23. {
  24. printf("The average score is %4.2f\nThe total score is %4.2f\n", total/n, total);
  25. printf("lowest: %4.2f\nhighest:%4.2f\n", min, max);
  26. }
  27. else
  28. printf("No valid scores were entered.\n");
  29. return 0;
  30. }
  31. enter the first score:
  32. 2.3
  33. enter next score(enter q to end the input):
  34. 4.5
  35. enter next score(enter q to end the input):
  36. 5.6
  37. enter next score(enter q to end the input):
  38. q
  39. The average score is 4.13
  40. The total score is 12.40
  41. lowest: 2.30
  42. highest:5.60

注意必须把n初始化为0,否则后面n++,最终得到的均值会完全错误

  1. int n = 0;//分数的个数

另一点,注意max初始化为MIN,而不是MAX哦!把max初始化为比较小的值,然后后面只要比他大的就替换他

还有一点,scanf对float用的转换说明是%f,千万别写成double的%lf咯,不然也会错误

示例 continue;和空语句一样效果,跳过某些输入

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. while((c=getchar())!='\n')
  6. ;
  7. printf("%u", c);
  8. return 0;
  9. }
  10. werf,d sad dsd
  11. 10

;空语句换为 continue;效果是一毛一样的

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. while((c=getchar())!='\n')
  6. continue;
  7. printf("%u", c);
  8. return 0;
  9. }
  10. qw dwkljk..sx
  11. 10

跳过制表符

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. while((c=getchar())!='\n')
  6. {
  7. //除了制表符以外的都打印出来其ascii码
  8. if(c=='\t')
  9. continue;
  10. else
  11. printf("%u ", c);
  12. }
  13. return 0;
  14. }

我输入了空格,d,制表符,f,然后只打印了3个码

  1. d f
  2. 32 100 102

示例 break

  1. #include <stdio.h>
  2. int main()
  3. {
  4. float length, width;
  5. printf("enter the length of the rectangle:\n");
  6. while(scanf("%f", &length)==1)
  7. {
  8. printf("length = %0.2f\n", length);
  9. printf("enter its width:\n");
  10. if(scanf("%f", &width)!=1)
  11. break;
  12. printf("width=%0.2f\n", width);
  13. printf("area=%0.2f\n", length*width);
  14. printf("enter the length of the rectangle(enter q to quit):\n");
  15. }
  16. printf("Done.\n");
  17. return 0;
  18. }
  19. enter the length of the rectangle:
  20. 12
  21. length = 12.00
  22. enter its width:
  23. 23
  24. width=23.00
  25. area=276.00
  26. enter the length of the rectangle(enter q to quit):
  27. q
  28. Done.

其实我没懂上面程序的那两句代码

现在懂了,看后面的练习部分,有一道题用在switch语句中break;实现了和continue一毛一样的功能:跳过
这里应该也一样,就是跳过,什么也不做

  1. if(scanf("%f", &width)!=1)
  2. break;

可以用while(scanf(“%f %f”, &length, &width)==2)简化上面的程序

  1. #include <stdio.h>
  2. int main()
  3. {
  4. float length, width;
  5. printf("enter the length and width of the rectangle:\n");
  6. while(scanf("%f %f", &length, &width)==2)
  7. {
  8. printf("length = %0.2f\n", length);
  9. printf("width=%0.2f\n", width);
  10. printf("area=%0.2f\n", length*width);
  11. printf("enter the length of the rectangle(enter q to quit):\n");
  12. }
  13. printf("Done.\n");
  14. return 0;
  15. }
  16. enter the length and width of the rectangle:
  17. 12 23
  18. length = 12.00
  19. width=23.00
  20. area=276.00
  21. enter the length of the rectangle(enter q to quit):
  22. q
  23. Done.

switch

示例 对应不同输入给不同输出

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char ch;
  5. printf("Type in a letter in lowercase, type # to end my act.\n");
  6. while((ch = getchar())!='#')
  7. {
  8. if(ch=='\n')
  9. continue;
  10. else
  11. switch(ch)
  12. {
  13. case 'a':
  14. printf("argali\n");
  15. break;
  16. case 'b':
  17. printf("babirusa\n");
  18. break;
  19. case 'c':
  20. printf("coati\n");
  21. break;
  22. case 'd':
  23. printf("desman\n");
  24. break;
  25. default:
  26. printf("That's a stumper!\n");
  27. }
  28. }
  29. printf("Bye!\n");
  30. return 0;
  31. }
  32. Type in a letter in lowercase, type # to end my act.
  33. a
  34. argali
  35. g
  36. That's a stumper!
  37. s
  38. That's a stumper!
  39. 2
  40. That's a stumper!
  41. h
  42. That's a stumper!
  43. b
  44. babirusa
  45. # Bye!

在这里插入图片描述
删除上面程序的switch语句的所有break,输入一个a,会把case a后面 的语句全部执行一遍

  1. Type in a letter in lowercase, type # to end my act.
  2. a
  3. argali
  4. babirusa
  5. coati
  6. desman
  7. That's a stumper!

在这里插入图片描述

continue不可用于switch语句

示例 switch的多重标签 投票(同一个字母的大小写识别为同样输入)

  1. #include <stdio.h>
  2. int main()
  3. {
  4. unsigned short a_cnt, e_cnt, i_cnt, o_cnt, u_cnt;
  5. a_cnt = e_cnt = i_cnt = o_cnt = u_cnt = 0;
  6. char ch;
  7. printf("vote for the five letters a e i o u:(enter # to end voting.)\n");
  8. while((ch=getchar())!= '#')
  9. {
  10. switch(ch)
  11. {
  12. case 'a':
  13. case 'A':
  14. a_cnt++;
  15. break;
  16. case 'E':
  17. case 'e':
  18. e_cnt++;
  19. break;
  20. case 'i':
  21. case 'I':
  22. i_cnt++;
  23. break;
  24. case 'o':
  25. case 'O':
  26. o_cnt++;
  27. break;
  28. case 'u':
  29. case 'U':
  30. u_cnt++;
  31. break;
  32. default:
  33. break;
  34. }
  35. }
  36. printf("\nEnd of voting! The number of vowels:\na:%u\ne:%u\ni:%u\no:%u\nu:%u\n", a_cnt, e_cnt, i_cnt, o_cnt, u_cnt);
  37. return 0;
  38. }
  39. vote for the five letters a e i o u:(enter # to end voting.)
  40. aaaoooiiiuueehj#
  41. End of voting! The number of vowels:
  42. a:3
  43. e:2
  44. i:3
  45. o:3
  46. u:2

上面的多重标签代码可以被改进地更短更简单,即统一转换为大写或小写:

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. int main()
  4. {
  5. unsigned short a_cnt, e_cnt, i_cnt, o_cnt, u_cnt;
  6. a_cnt = e_cnt = i_cnt = o_cnt = u_cnt = 0;
  7. char ch;
  8. printf("vote for the five letters a e i o u:(enter # to end voting.)\n");
  9. while((ch=getchar())!= '#')
  10. {
  11. switch(tolower(ch))//加这么一点就可以不用多重标签了
  12. {
  13. case 'a':
  14. a_cnt++;
  15. break;
  16. case 'e':
  17. e_cnt++;
  18. break;
  19. case 'i':
  20. i_cnt++;
  21. break;
  22. case 'o':
  23. o_cnt++;
  24. break;
  25. case 'u':
  26. u_cnt++;
  27. break;
  28. default:
  29. break;
  30. }
  31. }
  32. printf("\nEnd of voting! The number of vowels:\na:%u\ne:%u\ni:%u\no:%u\nu:%u\n", a_cnt, e_cnt, i_cnt, o_cnt, u_cnt);
  33. return 0;
  34. }

在这里插入图片描述

跳转

goto语句(不用!!!)

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

练习

‘b’>‘a’ 是true

  1. #include <stdio.h>
  2. int main()
  3. {
  4. if('b'>'a')
  5. printf("char can be compared.\n");
  6. return 0;
  7. }
  8. char can be compared.

switch(i++)

在这里插入图片描述
还真是没想到输出这个,主要是没注意到没有break,所以后面的都会输出一次

  1. fat hat cat oh no!
  2. hat cat oh no!
  3. cat oh no!

加上break的话

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int i = 0;
  5. while(i<3)
  6. {
  7. switch(i++)
  8. {
  9. case 0: printf("fat ");break;
  10. case 1: printf("hat ");break;
  11. case 2: printf("cat ");break;
  12. default: printf("oh no!");
  13. }
  14. putchar('\n');
  15. }
  16. return 0;
  17. }
  18. fat
  19. hat
  20. cat

把==写成=,结果就是 will never end···

在这里插入图片描述
在这里插入图片描述

改好后

  1. You are 40. Here is a raise.
  2. You are 60. Here is a raise.
  3. You are 65. Here is your gold watch.
  4. #include <stdio.h>
  5. int main()
  6. {
  7. char ch;
  8. while((ch=getchar())!='#')
  9. {
  10. if(ch=='\n')
  11. continue;
  12. printf("step 1\n");
  13. if(ch=='c')
  14. continue;
  15. else if(ch=='b')
  16. break;
  17. else if(ch=='h')
  18. goto laststep;
  19. printf("step 2\n");
  20. laststep: printf("step 3\n");
  21. }
  22. printf("Done!\n");
  23. return 0;
  24. }
  25. a
  26. step 1
  27. step 2
  28. step 3
  29. c
  30. step 1
  31. h
  32. step 1
  33. step 3
  34. b
  35. step 1
  36. Done!

如果以下列顺序输入呢,会输出什么
在这里插入图片描述
和我的a c h b一毛一样,因为除了定义的几个字母以外的字母都会打印三句

  1. q
  2. step 1
  3. step 2
  4. step 3
  5. c
  6. step 1
  7. h
  8. step 1
  9. step 3
  10. b
  11. step 1
  12. Done!

在这里插入图片描述
复习题9就是上面这个,不是很好改呢,小花了3分钟

由于不用goto又要跳转就只好用switch了,用default输出上面程序本来就要输出的三句;
输入换行符什么也不做所以直接break;起到了和continue一样的效果
记住每个case一定要break,这大概是switch语句最容易出错的地方了

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char ch;
  5. while((ch=getchar())!='#')
  6. {
  7. switch(ch)
  8. {
  9. case '\n':
  10. break;
  11. case 'c':
  12. printf("step 1\n");
  13. break;
  14. case 'b':
  15. printf("step 1\n");
  16. break;
  17. case 'h':
  18. printf("step 1\n");
  19. printf("step 3\n");
  20. break;
  21. default:
  22. printf("step 1\n");
  23. printf("step 2\n");
  24. printf("step 3\n");
  25. break;
  26. }
  27. if(ch=='b')
  28. break;
  29. }
  30. printf("Done!\n");
  31. return 0;
  32. }

在这里插入图片描述
在这里插入图片描述

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char ch;
  5. int space_cnt=0, n_lines=0, other_cnt=0;
  6. printf("enter # to quit.\n");
  7. while((ch=getchar())!='#'){
  8. if(ch==' ')
  9. space_cnt++;
  10. else if(ch=='\n')
  11. n_lines++;
  12. else
  13. other_cnt++;
  14. }
  15. printf("spaces:%d\nlines:%d\nother characters:%d\n", space_cnt, n_lines, other_cnt);
  16. return 0;
  17. }
  18. enter # to quit.
  19. sd sdsj ,./';]
  20. dd
  21. dd
  22. ht
  23. uo r w
  24. # spaces:8
  25. lines:6
  26. other characters:22

如果把提示语放在while里面,就会这样,每输入一个字符打印一次

  1. sd
  2. enter # to quit.
  3. enter # to quit.
  4. enter # to quit.
  5. d
  6. enter # to quit.
  7. enter # to quit.
  8. f
  9. enter # to quit.
  10. enter # to quit.

发表评论

表情:
评论列表 (有 0 条评论,75人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C语言】if分支语句

    1. 分支语句可以在程序运行的时候从多组语句中选择一组执行而忽略其他组,如果编写程序的时候遇到多种可能性,每种可能性都需要使用专门的语句处理,这种情况就可以采用分支结构解决。