第三章 程序控制结构
3.1 语句
语句是C程序的最小单位。
3.1.1 简单语句
简单语句包括表达式语句、函数调用语句和空语句,
(1)表达式语句;
(2)函数调用语句;
(3)空语句;只有一个分号。
(4)声明部分;
3.1.2 复合语句
将多个语句组成的语句序列用一对{}括起来组成的语句称为复合语句,也叫语句块,简称块。
复合语句内部可以进行变量定义或类型声明,这些定义或声明仅在复合语句内部可以使用,称为块的局部作用域。
3.1.3 注释
块注释:/…/
行注释://
3.1.4 语句的写法
一行一句
合理利用空白符
在C语言中字符串常量是不能从中间拆分的,编译器会认为字符串没有正常结束,例如
printf("this is a very long
string of examples.");
会产生编译错误。
解决字符串常量拆分的办法是使用“/”反斜杠行连接符,行连接符的作用是用程序的下一行替换当前的行连接符。
printf("one/
two/
three/");
相当于
printf("one two three");
3.2 输入与输出
C语言本身不提供输入输出语句,其输入输出操作时通过函数来实现的。
3.2.1 字符输入与输出
(1)字符输出putchar函数
putchar函数的作用是向终端输出一个字符,一般形式为:putchar©;
putchar函数可以直接输出ASC码中可显示的字符,控制字符有特殊的含义。例如‘/n’输出换行符。
//使用putchar输出字符
#include<stdio.h>
int main()
{
char a='C',b=6;
putchar(a);
putchar(b+'0');
putchar('\110');
putchar('\n');
return 0;
}
(2)字符输入getchar函数
getchar函数的作用是从终端输入一个字符,一般形式为getchar(),getchar函数没有函数参数,函数返回值为输入的字符,通常将其返回值赋值给一个字符型变量或者整型变量。
getchar函数的输入步骤如下:
(1):检查键盘缓冲区是否有字符。
(2):若有字符则直接从中提取一个字符返回,且缓冲区移向下一个字符。
(3):若没有字符,则getchar函数等待键盘输入,直到输入回车键结束等待。
//使用getchar输入字符
#include<stdio.h>
int main()
{
char c1,c2,c3;
c1=getchar();
c2=getchar();
c3=getchar();
putchar(c1);
putchar(c2);
putchar(c3);
return 0;
}
3.2.2 格式化输出
printf函数的作用是向标准输出设备输出格式化的数据,一般形式为:printf(格式控制,输出项列表);
printf函数的参数包括两部分。
(1):格式控制
格式控制为字符串形式,称为格式字符串,主要包括两部分内容,格式说明和一般字符。
3.2.3 格式化输入
scanf函数的作用是从标准输入设备中读取格式化的数据一般形式为:scanf(格式控制,输入项列表);
scanf函数将数据读入输入项列表中。每个输入项必须为地址形式(&变量)。
3.3 程序顺序结构
3.3.1 顺序执行
3.3.2 跳转执行
C语言有9种控制语句:
(1)选择语句:if语句、switch语句
(2)循环语句:while语句、do-while语句、for语句
(3)跳转语句:goto语句、break语句、Continue语句、return语句
goto语句:goto语句的作用是使程序无条件的跳转到别的位置。语句形式为goto 标号;
3.4 程序选择结构
3.4.1 if语句
if语句的作用是计算给定的表达式,根据结果选择执行相应的语句。
//利用下面的海伦公式计算三角形面积
#include<stdio.h>
#include<math.h>
int main()
{
double a,b,c;
printf("输入三个边长:\n");
scanf("%lf%lf%lf",&a,&b,&c);
if(a+b>c&&b+c>a&&a+c>b)
{
double t,s;
t=(a+b+c)/2.0;
s=sqrt(t*(t-a)*(t-b)*(t-c));
printf("%lf",s);
}
else
printf("error!\n");
return 0;
}
3.4.2 switch语句
switch语句的作用是计算给定的表达式,根据结果选择从多个分支入口执行,语句形式为:
switch(表达式){
case 常量表达式1 :语句序列1
case 常量表达式2 :语句序列2
case 常量表达式3 :语句序列3
case 常量表达式4 :语句序列4
case 常量表达式n :语句序列n
default :默认语句序列
}
switch语句的执行过程是先计算表达式,然后将该值与case的值逐一进行比较,若与某个常量表达式的值相等,就从该分支后的语句序列开始执行,执行完之后继续执行下一行语句序列,直到没有语句或者break语句为止,若没有相等的分支,则转向default分支,从默认语句序列开始执行。
switch语句后面的圆括号是必须要有的。
switch语句中的case分支必须是不同的常量表达式,不能包含变量。
注意使用break语句。最后的分支也可以不用break语句。
3.4.3 选择结构的嵌套
if语句和switch语句可以进行嵌套。
if语句的嵌套:
(1)在else语句上的嵌套
(2)在if和else语句上的嵌套
//编程输出成绩分类,90以上为A,80-89为B,...60以下为E
#include<stdio.h>
#include<math.h>
int main()
{
int s;
printf("请输入成绩:\n");
scanf("%d",&s);
if(s>100||s<0)
printf("ERROR!");
else if(s>=90)
printf("A\n");
else if(s>=80)
printf("B\n");
else if(s>=70)
printf("C\n");
else if(s>60)
printf("D\n");
else
printf("E\n");
return 0;
}
switch语句的嵌套,可以判断多个变量的情况。
3.4.4 选择结构程序举例
//输入某天的日期,输出下一天的日期
//分析:输入(Y,M,D),下一天为(Y,M,D+1),如果月份是1、3、5、7、8、10、12则有31天
//如果是4、6、9、11则有30天,如果是平年,则2月有28天,如果是闰年,则二月份有29天
//先判断年份是平年还是润年,再根据月份定出这个月有多少天,再计算下一天的日期。
#include<stdio.h>
#include<math.h>
int main()
{
int year,month,day,days;
printf("请输入日期:");
scanf("%d%d%d",&year,&month,&day);
switch(month){
case 2:
days=28;
if((year%100!=0&&year%4==0)||(year%400==0))//判断闰年
days++;
break;
case 4: case 6: case 9: case 11:
days=30;
break;
default:
days=31;
}
day++;
if(day>days){
day=1;
month++;
}
if(month>12){
month=1;
year++;
}
printf("日期为%d %d %d\n",year,month,day);
return 0;
}
//输入月份,判断星座。
#include<stdio.h>
#include<math.h>
int main()
{
int m,d,temp;
printf("请输入日期:");
scanf("%d%d",&m,&d);
if(m>12||m<1)
printf("ERROR!");
else{
temp=m>7?23:21;
if(d>temp)
m++;
switch(m){
case 2:printf("宝瓶座\n");break;
case 3:printf("双鱼座\n");break;
case 4:printf("白羊座\n");break;
case 5:printf("金牛座\n");break;
case 6:printf("双子座\n");break;
case 7:printf("巨蟹座\n");break;
case 8:printf("狮子座\n");break;
case 9:printf("处女座\n");break;
case 10:printf("天秤座\n");break;
case 11:printf("天蝎座\n");break;
case 12:printf("射手座\n");break;
default:printf("魔蝎座\n");break;
}
}
return 0;
}
3.5 循环结构
3.5.1 while语句
while语句的作用是计算给定的表达式,根据结果判断循环执行语句。
形式为:while(表达式) 语句;
while语句的执行过程是:
(1)计算给定表达式的值,无论为何种类型均将这个值按照逻辑值来处理。
(2)如果值为真,则执行循环语句,然后重复(1)
(3)如果值为假,则while语句结束,执行后面的语句
循环结构有三个要素:循环初始、循环条件、循环控制
//计算1-100的和
#include<stdio.h>
#include<math.h>
int main()
{
int i=1,sum=0;
while(i<101){
sum=sum+i;
i++;
}
printf("和为:%d\n",sum);
return 0;
}
3.5.2 do语句
do语句的作用是先执行语句,再计算给定的表达式,然后根据结果来判定是否进入循环。
形式为:do 语句;while(表达式);
do语句的执行过程是:
(1)执行语句。
(2)计算表达式,无论为何种类型均将这个值按照逻辑值来处理。
(3)如果值为真,则继续重复(1),如果值为假,则结束,执行后续语句。
do语句是先执行后判定,while语句是先判定再执行,do语句至少要执行一次,而while语句可能一次都不执行。
//连续输入多个数据,计算他们的乘积,直到输入为0时结束。
#include<stdio.h>
#include<math.h>
int main()
{
int x=1,m=1;
do{
m=m*x;
scanf("%d",&x);
}while(x!=0);
printf("%d\n",m);
return 0;
}
3.5.3 for语句
for语句的作用是计算给定的表达式,根据结果判定循环执行语句,for语句有循环初始和循环控制功能,语句形式为:for(表达式1;表达式2;表达式3)语句;
for语句的执行过程是:
先执行表达式1;
再计算表达式2;无论结果为何种类型,按照逻辑值处理。
如果为真,则执行循环体语句,再执行表达式3,再重复表达式2;
如果为假则for语句结束。执行后续语句。
for(循环初始;循环条件;循环控制)循环体;
3.5.4 break语句
break语句的作用是结束switch语句和循环语句的运行,转到后续语句
break语句只能在switch语句和循环语句中使用,不得单独使用。而且break语句只结束包含它的switch语句和循环语句,不会全都结束。
//判断一个数是否为素数,如果是输出YES,不是输出NO
//所谓素数,就是只能被1和自身整除的数。
#include<stdio.h>
#include<math.h>
int main()
{
int i,m;
printf("请输入一个整数:\n");
scanf("%d",&i);
for(m=2;m<i;m++){
if(i%m==0)
break;
}
if(m>=i)
printf("YES\n");
else
printf("NO\n");
return 0;
}
3.5.5 continue语句
continue语句的作用是在循环体中结束本次循环,直接进入下一次循环。
continue语句只能用在循环语句中,不能单独使用,而且只对包含它的循环语句有效果。
在while语句和do语句中使用continue语句,程序会转到表达式继续运行,而在for循环中,程序会转到表达式3中继续运行。
3.5.6 循环结构的嵌套
循环可以嵌套使用
3.5.7 循环结构程序举例
1.计数型循环
计数型循环用于处理已知循环次数的循环过程,在计数型循环过程中,循环控制是由控制变量来控制的,控制变量在每次循环时会发生规律性变化,当控制变量达到预定的循环次数时,循环结束。计数型循环常用for循环语句。
//求1-10的阶乘的和
#include<stdio.h>
#include<math.h>
int main()
{
int i=1,j=1,t=1,sum=0;
for(i=1;i<=10;i++){
for(j=1,t=1;j<=i;j++){
t=t*j;
sum=sum+t;
}
}
printf("%d\n",sum);
return 0;
}
条件型循环用于处理循环次数未知的循环过程,在条件型循环中,由于不知道循环次数,所以循环是由循环条件控制的,在每次循环时,判断条件是否满足,条件满足,循环结束。
//求pi的近似值,
#include<stdio.h>
#include<math.h>
int main()
{
int s=1;
double pi=0,n=1,t=1;
while(fabs(t)>1e-7){
pi=pi+t;
n=n+2;
s=-s;
t=s/n;
}
pi=pi*4;
printf("%lf\n",pi);
return 0;
}
//从键盘输入一行字符,直到输入回车结束,统计其中的字母、数字、空格个数。
#include<stdio.h>
#include<math.h>
int main()
{
char c;
int a=0,b=0,d=0;
printf("input string\n");
while((c=getchar())!='\n'){
if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
a++;
else if(c>='0'&&c<='9')
b++;
else if(c==' ')
d++;
}
printf("%d,%d,%d\n",a,b,d
);
return 0;
}
枚举法
//百钱百鸡,公鸡5元,母鸡3元,小鸡3只一元。
#include<stdio.h>
#include<math.h>
int main()
{
int x,y,z;
for(x=0;x<=20;x++){
for(y=0;y<=33;y++){
for(z=0;z<=100;z++){
if(z%3==0&&x+y+z==100&&5*x+3*y+z/3==100)
printf("公鸡%d,母鸡%d,小鸡%d\n",x,y,z);
}
}
}
return 0;
}
迭代法
//输出前40项斐波那契数列的值
#include<stdio.h>
#include<math.h>
int main()
{
int i,f0=0,f1=1,f2;
for(i=1;i<=40;i++){
f2=f0+f1;
f0=f1;
f1=f2;
printf("%d\n",f0);
}
return 0;
}