C语言学习--分支和循环语句


在这里插入图片描述

语句结构

C语言是一门结构化的程序设计语言。

C语言的语句结构,从执行流程的角度可以划分出三种基本结构:顺序结构分支(选择)结构循环结构

C语言中由 ; 隔开的就是一条语句。

int main()
{
    int a = 0; // 语句1
    int b = 1; // 语句2
    ;          // 空语句,也是语句
    return 0;  // 语句3 
}

顺序结构

顺序结构就是从上往下的顺序依次执行语句的结构,是C语言最基本的结构。

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a;
    a = b;
    b = c;
    printf("a=%d b=%d\n",a,b );
    return 0;
}

在这里插入图片描述

分支(选择)结构

为了完成不同的任务,我们通常需要给一段执行代码前加上判断条件,来决定是否执行相应的代码,这种结构就成为分支(选择)结构。
在这里插入图片描述

if 语句

if语句分为: if、if else 、if else if … else;

if

int main(){
    if(表达式)  // 如果表达式为真,执行语句1
    { 
        执行语句1; 
    }
               // 表达式为假,继续执行下面语句
    return 0;
}
举例
int main()
{
    int age = 10;
    if(age<18)
    {
        printf("未成年");
    }
    // 单条执行语句可以省略代码块,个人习惯使用代码块,结构清晰。
}

在这里插入图片描述

#include <stdio.h>
int main()
{
    int age = 18;
    if(age<18)
    {
        printf("未成年");
    }

}

在这里插入图片描述

if else

int main()
{
    
    if(表达式) // 如果表达式为真,执行语句1
    {
        执行语句1;
    }  
      
    else {    // 否则,执行语句2
        执行语句2;
    }
    return 0;
}
举例
#include <stdio.h>
int main()
{
    int age = 10;
    if(age<18)
    {
        printf("未成年\n");
    } 
    else 
    {
       printf("成年了\n");    
    }
}

在这里插入图片描述

在这里插入图片描述

if else if … else

// 只能有一个语句块被执行,按顺序从上往下判断
int main()
{
    if(expr1)        // if expr1 is true,  execute statement 1;
    {
        statement1;
    } else if(expr2) // if expr2 is true,  execute statement 2;
    {
        statement2;
    } else if(expr3) // if expr3 is true,  execute statement 3;
    {
        statement3;
    } ...           // ...
      else          // else ,execute  statment4
    {
        statment4;    
    }
    return 0;
}
举例
#include <stdio.h>
int main()
{
    int age = 10;
    if(age<18)
    {
        printf("未成年\n");
    }  
    else if((age>=18)&&(age<28))
    {
        printf("青年\n");
    } 
    //  注意:(18<=age<28) 这种写法是错误的,系统会先判断18<=age,再将判断返回的真值与28比较,为真时返回1<28,为假时返回0<28,这种判断条件永真。
     else if((age>=28)&&(age<60))
    {
        printf("壮年\n");
    } 
     else if((age>=60)&&(age<150))
    {
        printf("老年\n");
    } 
    else
    {
        printf("respect\n");
    }   
    return 0;
}
// 太多了,不截屏了

悬空else 问题

// 下面代码的输出结果?
#include <stdio.h>
int main()
{
	int a = 1;
	int b = 2;
	if (a == 0)
		if (b == 2)
			printf("haha\n");
	else
			printf("hehe\n");
	return 0;
}

在这里插入图片描述

因此建议使用代码块{}将执行语句包裹,会使得程序的结构化更加清晰,编译器也能编译出我们想要的效果。
在这里插入图片描述

if 书写形式对比

例一

下面代码意思是否一样?

if(expr)
{
    return x;
}
return z;
if(expr)
{
    return x;
}
else 
{ 
    return z;
}

上述代码的意思是一样的,return x 会直接跳出当前函数,不会执行return 后面的语句。

因此为了不产生歧义,使用第二种书写方式的代码风格是更加清晰的。

例二

下面代码的输出结果为?

int main()
{
    int a = 0;
    if(a = 1)
    {
        printf("1\n");
    }
    else
    {
        printf("0\n");
    }
    return 0;
}

输出结果为1, 因为 =赋值操作符,等于给a重新赋值为1,条件永真。

为了避免这类错误,可以将常量放在 == 右侧,变量放在 == 左侧

