[华为云在线课程][C语言基础][三][流控制][学习笔记]
程序语言中的控制流语句用于控制各计算操作执行的次序。
1.语句与程序块
在表达式之后加上一个分号,就可以变成一个语句。在C语言中,分号就是语句结束符。
用一对花括号把一组声明和语句括在一起就构成了一个复合语句(程序块),复合语句语法上等价于单条语句。
2.if-else语句
if-else语句用于条件判定,语法为:
if {表达式}
语句1
else
语句2
语句执行时,先计算表达式的值,如果为真(非0),执行语句1;为假(0)且语句包含else部分,执行语句2。
3.else-if语句
在C语言中经常用到以下结构:
if (表达式)
语句
else if (表达式)
语句
else
语句
这种if语句序列是编写多路判定最常用的方法。其中的各表达式依次求值,一旦某个表达式结果为真,则执行相关的语句,并终止整个语句序列的执行。最后一个else部分用于处理所有条件均不成立的情况。
现在通过一个折半查找函数说明三路判定的用法。该函数用于判定已排序的数组 v 中是否存在某个特定的值 x。数组 v 的元素必须以升序排列。如果 v 中包含 x,则该函数返回 x 在 v 中的位置(介于0~n-1之间的一个整数);否则,该函数返回-1。
在折半查找时,首先将输入值 x 与数组 v 的中间元素进行比较。如果 x 小于中间元素,则在该数组的前半部分查找;否则,在数组的后半部分查找。
int binsearch(int x,int v[],int n)
{
int low,high,mid;
low=0;
high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(x<v[mid])
{
high=mid+1;
}else if(x>v[mid])
{
low=mid+1;
}
else
{
//找到了
return mid;
}
}
//没找到
return -1;
}
练习3-1:
/*
在上面折半查找例子中,while循环语句内共执行了两次测试,其实只要一次就可以。(将更多测试在循环外执行)
重写该函数,使得在循环内部只执行一次测试。
*/
#include <stdio.h>
int binsearch(int x, int v[], int n);
int main()
{
int test[] = {2, 4, 6, 8, 10, 12, 14};
int i;
for (i = (sizeof(test) / sizeof(int)) - 1; i >= 0; --i)
{
printf("查找= %d, 下标= %d\n", test[i], binsearch(test[i], test, sizeof(test) / sizeof(*test)));
}
return 0;
}
int binsearch(int x, int v[], int n)
{
int low, high, mid;
low = 0;
high = n - 1;
while (low < high)
{
mid = (low + high) / 2;
if (x <= v[mid])
{
high = mid;
}
else
{
low = mid + 1;
}
}
return (x == v[low]) ? low : -1;
}
/*
查找= 14, 下标= 6
查找= 12, 下标= 5
查找= 10, 下标= 4
查找= 8, 下标= 3
查找= 6, 下标= 2
查找= 4, 下标= 1
查找= 2, 下标= 0
*/
4.switch语句
switch语句是一种多路判定语句,测试表达式是否与一些常量整数值中的某一值匹配,并执行相应的分支动作。
switch (表达式)
{
case 常量表达式:语句序列
case 常量表达式:语句序列
default:语句序列
}
每个表达式都有一个或多个整数值常量或常量表达式标记。如果某个分支与表达式的值匹配,则从该分支开始执行。如果没有匹配,就执行default分支,default分支是可选的。
/*
用switch语句编写一个程序,统计各个数字、空白符及其它所有字符出现的次数。
*/
#include <stdio.h>
int main()
{
int c, i, nwhite, nother, ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; i++)
{
ndigit[i] = 0;
}
while ((c = getchar()) != EOF)
{
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
ndigit[c - '0']++;
break;
case ' ':
case '\n':
case '\t':
nwhite++;
break;
default:
nother++;
break;
}
}
printf("digits = ");
for (i = 0; i < 10; i++)
{
printf(" %d", ndigit[i]);
}
printf(", white space = %d, other = %d\n", nwhite, nother);
return 0;
}
break语句将导致程序立即执行从switch语句中退出。在switch语句中,case的作用只是一个符号,在某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显式跳转。跳出switch语句最常用的方式使用break和return。
好处是可以把若干个分支组合在一起完成一个任务,但要注意在最后一个分支(default)后面也要加上break语句。降低犯错误的可能性。
练习3-2:
/*
编写一个函数escape(s,t),将字符串t复制到字符串s中,
并在复制过程中将换行符、指标符等不可见字符分别转换成
\n \t 等相应的可见的转移字符序列。要求使用switch语句。
在编写一个具有相反功能的函数,在复制过程中将转义字符序列
转换成实际字符。
*/
#include <stdio.h>
void escape(char *s, char *t);
void unescape(char *s, char *t);
int main()
{
char text1[50] = "\aHello, \n\tWorld! \"Again\n";
char text2[51];
printf("原始字符串: \n%s\n", text1);
escape(text2, text1);
printf("转换后的字符串: \n%s\n", text2);
unescape(text1, text2);
printf("反转后的字符串: \n%s\n", text1);
return 0;
}
void escape(char *s, char *t)
{
int i, j;
i = j = 0;
while (t[i])
{
switch (t[i])
{
case '\n':
s[j++] = '\\';
s[j] = 'n';
break;
case '\t':
s[j++] = '\\';
s[j] = 't';
break;
case '\a':
s[j++] = '\\';
s[j] = 'a';
break;
case '\b':
s[j++] = '\\';
s[j] = 'b';
break;
case '\f':
s[j++] = '\\';
s[j] = 'f';
break;
case '\r':
s[j++] = '\\';
s[j] = 'r';
break;
case '\v':
s[j++] = '\\';
s[j] = 'v';
break;
case '\\':
s[j++] = '\\';
s[j] = '\\';
break;
case '\"':
s[j++] = '\\';
s[j] = '\"';
break;
default:
s[j] = t[i];
break;
}
++i;
++j;
}
s[j] = t[i];
}
void unescape(char *s, char *t)
{
int i, j;
i = j = 0;
while (t[i])
{
switch (t[i])
{
case '\\':
switch (t[++i])
{
case 'n':
s[j] = '\n';
break;
case 't':
s[j] = '\t';
break;
case 'a':
s[j] = '\a';
break;
case 'b':
s[j] = '\b';
break;
case 'f':
s[j] = '\f';
break;
case 'r':
s[j] = '\r';
break;
case 'v':
s[j] = '\v';
break;
case '\\':
s[j] = '\\';
break;
case '\"':
s[j] = '\"';
break;
default:
s[j++] = '\\';
s[j] = t[i];
}
break;
default:
s[j] = t[i];
}
++i;
++j;
}
s[j] = t[i];
}
5.while循环与for循环
while (表达式)
语句
在while循环语句中,首先求表达式的值。如果值非0,执行语句,再次求该表达式的值。直到表达式的值为0为止,然后继续执行后面的部分。下面的for循环和while循环是等价的。
for 循环语句;
for (表达式1 ; 表达式2 ; 表达式3)
语句
//------------------------------
表达式1;
while (表达式2)
{
语句
表达式3;
}
for循环语句的3个组成部分都是表达式。最常见的是,表达式1与表达式3是赋值表达式或函数调用,表达式2是关系表达式。3个部分任一部分都可以省略,分号必须保留。省略了表达式1和3会变成while循环语句。省略表达式2,值就永远变成是真值,需要借助break或者return才能终止循环。
如果没有初始化或重新初始化的操作,使用while语句更自然一些;如果语句中需要执行简单的初始化和变量递增,使用for语句更合适一些。
6.do-while循环
C语言中的第三种循环,do-while循环则在循环体执行后测试终止条件,这样循环体至少被执行一次。
do
语句
while (表达式);
7.break语句与continue语句
不通过循环头部或尾部地条件测试而跳出循环,可以使用break语句。break语句能使程序从switch语句或最内层循环中立即跳出。
/*
函数trim用于删除字符串尾部的空格符、制表符与换行符。当发现最右边的字符为非空格符、非制表符、
非换行符时,就使用break语句从循环中退出。
*/
int trim(char s[])
{
int n;
for(n=strlen(s)-1 ; n>=0 ; n--)
{
if( s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
{
break;
}
s[n+1] = '\0';
return n;
}
}
continue语句与break语句是相关联的,但没有break语句常用。continue语句用于使循环语句开始下一次循环的执行。在while和do-while中,continue语句的执行意味着立即执行测试部分;在for循环中,则意味着使控制转移到递增环变量部分。continue语句只用于循环语句,不用于switch语句。某个循环包含的switch语句中的continue语句,将导致进入下一次循环。
/*
这段程序用于处理数组a中的非负元素。如果某个元素的值为负,则跳过不处理。
*/
for (i=0 ; i<n ; i++)
{
if (a[i] < 0)
{
continue;
}
}
8.goto语句与标号
C语言提供了可随意滥用的goto语句及标记跳转位置的符号。大多数情况下,使用goto语句的程序段比不使用goto语句的程序段要难以理解和维护,建议尽可能少地使用goto语句。
- 点赞
- 收藏
- 关注作者
评论(0)