当前位置:首页 » 《资源分享》 » 正文

第2章 分支和循环语句_今天的你也辛苦啦!

15 人参与  2021年10月11日 12:03  分类 : 《资源分享》  评论

点击全文阅读


目录

  • 1. 什么是语句?
  • 2. 分支语句(选择结构)
    • 2.1 if 语句
      • 2.1.1 语法结构
      • 2.1.2 悬空else
    • 2.2 switch 语句
      • 2.2.1 语法格式
      • 2.2.2 default 子句
      • 2.2.3 练习
  • 3. 循环语句 (循环结构)
    • 3.1 while 语句
      • 3.1.1 语法结构
      • 3.1.2 while 语句中的 break 和 continue
    • 3.2 for 语句
      • 3.2.1 语法格式
      • 3.2.2 for 循环 和 while 循环的对比
      • 3.2.3 for 语句中的 break 和 continue
      • 3.2.3 for 循环的一些变种
      • 3.2.4 一道笔试题
    • 3.3 do … while 语句
      • 3.3.1 语法格式
      • 3.3.2 do 语句的特点
      • 3.3.4 do…while 语句中的 break 和 continue
    • 3.4 练习
    • 3.5 goto 语句


1. 什么是语句?

C语言中由一个分号;,隔开的就是一条语句。

比如:

printf("hello world!");
1+2;

2. 分支语句(选择结构)

2.1 if 语句

2.1.1 语法结构

if(表达式)
    语句;

if(表达式)
    语句1;
else
    语句2;

// 多分支
if(表达式1)
    语句1;
else if(表达式2)
    语句2;
else
    语句3;

举例:

#include <stdio.h>
//代码1
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年\n");
	}
}
 

//代码2
#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年\n");
	}
	else
	{
		printf("成年\n");
	}
}


//代码3
#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("少年\n");
	}
	else if (age >= 18 && age < 30) // 18<=age<=30  => (18<=age)<=30
	{
		printf("青年\n");
	}
	else if (age >= 30 && age < 50)
	{
		printf("中年\n");
	}
	else if (age >= 50 && age < 80)
	{
		printf("老年\n");
	}
	else
	{
		printf("老寿星\n");
	}

}

2.1.2 悬空else

《高质量C++编程指南》

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hhe\n");
	else
		printf("haha\n");
	return 0;
}

// 运行结果: 什么都不输出
// else 与离得最近的未匹配的if 进行匹配


// 改正
#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)  // 判断条件建议写成 1 == a
    {	
        if (b == 2)
			printf("hhe\n");
    }
	else
		printf("haha\n");
	return 0;
}
// 输出 haha

2.2 switch 语句

2.2.1 语法格式

switch(整形表达式)
{
	case 整型常量表达式;
     	语句;
        break;
}
// 在 switch 语句中,我们没法直接实现分支,搭配 break,使用才能实现真正的分支。
// break 语句的实际效果是把语句列表划分为不同的部分。

举例

输入1,输出星期一

输入2,输出星期二

输入3,输出星期三

输入4,输出星期四

输入5,输出星期五

输入6,输出星期六

输入7,输出星期日

#include <stdio.h>
int main()
{
	int a;
	printf("请输入一个数,\n");
	scanf("%d", &a);
	switch (a) // 括号内必须是整型表达式
	{
	case 1:  // 必须为 整型 常量 表达式
		printf("星期一\n");
		break;
	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;
	}

	return 0;
}

输入1-5输出的是“weekday”;

输入6-7输出“weekend”;

#include <stdio.h>
int main()
{
	int a;
	printf("请输入一个数,\n");
	scanf("%d", &a);
	switch (a)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	default:
		printf("输入错误\n");
		break;
	}

	return 0;
}

2.2.2 default 子句

  • default语句可有可无,其作用是处理语句中的非法状况。

  • defaulecase没有顺序所言,但是一般建议把default放到最后。

  • 编程好习惯

    在每个 switch 语句中都放一条 default子句是个好习惯,甚至可以在后边再追加一个 break