int main()
{
    int a = 0;
    if(1 == 0) // 这样书写即使少写一个 = 代码也会报错
    {
        printf("1\n");
    }
    else
    {
        printf("0\n");
    }
    return 0;
}

练习

判断一个数是否为奇数

先分析:

  1. 奇数不能被2整除的整数,假设奇数x,则x%2=1;
#include <stdio.h>
int main()
{
    int num = 0;
    printf("请输入一个整数>:");
    scanf("%d", &num);
    if (1 == num % 2)
    {
        printf("%d is a odd number\n", num);
    }
    else
    {
        printf("%d is a even number\n", num);
    }
    return 0;
}
输出1~100之间的奇数

分析:

  1. 奇数是不能被2整除的整数,假设奇数x,则x%2=1;

  2. 偶数一定是2的倍数,1一定是奇数,因此从1开始查找每次+2,跳过所有偶数。

  3. 利用循环遍历1~100的数。

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

switch语句

switch语句常用于多分支情况

语法

switch(int_expr) 
{
    case const_expr1: 
            statement1;
    case const_expr2: 
            statement2;
            break;
    case const_expr3: 
        	statement3;
    ...
    default :
        	statment4;
        	break;
}
  1. switch语句中的表达式(int_expr)必须是整型表达式

  2. case 后面的表达式(const_expr)必须是整型常量表达式

  3. int_expr 会按照顺序结构从上往下依次对比 const_expr,哪个相等就从哪个case开始执行。

  4. 当执行完毕后,如果case里的执行语句含有break;跳出当前switch语句,如果没有break;则继续执行下面的case

  5. 当所有expr与所有case的 const_expr 都不相等,如果有 default 默认执行 default 里面的语句。如果没有则结束switch语句。

  6. default 的位置不影响switch语句的执行顺序。

  7. 分支语句中不能使用continue;

举例

#include <stdio.h>
int main()
{
	int a = 0;
	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;
	default:
		printf("输入值不正确\n");
         break;
	}
	return 0;
}

如果case中没有break; 执行继续执行当前case之后的语句,直到遇到break; 或者switch语句全部执行完毕。

// 例如将说有break;删除,并输入1,查看最终的输出结果
#include <stdio.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	switch (a)
	{
	case 1:
		printf("星期一\n");
	case 2:
		printf("星期二\n");
	case 3:
		printf("星期三\n");
	case 4:
		printf("星期四\n");
	case 5:
		printf("星期五\n");
	case 6:
		printf("星期六\n");
	case 7:
		printf("星期天\n");
	default:
		printf("输入值不正确\n");
	}
	return 0;
}

结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9Fp54NS-1623408611999)(pic/image-20210609124049454.png)]

练习

下面代码的输出结果为?

