C语言初阶——分支和循环语句

一、什么是语句?

1.1 语句的概念和控制语句

C语言中的语句可分成五类:表达式语句、函数调用语句、控制语句、复合语句、空语句

分支和循环语句属于控制语句,控制语句用于控制程序的执行过程,以方便实现程序的各种结构方式,C语言有九种控制语句。

1.2 控制语句的分类

(1)条件判断语句(分支语句):if语句、switch语句

(2)循环执行语句(循环语句):do while语句,while语句,for语句

(3)转向语句:break语句,goto语句,continue语句、return语句;

二、分支语句(选择结构)

2.1 if语句 

(1)if语句的基本形式如下:只要表达式为真,则执行表达式1;反之则执行表达式2。表达式为真的条件就是表达式判定为真,或者值为真(即不等于0);

在计算机语言中,非0表示真,0表示假。(无论正数负数,只要非0即为真)。

单分支语句 双分支语句 多分支语句
int main() {
    int a = 10;
    if (a == 10) {
        printf("hehe
");
    }
    return 0;
}
int main() {
    int a = 10;
    if (a == 10) {
        printf("hehe
");
    }
    else {
        printf("haha
");
    }
    return 0;
}
int main() {
    int a = 5;
    if (a == 10) {
        printf("hehe
");
    }else if (a == 5) {
        printf("haha
");
    }else {
        printf("无法打印");
    }
    return 0;
}
if (表达式) {
	表达式1(如果为真,则执行这个);
}
//else是可以不加的,代表这个判断语句是单分支语句,如果真则执行,假则直接跳过;
//else加上则表达这个判断语句是双分支语句,如果真则执行if中的语句,假则执行else中的语句;
else{
	表达式2(如果为假,则执行这个);
}

注意:

(1)if 语句后要执行多条语句,则这些语句一定要用大括号全部包裹起来,如果不加大括号的话则默认执行第一条语句,如果在双分支语句中,则else无法与if匹配,导致程序报错。

(2)else是与离他最近的 if 进行匹配的。(由于每个人的代码习惯不同,可能会导致某些else不是和与他匹配的 if 对齐的,因此,在学习的过程中一定要养成良好的代码书写习惯)

(3)特别注意:= 是赋值的意思,要判断需要使用 ==

(2)else后面也是可以加上判断语句if的,比如把判断成绩优良(80~100分)、及格(60~80分)、不及格(0~60分)三段,可以用如下代码执行:

int main() {
	int gra = 0;
	scanf("%d", &gra);
	if (gra >= 80 && gra < 100) {
		printf("这位同学的成绩为优良");
	}
	else if (gra >= 60 && gra < 80) {
		printf("这位同学的成绩为及格");
	}
	else if (gra >= 0 && gra < 60) {
		printf("这位同学的成绩不及格");
	}
	else {
		printf("输入非法,没有成绩,请重新尝试");
	}
	return 0;
}

注意:在if中的表达式最好不要表示为 0 < gra < 60,因为如果表示为这样,则会以此判断表达式是否为真,即:先判断前一个大于号左右两边的大小,如果为真则为1,如果为假则为0,而1和0恒小于60,因此表达式为恒假式,永远不会执行条件为真的语句。

2.2 switch语句

if语句适用于较少分支的语句,switch适用于较多分支的语句。

switch语句的格式:switch(整型表达式){语句项;}

语句项的格式:case 整型常量表达式:语句;

int main() {
	int num = 0;
	scanf("%d", &num);

	switch (num)//必须是整型表达式
	{
	case 1://必须是整型常量
		printf("今天是星期一");
		break;//如果不加上break,则会依次执行到switch语句结束,或者直至遇到下一个break;
	case 2:
		printf("今天是星期二");
		break;
	case 3:
		printf("今天是星期三");
		break;
	case 4:
		printf("今天是星期四");
		break;
	case 5:
		printf("今天是星期五");
		break;
	case 6:
		printf("今天是星期六");
		break;
	case 7:
		printf("今天是星期日");
		break;
	default:
		printf("非法字符,不予打印");
		break;
	}
	return 0;
}

(1)default子句:当所有情况下的case都无法匹配的时候,执行default子句;

(2)switch语句:允许嵌套使用;

(3)break只能跳出当前所在的选择或者循环语句,而不是跳出所有的选择与循环语句

三、循环语句

生活中有需要进行不断循环的动作,这个时候选择语句和跳转语句都无法实现这个操作,我们需要用循环语句来实现这个循环的动作。循环语句包括while、do while和for语句。

3.1 while语句

int main() {
	int i = 0;//由于while中第一句为i++,因此需要从0开始;
	//打印出1到10中的单数
	while (i<=9)//由于第一句是i++,因此i=9时进入循环,可得进入if判断时i=10;
	{
		i++;//放在前面防止死循环;
		if (i % 2 == 1) {
			continue;//结束本次循环,进入下一循环;
		}
		printf("%d
", i);
	}
	return 0;
}

(1)循环中的break会直接跳出循环,永久的终止了循环;

(2)循环中的continue会跳出本次循环,不执行本次循环中continue之后的语句,而开始下次循环的判断。

3.2 读取和输入缓冲区

(1)scanf读取有一个特性就是遇到空格会停止读取,所以在遇到需要读取空格的情况下我们需要使用gets来进行一行数的读取;

(2)getchar()是字符读取函数,每一次只能读取一个字符,如果读取不成功则返回EOF也就是-1;

int main() {
	int ch = getchar();
	//getchar()是字符读取函数;如果能正常读取的话,就能够读取到一个字符;
	//但是如果不能正常读取,那么getchar会返回一个EOF(相当于-1);
    //因为char类型接收不了-1,因此用int定义。
	printf("%c
", ch);
	putchar(ch);
}

在键盘输入到读取的过程当中,有一个输入缓冲区。当用户通过键盘输入信息的时候,输入的信息会被放入输入缓冲区中,然后scanf或getchar或gtes才能进行读取。例如:

如果需要读取密码,则密码的几种形式:

(1)如果密码是:abcdef;

当用户通过键盘输入这个的时候,当输入完毕时会按下一个回车键来确认,但这个回车键会被键盘当做一次
放入输入缓冲区,所以如果要用getchar进行,密码确认的时候,getchar不会进行等待输入Y和N,而是直接读取了
。所以我们要在getchar之前再写一个getchar函数来读取这个
字符。

(2)如果密码是:abcdef g;

当密码输入这个的时候,scanf只会读取空格之前的信息,而保留空格和空格之后的信息,因此仅仅使用一次getchar读取是不正确的,我们应该循环使用getchar读取,直到读取到转义字符

int main() {
	char password[20] = { 0 };
	printf("请输入密码为->");
	scanf("%s", password);
	//通过不断读取清空输入缓冲区;
	int ch = 0;
	while ((ch = getchar()) != '
'){//直到遇到'
'后,跳出循环;
		;
	}
	//完成后在进行下面的getchar读取时,输入缓冲区中没有任何信息,所以需要等待键盘输入;
	printf("请确认密码是否正确(Y/N)");
	int ret = getchar();
	if ('Y' == ret) {
		printf("Yes
");
	}
	else{
		printf("No
");
	}
	return 0;
}

3.3 for循环

while循环 for循环
int main() {
    int i = 1;//初始化
    while (i < 5) {//条件判断
        printf("hehe
");
        i++;//调整
    }
}

int main() {
    for (int i = 1; i < 5; i++) {
        printf("hehe
");
    }
}

//直接一体化,便于调整

for循环的格式为:for(表达式1;表达式2;表达式3){循环语句;}

(1)表达式1:初始化部分,用于初始化循环变量;可以在初始化部分直接定义变量进行初始化,但是只有在支持c99语法的编译器中才可以使用,如果不支持,会报错;

(2)表达式2:条件判断部分,用于判断循环何时终止;(必须是判断语句)

(3)表达式3:调整部分:用于循环条件的调整。

(4)for循环的执行过程:初始化—>条件判断—>循环体—>调整;continue跳过for循环本次循环后面的代码,但是并不会跳过调整部分,因为continue本质上是跳过循环体;

建议:(1)不可在for循环内部修改循环变量,防止for循环失去控制;(2)建议for循环语句的循环控制变量的取值采用“前闭后开区间”写法:如果写1到10,用的是(int i=1;i < 11;i++),而不是(int i=1;i <= 10;i++);

3.4 do while循环

while循环 for循环 do while循环
int main() {
    int i = 1;//初始化
    while (i < 5) {//条件判断
        printf("hehe
");
        i++;//调整
    }
}

int main() {
    for (int i = 1; i < 5; i++) {
        printf("hehe
");
    }
}

//直接一体化,便于调整

int main() {
    int i = 1;
    do {
        printf("hehe
");
        i++;
    } while (i < 5);
}

do while循环的格式为:do {循环语句;}while(表达式);

(1)do while循环的执行过程:循环体—>条件判断;

(2)while(表达式)后面有一个“ ; ”,一定不能忘记;

(3)do while循环的循环体至少会执行一次;