2.2.3 练习

#include <stdio.h>
int main()
{
	int n = 1;
	int m = 2;
	switch (n)
	{
	case 1:m++;
	case 2:n++;
	case 3:
		switch (n)
		{ // switch 允许嵌套使用
		case 1:n++;
		case 2:
			m++;
			n++;
			break;
		}
	case 4:
		m++;
		break;
	default:
		break;
	}
	printf("m = %d,n = %d\n", m, n);

	return 0;
}
// 运行结果
// m = 5,n = 3

3. 循环语句 (循环结构)

3.1 while 语句

3.1.1 语法结构

while(判断条件) // 符合判断条件。就执行语句体。
{
	语句体;
}

3.1.2 while 语句中的 break 和 continue

break 介绍

#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			break;
		printf("%d ", i);
		i++;
	}

	return 0;
}
// 运行结果: 1 2 3 4

总结:

break 在 while 循环中的作用:

其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。

所以:while中的break是用于 永久 终止循环的。

continue 介绍

#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			continue;
		printf("%d ", i);
		i++;
	}

	return 0;
}
// 运行结果: 1 2 3 4 之后光标闪着不动,程序进入死循环。
#include <stdio.h>
int main()
{
	int i = 0;
	while (i <= 10)
	{
		i++;
		if (5 == i)
			continue;
		printf("%d ", i);

	}

	return 0;
}
// 运行结果: 1 2 3 4 6 7 8 9 10 11

总结:

continue 在 while 循环中的作用是:

continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。

再来看几个代码吧

#include <stdio.h>
int main()
{
    int ch = getchar();
    putchar(ch);
    return 0;
}


// getchar 是读取字符
// 为什么返回类型是int 呢?
// 1. getchar 既然返回的是字符,其实返回的是字符的ascii码值(整数)
// 2. getchar 在读取结束或者失败的时候,会返回EOF(文件的结束符)
//     EOF  -- end of file   -->  -1
#include <stdio.h>
int main()
{
 	int ch = 0;
	while ((ch = getchar()) != EOF) 
       	putchar(ch);
    return 0; 
}



// EOF -- end of file --文件结束标志
// 输入EOF 循环并不会结束,而是执行三次循环,读取三次,输出EOF,只有按ctrl+z才能终止循环。

输入密码确认案例

#include <stdio.h>
int main()
{
	int ret = 0;
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	printf("请确认(Y/N):>");
	ret = getchar();
	if (ret == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("放弃确认\n");
	}
	return 0;
}

// 上述代码存在问题,输入密码后按回车,自动输出放弃确认。

解析:

造成上述问题的原因是,在输入密码并按回车后,缓冲区的内容是12345\n,%s只会读取\n之前的字符,而\n就会被ret所读取。这就造成了,未进行确认就输出放弃确认的结果。

// 改正后代码
#include <stdio.h>
int main()
{
    int ch = 0;
    int ret = 0;
    char pass[20] = { 0 };
    printf("请输入密码:>");
    // scanf() 读取字符串会在末尾自动加'\0'
    scanf("%s", pass);
    // 把缓冲区中的内容清空
    while((ch = getchar()) != '\n')
    {
        ;
    }
    printf("请确认(Y/N):>");
    ret = getchar();
    if ('Y' == ret)
        printf("确认正确\n");
    else
        printf("确认失败\n");

    return 0;
}

3.2 for 语句

3.2.1 语法格式

for(表达式1;表达式2;表达式3)
    循环语句;
  • 表达式1:为 初始化部分,用于初始化循环变量;表达式2:为 条件判断部分,用于判断循环时候终止;表达式3:为 调整部分,用于循环条件的调整。

建议for语句的循环控制变量的取值采用 **“前闭后开区间”**的写法