#include <stdio.h>
int main()
{
    int n = 1;
    int m = 2;
    switch(n)
    {
        case 1: m++;
        case 2: n++;
        case 3:
            // switch语句可以嵌套使用
            switch(n)
            {
                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

代码分析
int main()
{
    int n = 1;
    int m = 2;
    switch(n)
    {
        case 1: m++; // n = 1首先进入 case 1:m++; m = 2 + 1 = 3
        case 2: n++; // 接着 n++; n = 1 + 1 = 2
        case 3:      // 接着 进入 case 3:
            switch(n)
            {
                case 1 : n++;
                case 2 :   // n = 2 进入 case 2:
                    m++;   // m = 3 + 1 = 4
                    n++;   // n = 2 + 1 = 3
                    break; // 跳出当前的这个嵌套的switch
            }
        case 4:    // 继续执行 case 4: 
            m++;   // m = 4 + 1 = 5
            break; // 跳出当前switch循环
        default:
            break;
    }
    printf("m = %d, n = %d\n", m,n); // m = 5 n = 3
    return 0;
}

循环结构

  1. 循环结构(语句),有规律的执行重复的操作,被重复执行的语句称为循环体
  2. 循环语句中的判断表达式用于判断循环的终止条件。
  3. 条件为真继续循环,条件为假终止循环。
  4. 循环语句分为3种:whilefordo while

while循环

先判断,当表达式为真进入循环,为假终止循环。

注意切勿使while循环的判断表达式永真,会成为死循环

在这里插入图片描述

语法

while(expr)
{  // 循环体
    statement;
}
举例

打印1~10

分析:

#include <stdio.h>
int main()
{
    int i = 1;
    while(i<=10) // 当i>10时 条件式为假,结束循环
    {
        printf("%d ", i);
        i++;
    }
    return 0;
}

break和continue

break 终止整个循环

// 假如你买了5个包子,当吃到第三个时,你开始拉肚子...
int main()
{
    int i = 1;
    while (i <= 5)
    {
        printf("正在吃第%d包子\n", i);
        if (3 == i)
        {
            printf("拉肚子了,上医院\n");
            break;
        }
        i++;
    }
    return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOpLyD2n-1623408612000)(pic/image-20210609143648144.png)]

continue 跳出本次循环,后面的代码本次不再不执行,继续下次循环

// 假如你买了5个包子,当吃到第三个时,吃到一个虫子...
int main()
{
    int i = 1;
    while (i <= 5)
    {
        printf("正在吃第%d包子\n", i);
        if (3 == i)
        {
            printf("有虫子,丢掉,接着吃\n");
            i++; 
            continue;
        }
        i++; 
        
    }
    return 0;
}

在这里插入图片描述

注意

continue 后面如果有对条件表达式中变量的操作,例如 ++ – 等,很容易造成死循环。

// 例如上面的代码
int main()
{
    int i = 1;
    while (i <= 5)
    {
        printf("正在吃第%d包子\n", i);
        if (3 == i)
        {
            printf("有虫子,丢掉,接着吃\n");
            // i++; 这里如果不写i++,就变成死循环
            // i == 3时 跳出本次循环,i没有+1,i == 3,继续进入if语句,一直重复就变成死循环了
            continue;
        }
        i++; 
    }
    return 0;
}

while循环的一些实际应用

下面代码的意思是?

#include <stdio.h>
int main()
{
    int ch = 0;
    while((ch= getchar()) != EOF)  // getchar 接收一个字符,当 ch == EOF时,终止循环。 
        putchar(ch);               // putchar 输出一个字符
    return 0;
}

这段代码的意思是当 ch != EOF时一直进行循环, 当getchar()读取到文件末尾或者是读取错误时,返回EOF,此时退出循环。

关于介绍getchar(void)、putchar(int_char)和 EOF。

getchar(void)

从标准输中接收一个无符号字符,并且一次只能接收一个字符

返回值:
  1. 成功键入则返回这个键入的字符的ASCII,类型为int。
  2. 读取错误或者到达文件末尾则返回EOF(-1)。
  3. ctrl+z 在DOS中被解释为文档结束。

在这里插入图片描述

putchar(int_char)

输出一个字符到标准输出,输出的字符会被转为unsigned char。

返回值
  1. 输出成功则返回输出的字符的ASCII码值。
  2. 输出错误则返回EOF。
EOF
  1. End of file 文件结束标志,是在stdio.h文件中被#define定义的宏常量。

  2. EOF == -1,在<stdio.h> 文件中可以看到EOF被定义为-1。

  3. 被用于一些在头文件里的函数返回的值,标志着文件的结束或者其他一些错误的情况。

  4. 也被用于代表一个无效字符的值。

在这里插入图片描述

大佬关于EOF的解释

举例解释
int main()
{
    char ch = getchar(); // 接收为字符型
    printf("%d\n", ch);  // 输出ASCII值
    putchar(ch);         // 输出为字符型
    return 0;
}
  1. 当在键盘键入5时,getchar() 接收到的输入实际上是字符’5’。
  2. 而接收这个输入的变量 ch 也为字符型变量,因此直接将’5’存入变量中。
  3. 在打印时可以看到printf()是以十进制格式打印ch里面的值,打印结果为是字符‘5’所对应的ASCII码值。
  4. getchar()输出的的依然是字符型‘5‘。

在这里插入图片描述

int main()
{
	int ch = 0;
	int count = 1;
	while ((ch = getchar()) != EOF) 
	{
		printf("\n%d.--------------\n", count);
		printf("ch接收到字符所对应的ASCII值%d\n", ch);  
		putchar(ch);         // 输出为字符型  9
		count++;
	}
	return 0;
}
  1. 这次使用整型类型的变量int来接收getchar()的值,getchar()接收到的值都为字符型,而ch为整型,因此ch实际接收到的值为输入字符所对应的ASCII码值。

  2. 并且,因为getchar()一次只能接收一个字符,所以在while的循环里会将getchar()所接收到的每一个字符和最后确认时键入回车存入的**\n**的值赋给ch,每次都会把ch之前的值给替换掉。

在这里插入图片描述

int main()
{
    printf("%c\n",getchar()); // 返回键入的字符
    return 0;
}

在这里插入图片描述

int main()
{
    printf("%d\n",getchar()); // 返回键入的字符对应的ASCII值
    return 0;
}

在这里插入图片描述

下面代码的意思是?

int main()
{
    int ch = 0
    while((ch = getchar()) != EOF)
    {
        if((ch < '0') || (ch>'9'))
        {
            continue;
        }
        putchar(ch);  // 只打印0~9的字符
    }
    
    return 0;
}

for循环

for循环的优势

通过while循环的学习,不难发现,while循环经常配合循环变量、判断表达式和对循环变量的调整来完成一个while循环的基本操作。

//while循环存在的问题
int main()
{
	int i = 0;     // 循环变量初始化
	while (i < 10) // 判断表达式
	{
		i++;      // 循环变量的调整
	}
	return 0;
}

但是,三个部分的布局比较分散,特别实在代码量非常多时,如果想要对这三个部分进行修改,很容易出现错误。

而for循环是将这三个部分布局在一个括号()内,对其进行修改是不容易犯错,结构也更加清晰。

在这里插入图片描述

语法

for (初始化表达式;判断表达式;调整表达式)
    // 只有第一次进入for循环时会执行初始化表达式
    // 之后的循环都是对循环变量的调整和调整后对表达式的判断。
    // 最后一个表达式不用加;
{
    循环体;
}

初始化表达式用于初始化循环变量,判断表达式用于作为for循环的判断条件,调整表达式用于调整循环变量的值。

举例

打印1~10

#include <stdio.h>
int main()
{
    int i = 0;
      // 初始化; 判断; 调整
    for( i = 1; i<=10; i++ )
    {
        printf("%d ", i);
    }
    return 0;
}

执行流程:

  1. 第一次进入for循环 执行i = 1,并判断i<=10是否为真,为真进入循环执行循环体。

  2. 循环体执行完毕后,来到调整表达式对i++。

  3. 然后继续判断i<=10是否为真,为真进入循环体。

  4. …不断循环

  5. 直到 i <= 10 为假,结束循环。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6DGBpyhv-1623408612006)(pic/image-20210611102730431.png)]

