C语言学习记录——유 分支与循环(2)

目录

一、循环结构

for循环

for循环控制变量

变种1

变种2

do—while循环

二、练习

1、计算n的阶乘

2、计算1!+2!+3!。。。10!

3、在一个有序数组中查找具体的某个数字n,编写int binsearch(int x, int v[], int n);功能:在v[0] <= v[1] <= v[2] <= ...<= v[n-1]的数组中查找x。

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

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


一、循环结构

接着之前的继续写。写一个程序

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;
}

当真正开始输入时,我们会发现结果并不是我们想象的结果,会是输入密码之后请确认y或者n之后直接就是放弃确认。按照我们所想象的那两个应该是输入密码之后,然后要去判断,看看是不是Y,然后再去就确认成功或者放弃确认。但是无论怎么样,他都会直接输出一个放弃确认,所以说这就会发现一些问题。为什么出现问题?要仔细看这一个代码。输入密码之后,scarf这个函数,它就会去读取密码,但scanf和下面的get char都会去读取一个地区叫做输入缓冲区,我们所输入的东西都在这个输入缓冲区里边,当程序刚开始的时候输入缓冲区是空的,什么都没有,所以这时候scanf就在等待,等待你输入。当我们输入了比如说123456之后,但是我们输入数字之后空格一下,后面会有自带的\n,这是一个自带的,也就是我们输入到输入缓冲区里边儿的是123456\n,而scanf函数要读取这个密码,它一旦读取之后呢它读取了123456,它就会去拿走这个123456这个密码,而剩下的这个\n它的ANCII码值是10,后面的getchar会再去读取得到一个10,10并不是Y,所以说它会直接输入放弃确认。那么修改一下。

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

在scanf后加了一个getchar,这样就读取走了10,之后的getchar就会等待输入Y/N。但是这样仍然错误。如果我们输入123456 ABCD  。123456空格ABCD空格,那么最后的getchar读取走了ABCD,仍然错误。再次改进,用循环来持续读取:

    int ret = 0;
    int ch = 0;
    char password[20] = { 0 };
    printf("请输入密码: >");
    scanf("%s", password);
    while ((ch = getchar()) != '\n')
    {
        ;
    }
    printf("请输入(Y/N): >");
    ret = getchar();

把getchar()改为while循环,这样就会让scanf一直读取。避免出现错误。继续再看一个代码:

    int ch = 0;
    while ((ch = getchar()) != EOF)
    {
        if (ch < '0' || ch > '9')
            continue;
        putchar(ch);
    }
    return 0;

只打印零到9的数字

for循环

前面已经讲到一些:for(expr1;expr2;expr3)

                                           循环语句

写一个简单的程序

    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        if (i == 5)
            break;
        printf("%d ", i);
    }

break跳出循环,与while中作用一致,而continue有点不同,和之前一段讲述break和continue的结果一样。

写一下while的:

    int i = 0;
    while (i <= 10)
    {
        if (i == 5)
            continue;
        printf("%d\n", i);
        i++;
    }

for中不会死循环,因为赋值,判断后,就执行if语句,continue后就来到i++,所以不会死循环。

for循环控制变量

1、不可在for循环体内改变循环变量,防止循环不受控制

    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        if (i = 5)
            printf("haha ");
        printf("hehe ");
    }

如果是这样,程序就会死循环。当到达if这一步时,i被赋值为5,打印hehehaha,而回到i++,再到i = 1,会发现循环一直进行,无法停止。

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

for(i = 1; i < 10)  这样就是前闭后开。习惯问题,10就好像代表着10次循环一样,只是一种习惯问题。

变种1

for语句初始化(赋值), 判断,调整都可以省略,但是判断省略后就表示条件恒为真,需谨慎使用。具体看一个例子:

    int i = 0;
    for (i = 0; i < 10; i++)
    {
        int j = 0;
        for (j = 0; j < 10; j++)
        {
            printf("hehe\n");
        }
    }

会打印100个hehe,但是程序可能会感觉繁琐了。前有i = 0了,for语句是否需要再说一遍,如果去掉for语句的初始化部分,结果是十个hehe

变种2

也有多种条件的:

    int x, y;
    for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
    {
        printf("hehe\n");
    }

此外看一道题:

    int i = 0;
    int k = 0;
    for (i = 0, k = 0; k = 0; i++, k++)
    {
        k++;
    }

循环根本不进入,k加为1后,到了k = 0后判为假,就退出了。

do—while循环

do

      循环语句;

while(表达式)

打印1~10:

int main()
{
    int i = 1;
    do
    {
        printf("%d ", i);
        i++;
    } while (i <= 10);
    return 0;
}

do后有大括号才能写多个语句,否则只能写一个,其他循环也是如此,if,else,elseif下面必须有没有大括号就只能写一行。打印出1后,变为2,2 <=  10,然后再回到循环中,直接进入循环,打印2.....。do while也有break,continue。break总是终止循环,所以只有1234。continue跳过printf,i++,直接到while,然后又回到判断方面,i还是5,形成死循环。

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

到现在为止,所有循环都已经学完,需要做一些总练习。

二、练习

1、计算n的阶乘

int main()
{
    int i = 0;
    int n = 0;
    int ret = 1;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {
        ret = ret * i;
    }
    printf("%d\n", ret);
    return 0;
}

2、计算1!+2!+3!。。。10!

    int n = 0;
    int ret = 1;
    int sum = 0;
    for (n = 1; n <= 10; n++)
    {
        ret = ret * n;
        sum = sum + ret;
        printf("加到%d!: %d\n", n, sum);
    }

3、在一个有序数组中查找具体的某个数字n,编写int binsearch(int x, int v[], int n);功能:在v[0] <= v[1] <= v[2] <= ...<= v[n-1]的数组中查找x。

    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int k = 7;
    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;

但是不够有效,折中想法。

    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)
    {
        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;

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


#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>

    char arr1[] = "welcome to world!!!!";
    char arr2[] = "********************";
    int left = 0;
    int right = strlen(arr1) - 1;
    while (left <= right)
    {
        arr2[left] = arr1[left];
        arr2[right] = arr1[right];
        printf("%s\n", arr2);
        Sleep(1000);
        system("cls");//执行系统命令的一个函数cls---清空屏幕
        left++;
        right--;
    }
    return 0;

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

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

如果字符串相等,strcmp返回0。第一个大于第二个,返回大于0的数值,小于则返回小于0的数值。

以上练习需反复琢磨,新手期需要这样的代码。

结束。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值