不可在for 循环体内修改循环变量,防止 for 循环失去控制。

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int i = 0;
    // 10次循环
    // 10次打印
    // 10个元素
    for (i = 0; i<10; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}
// C 语言语法
int main()
{
    int i = 0;
    for(i = 0;i<=12;i++)
    {
        printf("hehe\n");
    }
}

// C++ 语法
int main()
{
    for(int i = 0;i<=12;i++)
    {
        printf("hehe\n");
    }
}

3.2.2 for 循环 和 while 循环的对比

#include <stdio.h>
int main()
{
    int i = 0;

    //实现相同的功能,使用while
    i = 1;//初始化部分
    while (i <= 10)//判断部分
    {
        printf("hehe\n");
        i = i + 1;//调整部分
    }

    //实现相同的功能,使用while
    for (i = 1; i <= 10; i++) {
        printf("hehe\n");
    }
    return 0;
}

可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹。

for循环使用的频率也最高。

3.2.3 for 语句中的 break 和 continue

可以发现在 for循环中也可以出现breakcontinue,他们的意义和在while循环中是一样的。

但是还是有些差异:

//代码1
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
	}
	return 0;
}



//代码2
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}

3.2.3 for 循环的一些变种

变种1

#include <stdio.h>
int main()
{
 	for(;;)
 	{
 		printf("hehe\n");
 	}
    
    return 0;
}  

    
// 结果: 死循环打印 hehe 
// 1.  for循环的初始化、调整、判断,都可以被省略,
 	// 但是:
 	// for 循环的判断部分如果被省略,那判断条件就是:恒为真
// 2.  不要随便省略相应的代码    

变种2

#include <stdio.h>
int main()
{
 	int x, y;
    for (x = 0, y = 0; x<2 && y<5; ++x, y++)
    {
        printf("hehe\n");
    }
 return 0; 
}   

3.2.4 一道笔试题

请问循环要循环多少次

#include <stdio.h>
int main()
{
    int i = 0;
    int k = 0;
    for (i = 0, k = 0; k = 0; i++, k++)
        k++;
    return 0;
}



// 循环执行0次,因为判断表达式中 k = 0 ,0为假,所以循环执行0次。

3.3 do … while 语句

3.3.1 语法格式

do
    循环语句;
while(表达式);

3.3.2 do 语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用。

#include <stdio.h>
it main()
{
	int i = 10;
	do
	{
		printf("%d\n", i);
	} while (i < 10);
	return 0;
}

3.3.4 do…while 语句中的 break 和 continue

#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			break;
		printf("%d ", i);
		i++;
	} while (i < 10);
	return 0;
}


// 运行结果: 1 2 3 4



#include <stdio.h>
int main()
{
    int i = 1;
    do
    {
        if (5 == i)
            continue;
        printf("%d ", i);
        i++;
    } while (i < 10);
    return 0;
}



// 运行结果: 1 2 3 4 闪光标
// do while 和 while 较相似

3.4 练习

计算 n 的阶乘。

#include <stdio.h>
int main()
{
    int i = 0;
    int n = 0;
    int sum = 1;
    printf("请输入一个数,将输出这个数的阶乘\n");
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        sum *= i;
    printf("%d的阶乘为:>%d", n, sum);
    
    return 0;
}

计算 1!+2!+3!+……+10!

// 方法一
#include <stdio.h>
int main()
{
    int i = 0;
    int j = 0;
    int n = 0;
    int sum = 0;
    for (n = 1; n <= 10; n++)
    {
        j = 1;
        for (i = 1; i <= n; i++)
            j *= i;   
        printf("%d的阶乘为:>%d\n", n, j);
        
        sum += j;
    }
    printf("1!+2!+3!+……+10!的和为%d",sum);
    
    return 0;
}




// 方法二
#include <stdio.h>
int main()
{
    int i = 0;
    int j = 1;
    int n = 0;
    int sum = 0;
    for (n = 1; n <= 10; n++)
    {
        j *= n;   
        sum += j;
    }
    printf("1!+2!+3!+……+10!的和为%d",sum);
    
    return 0;
}