break和continue

break在for和while中的作用一样都是终止整个循环。

coutinue在for和while中使用有些差异:

  1. while循环中如果调整表达式写在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 死循环
  1. for循环中,调整表达式是每次循环必须要执行的,因此不受continue的影响。
int main()
{
    int i = 0;
    // 初始化; 判断; 调整
    for (i = 1; i <= 10; i++)
    {
        if (5 == i)
        {
            continue;
        }
        printf("%d ", i);
    }
    return 0;
}
// 1 2 3 4 6 7 8 9 10

注意

for循环体中不要随便改变循环变量的值,防止for循环失去控制

// 这段结果的代码是?
int main()
{
    int i = 0;
    for(i = 0;i < 10; i++)
    {
        if(i = 5)
        {
            printf("efg");
        }
        printf("abc");
    }
    return 0;
}
// 无限打印efg的死循环
// 因为i = 5 不是判断,而是赋值

for循环的表达式建议使用前闭后开区间的写法。

int i = 0;
//前闭后开的写法
for(i=0; i<10; i++)
{}

//两边都是闭区间
for(i=0; i<=9; i++)
{}

for循环的一些特殊写法

例1
 // 死循环
int main()
{
	for (;;)
	{
		printf("abc");
	}
	return 0;
}
  1. for循环的初始化、条件判断、调整表达式都可以省略。

  2. for循环的判断部分,如果被省略,那么判断条件就是永真。

  3. 如果不是非常熟练,建议不要随便省略。

为什么不能随便省略?看下面例子

例2
// 下面的打印结果是?
int main()
{
	int i = 0;
	int j = 0;
	for (; i < 10; i++)
	{

		for (; j < 10; j++)
		{
			printf("%d ", i * j);
		}
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyYnoIyq-1623408612007)(pic/image-20210611114804531.png)]

从结果也能猜出来,只有 i = 0 时,进入了 j 循环打印了结果。

因为 j 的初始 在两个for循环外面,当第一个内存for循环结束时j == 10,并且当进行第二次外层for循环时,j已经等于10,j也没有被初始化,不满足内层for循环的条件,所以无法进入内层for循环。

例3
// 下面代码打印几次abc?
int main()
{
    int x = 0;
    int y = 0;
    for (x = 0,y = 0; x<2 && y < 5; ++x, y++)
    {
        printf("abc\n");
    }
    return 0;
}
// 打印2次abc 

练习

下面的for循环会循环多少次?

int main()
{
    int i = 0;
    int k = 0;
    for (i = 0, k = 0;k = 0; i++, k++)
        k++;
    return 0;
}
// 0次 表达式是 k = 0,而不是 k == 0, 0代表假,不进入for循环。

do while 循环

while循环的执行流程是先判断,再根据判断选择是否进入循环体。

而do while循环的执行流程是先执行循环体,循环体执行完毕后,再来判断是否再次进入循环体。
在这里插入图片描述

语法

do 
{
    循环体;
} while(表达式);
举例

打印1~10

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

	return 0;
}

break和continue

break和continue在do while 语句中,功能类似于在while语句中,按照上面的例子,continue在do while 语句中也会出现死循环。

练习

求n的阶乘

描述

计算n!,并输出。

分析
  1. n! = 1 * 2 * 3 * … * (n-1) * n=(n-1)!*n
  2. 创建一个变量n用来作用for循环的判断条件。
  3. 创建一个变量fac用来存放结果。
  4. 考虑到要给变量定义类型,如果n的数值太大可能放不下,因此加上一个判断条件。
代码实现
int main()
{
    int n = 0;
    int fac = 1;
    int i = 0;
    scanf("%d", &n);
    if (n <= 10)
    {
        for (i = 1; i <= n; i++)
        {
            fac *= i;
        }
        printf("%d\n", fac);
    }
    else {
        printf("数值过大");
    }
    return 0;
}

求1~10阶乘的和

描述

求1!+2!+…+10!,并输出。

分析
  1. n! = (n-1)!*n

  2. 创建变量fac存放每次数阶乘的结果

  3. 创建变量sum存放阶乘相加的和。

代码实现
int main()
{

    int fac = 1;
    int sum = 0;
    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        fac *= i;
        sum += fac;
    }
    printf("%d\n", sum);
    return 0;
}

水仙❀数

描述

求水仙花数,并输出

分析
  1. 十进制数中的一个三位数,它每一位数的3次幂之和等于数本身的就是水仙花数。
  2. 限制查找范围,创建变量x存放水仙花数,100<=x<1000。
  3. 求x上每一位数,创建变量h, t, o 分别存放百位 十位 个位上的数。
  4. 判断,如果三个数的3次幂的和等于x 则打印这个数。
代码实现
int main()
{
    int x = 0,h = 0,t = 0, o = 0;
    for(x = 100;x<1000;x++)
    {
        h = x / 100;      // 商为百位数
        t = x / 10 % 10;  // 商为百位+十位再%10为十位数
        o = x % 10;       // 余数为个位数
        if(((h*h*h)+(t*t*t)+(o*o*o)) == x)
        {
            printf("%d ", x);
        }
    }
    
    return 0;
}

有序数组查找(二分查找)

描述

在一个有序数组中查找具体的数字n,并输出它的下标。

分析
  1. 有序数组的查找使用二分查找算法
  2. 创建变量n 用于接收要查找的数字。
  3. 创建变量 left 接收数组第一个数的下标,创建变量 right 接收数组最后一个数的下标,创建变量 mid 接收数组中间位数的下标。
  4. left = 0,right = 数组长度 - 1, mid = (left + right) / 2。
  5. 利用mid作为数组下标号,查找数组中间位数。
  6. 如果大于被查找数,则范围缩小至mid的左侧,right = mid - 1, left 不变。
  7. 如果小于被查找数,则范围缩小至mid的右侧,left = mid + 1 , right 不变。
  8. mid的值需要随着 left 和 right的改变而改变,因此需要放在循环体中。
  9. 如果找到数字n,直接break; 终止循环。
  10. 如果直到 left>right,n还没有被查找到,则不存在于这个数组中。