在一个有序数组中查找具体的某个数字n。

编写int binsearch(int x, int v[], int n);

功能:在v[0]<=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x。

// 方法一  -- O(n)
#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 17;
    int i = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (i = 0; i < sz; i++)
    {
        if (k == arr[i])
        {
            printf("找到了,下标为:%d\n", i);
            break;
        }
    }
    if (i == sz)
        printf("找不到\n");
    
    return 0;
}


// 方法二  -- O(log~2~^n^)
// 折半查找、二分查找算法
#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;

    int sz = sizeof(arr) / sizeof(arr[0]);  // 计算元素个数
    int left = 0; // 左下标
    int right = sz - 1; // 右下标


    while(left <= right)// 即使是left == right 也有一个元素要查找
    {
        int mid = (left + right) / 2; // 中间元素下标
        if (arr[mid] > k)
        {
            right = mid - 1;
        }
        else if (arr[mid] < k)
        {
            left = mid + 1;
        }
        else
        {
            printf("找到了,下标为:%d\n", mid);
            break;
        }
    }
    if (left > right)
        printf("找不到\n");
    return 0;
}

编写代码,演示多个字符从两端移动,向中间汇聚。

#include <stdio.h>
#include <string.h>
#include <Windows.h>  // 调用sleep函数
#include <stdlib.h>  // 调用清屏函数
int main()
{
    char arr1[] = "hello world!!!!!!";
    char arr2[] = "####################";
    int left = 0;
    // char arr[] = "abc";
    // [a b c \0]
    //  0 1 2  3
    // 表示下标时应该 4-2  -- sizeof(arr)/sizeof(arr[0])-2
    // int right = sizeof(arr1)/sizeof(arr1[0])-2;
    int right = strlen(arr1) - 1;
    while (left <= right)
    {
        arr2[left] = arr1[left];
        arr2[right] = arr1[right];
        printf("%s\n", arr2);
        // 休息1秒 -- 1000毫秒
        Sleep(1000);
        system("cls"); // 执行系统命令的一个函数 - cls - 清空屏幕
        left++;
        right--;
    }
    printf("%s\n", arr2);
    return 0;
}

模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确,提示登录成功,如果三次均输入错误,则退出程序。)

#include <stdio.h>
#include <string.h
int main()
{

    int i = 0;
    char password[20] = { 0 };
    for (i = 0; i < 3; i++)
    {
        printf("请输入密码:>");
        scanf("%s", password);
        if (0 == strcmp(password, "123")) // == 不能用来比较两个字符串是否相等,应该使用一个库函数strcmp
        {
            printf("登录成功\n");
            break;
        }
        else
            printf("密码错误\n");
    }
    if (i == 3)
        printf("三次密码均错误,退出程序\n");
    
    return 0;
}

求最大公约数

// 辗转相除法
#include <stdio.h>
int main()
{
    int m = 24;
    int n = 6;
    int r = 0;
    while (r = m % n)
    {
        // r = m % n;
        m = n;
        n = r;
    }
    printf("%d\n", n);
    return 0;
}

打印1000~2000 之间的闰年

// 方法1
#include <stdio.h>
int main()
{
    int year = 0;
    int count = 0;
    for (year = 1000; year <= 2000; year++)
    {
        // 判断闰年的方法:
        // 1. 能被4整除并且不能被100整除是闰年
        // 2. 能被400整除是闰年
        if (0 == year % 4 && 0 != year % 100)
        {
            printf("%d ", year);
            count++;
        }
        else if (0 == year % 400)
        {
            printf("%d ", year);
            count++;
        }
    }
    printf("\n有%d个闰年", count);
    return 0;
}