代码实现
int main()
{
    int n = 0;
    scanf("%d", &n);
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int length = sizeof(arr) / sizeof(arr[0]);
    int left = 0;
    int right = length - 1;
    while (left <= right)
    {
        int mid = (left + right) / 2;
        if (arr[mid] > n)
        {
            right = mid - 1;
        } 
        else if (arr[mid] < n)
        {
            left = mid + 1;
        }
        else 
        {
            printf("找到了,下标为: %d\n", mid);
            break;
        }
    }
    if (left > right)
    {
        printf("找不到");
    }

    return 0;
}
// 
// 
  1. 如果用穷举法计算,有n个数则最大查找次数是n次。
  2. 而如果使用二分查找算法,等于n 不断的除以2,每次排除掉一半,直到除以2 = 1 ,而这中间所循环的次数 x 就是最大查找次数。2 x = n, x = log2n
  3. 可以看到假如查找的个数为232, 穷举法最大查找次数是 232 次,而二分查找法的最大查找次数是32次,效率十分的高。

动态打印字符

描述

编写代码实现字符从两端移动,向中间汇聚。

// 实现效果
// w###################!
// we#################!!
// wel###############!!!
// ...
// welcome t###it !!!!!!
// welcome to#bit !!!!!!
// welcome to bit !!!!!!
分析
  1. 首先准备2个字符数组,str1 存放全#,str2 存放最终打印效果。
  2. 利用循环每次将str2下左右下标的字符赋值给str1对应下标的字符。
  3. 因此需要变量left和right来存放数组的下标,left = 0,right = 字符串长度 - 1。
  4. 如果使用sizeof计算字符串长度,因为字符串默认在结尾隐藏一个\0,则需要减去2;不过可以使用strlen() 来计算字符串长度,strlen()不会统计\0的个数。
  5. 每次循环left+1,right-1。
  6. left == right 时最后一个字符被赋值, 因此循环的判断条件为 left > right。
代码实现
#include <stdio.h>
#include <string.h>
#include <windows.h> // 使用sleep函数 需要引用头文件
#include <stdlib.h>  // 使用system函数 需要引用头文件
int main()
{
	char str1[] =  "#####################" ;
	char str2[] =  "welcome to my blog!!!" ;
	int left = 0;
	int right = strlen(str1) - 1;
	while (left <= right)
	{
		str1[left] = str2[left];
		str1[right] = str2[right];
		printf("%s\n", str1);
		// 每打印一次休息1s
		Sleep(1000); //  sleep函数需要引用<windows.h> 头文件
		// 休息一秒后清屏
		if (left != right)
		{   // 加这个if是为了防止最后一次被清屏
			// 执行系统命令的函数, cls- 清空屏幕命令
			system("cls");
			// 使用system函数 需要引用头文件<stdlib.h> 
		}
		left++;
		right--;
	}
	
	return 0;
}

模拟用户登录

描述

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

分析
  1. 打印提示用户输入账号密码。
  2. 创建字符数组account、passwd 来接收用户输入的账户和密码。
  3. 利用for循环来判断如果用户输入的账户密码是否等于设定的值。
  4. 如果等于则提示登录成功,break; 终止循环,否则继续循环。
  5. 等号不可以判断字符串是否相等,应该使用库函数–strcmp()。
  6. 当三次均不等于结束循环,提示用户登录失败。
代码实现
#include <stdio.h>
#include <string.h>
int main()
{
	char account[20] = "";
	char passwd[20] = "";
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("请输入账号:>");
		scanf("%s", account);
		printf("请输入密码:>");
		scanf("%s", passwd);
		if ((strcmp(account,"joker") == 0) && (strcmp(passwd,"123456") == 0))
		{
			printf("登录成功\n");
			break;
		}
		else
		{
			if (!(strcmp(account, "joker") == 0))
			{
				printf( "未匹配到相关账户\n" );
			}
			else
			{
				printf("密码错误\n");
			}
		}
	}
	if (3 == i)
	{
		printf("登录失败\n");
	}
	
	return 0;
}
strcmp(str1,str2)

string compare

判断两个字符串是否相等使用strcmp(str1,str2)函数,strcmp函数会从两个字符的第一个字符开始对比它们的ASCII码值,直到其中有字符不同或者遇到\0结束。

返回值
  1. 两个字符串完全相等返回0。
  2. 不相等的两个字符中,str1的字符比str2的字符ASCII值小,返回<0的数值。
  3. 不相等的两个字符中,str1的字符比str2的字符ASCII值2,返回>0的数值。



  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值