// 方法二
#include <stdio.h>
int main()
{
    int year = 0;
    int count = 0;
    for (year = 1000; year <= 2000; year++)
    {
        // 判断闰年的方法:
        // 1. 能被4整除并且不能被100整除是闰年
        // 2. 能被400整除是闰年
        if ((0 == year % 4 && 0 != year % 100) || (0 == year % 400))
        {
            printf("%d ", year);
            count++;
        }
    }
    printf("\n有%d个闰年", count);
    return 0;
}

打印 100 ~ 200 之间的素数。

《素数求解的n种境界》

#include <stdio.h>
#include <math.h>
int main()
{
    int i = 0;
    int count = 0;
    for (i = 101; i <= 200; i+=2)
    {    
        int j = 0;
        // sqrt() -- 开平方的数学库函数
        for (j = 2; j <= sqrt(i); j++)
        {
            if (0 == i % j)
            { 
                break;
            }                
        }
        if (j > sqrt(i))
        {
            count++;
            printf("%d是素数\n", i);

        }
    }
    printf("count = %d\n", count);
    return 0;
}

计算1/1-1/2+1/3+1/4+1/5+……+1/99-1/100的值,打印结果。

#include <stdio.h>
int main()
{
    int i = 0;
    int flag = 1;
    double sum = 0;
    for (i = 1; i < 101; i++)
    {
        sum += flag * 1.0 / i;
        flag = -flag;
    }
    printf("sum = %lf", sum);
    return 0;
}

求十个整数中的最大值

#include <stdio.h>
int main()
{
    int arr[] = { -1,-2,-3,-4,-5,-6,-7,-8,-9,-10 };
    int max = arr[0]; // 由于数组中的数都是小于0 的,如果将max初始化为0,则将找不出该数组中的最大值。所以用数组的第一个数对max进行初始化。
    int i = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (i = 0; i < sz; i++)
    {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    printf("max = %d\n", max);
    return 0;
}

打印九九乘法表

#include <stdio.h>
#include <math.h>
int main()
{
    int i = 0;
    int j = 0;
    for (i = 1; i <= 9; i++)
    {
        for (j = 1; j <= i; j++)
            // %xd , x指定的域宽,默认是右对齐的
            // %-xd,x指定的域宽,默认是左对齐的
            printf("%d*%d=%d\t", j, i, i * j);
        printf("\n");
    }
    return 0;
}

猜大小游戏

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void menu()
{
    //system("cls");
    printf("***************************************\n");
    printf("****  1.play         0.exit        ****\n");
    printf("***************************************\n");
}

// 0x123  -- 十六进制
// 0123   -- 八进制
void game()
{
    // 1. 生成一个随机数
    int ret = 0;
    int guess = 0; // 接收猜的数字
    // 拿时间戳来设置随机数的生成起始点
    // time_t time(time_t *timer)
    // time_t
    //srand((unsigned int)time(NULL));

    // rand() 生成 0~0x7fff 的随机值
    ret = rand()%100+1; // 生成1-100之间的随机数
    // printf("%d\n", ret);
    // 2. 猜数字
    while (1)
    {
        printf("请猜数字:>");
        scanf("%d", &guess);
        if (guess > ret)
            printf("猜大了\n");
        else if (guess < ret)
            printf("猜小了\n");
        else
        {
            printf("猜对了\n");
            break;
        }
    }   
}
int main()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("选择错误\n");
            break;   
        }

    } while (input);
    return 0;
}

3.5 goto 语句

  • 不建议使用goto语句。
#include <stdio.h>
int main()
{
again:
	printf("hello bit\n");
	goto again;
	return 0;
}
  • goto语句最常见的用法: 就是终止某些深度嵌套的结构的处理过程,例如一次跳出多层循环。
for(...)
    for(...)
   {
        for(...)
       {
            if(disaster)
                goto error;
       }
   }
    …
error:
 if(disaster)
         // 处理错误情况

希望可以对大家有所帮助,如果有什么不对的地方,还烦请指教,谢谢!


点击全文阅读


本文链接:http://zhangshiyu.com/post/29818.html

语句  循环  表达式  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1