嵌入式Linux学习路线分享---C语言(3)

目录

一、C语言常用的输入输出函数

1.putchar()/getchar()

1.1putchar()

1.2getchar()

2.puts()/gets()

2.1puts()

2.2gets()

3.printf()/scanf

3.1printf()

3.2scanf()

二、分支控制语句

1.if..else 语句

1.1格式

1.2 if..else语句注意事项

2.switch..case 语句

2.1 格式

2.2 注意事项

三、循环控制语句

1. goto实现循环

2.while 循环

3. do..while 循环

4. for循环

5. C语言中求次方和开平方的函数

5.1 pow()函数

5.2 sqrt()函数

6. 死循环

四、辅助控制关键字

1. break

2. continue

3. return

五、控制语句综合练习


一、C语言常用的输入输出函数

1.putchar()/getchar()

1.1putchar()

功能:

向终端输出一个字符

头文件:

#include

函数原型:

int putchar(int c);

参数:

c : 要输出的字符

#include <stdio.h>

int main(int argc, const char *argv[])
{
	//可以直接输出一个字符
	putchar('M');
	putchar('\n');

	//也可以输出字符的 ascii 码
	putchar(77);
	putchar(10);

	//也可以传一个保存的字符的变量
	char value = 'M';
	putchar(value);
	putchar(10);

	//也可以传一个能计算出字符ascii码的表达式
	putchar('D'-3);//A
	putchar('\n');
	
	return 0;
}

1.2getchar()

功能:

从终端获取一个字符

头文件:

#include

函数原型:

int getchar(void);

#include <stdio.h>

int main(int argc, const char *argv[])
{
#if 0
	char v1 = 0;
	v1 = getchar();
	printf("v1 = %d [%c]\n", v1, v1);
#endif
	char v1 = getchar();
	getchar();//清理垃圾字符 回车
	char v2 = getchar();
	getchar();
	char v3 = getchar();
	printf("v1 = %d [%c]\n", v1, v1);
	printf("v2 = %d [%c]\n", v2, v2);
	printf("v3 = %d [%c]\n", v3, v3);

	return 0;
}

2.puts()/gets()

2.1puts()

功能:

向终端输出一个字符串,自带换行

头文件:

#include

函数原型:

int puts(const char *s);

参数:

s : 要输出的字符串

#include <stdio.h>

int main(int argc, const char *argv[])
{
	//可以直接输出字符串
	puts("hello world");

	//也可以输出保存字符串的数组的首地址
	char str1[] = "www.hqyj.com";
	puts(str1);

	//也可以输出指向字符串常量的指针
	char *p = "DC22021";
	puts(p);

	//puts 输出字符串时遇到 \0 就结束了
	puts("www.b\0aidu.com");// www.b

	return 0;
}

2.2gets()

功能:

从终端获取一个字符串

头文件:

#include

函数原型:

char *gets(char *s);

参数:

s : 要保存输入字符串的缓冲区的首地址

返回值:

成功返回获取的字符串

失败返回NULL

#include <stdio.h>

int main(int argc, const char *argv[])
{
	//缓冲区要足够大,否则可能出现访问越界的风险
	char str[32];

	gets(str);//输入  遇到回车结束输入
             //gets可以获取带有空格的字符串

	puts(str);//输出

	return 0;
}

3.printf()/scanf

3.1printf()

功能:

向终端按照一定格式输出一个字符串,----格式化输出

头文件:

#include

函数原型:

int printf(const char *format, ...);

参数:

format : 格式

%c 输出字符

%d 输出十进制整型

%u 按无符号输出十进制整型

%o 输出八进制整型

%x 输出十六进制整型

%f 输出浮点型

%e 按指数形式输出

%% 输出%

附加格式说明:

l 输出long 或者long long 或者double时会用到

# 按照八进制或十六进制输出时 输出前导符 0 0x

m m是一个实际的数字,表示输出数据的位宽

0 指定位宽后,不足的宽度用0来补

- 左对齐

+ 输出正数时 带正号

.n 保留n位小数

...:可变参

#include <stdio.h>

int main(int argc, const char *argv[])
{
	unsigned char a = 255;
	printf("%u\n",a);

	int hour = 13;
	int min = 45;
	int sec = 6;
	// 13:45:06
	printf("%02d:%02d:%02d\n", hour, min, sec);

	printf("hour=%d\n", hour);
	printf("hour=%8d\n", hour);
	printf("hour=%-8d\n", hour);
	hour = -5;//如果是负数  +号就不显示了
	printf("hour=%+d\n", hour);

	hour = 12345;
	printf("hour=%3d\n", hour);//指定的位宽不够时,以实际为准

	return 0;
}

3.2scanf()

功能:

从终端按照一定格式获取数据,----格式化输入

头文件:

#include

函数原型:

int scanf(const char *format, ...);

参数:

format:格式 类似于printf 的格式

scanf的格式是怎么的,就要怎么输入,否则获取不到

... :可变参,需要写存储改输入的地址需要用到&

#include <stdio.h>

int main(int argc, const char *argv[])
{
#if 0
	int hour = 0;
	int min = 0;
	int sec = 0;

	//输入时 必须以 - 分隔,否则获取不到
	scanf("%d-%d-%d", &hour, &min, &sec);

	printf("%02d:%02d:%02d\n", hour, min, sec);
#endif

#if 0
	//---------------char-----
	char a;
	scanf("%c", &a);
	putchar(a);
#endif

#if 0
	//----------------int-----
	int b;
	int c;
	scanf("%d%d", &b, &c);//输入时 以空格或回车分隔 都可以
	//%d 输入的就必须是整数
	printf("b = %d   c = %d\n", b, c);
#endif

#if 0
	//--------------long------------
	long d;
	scanf("%ld", &d);
	printf("d = %ld\n", d);
#endif

#if 0
	//--------------float-----------------
	float f1;
	float f2;
	scanf("%f%f", &f1, &f2);
	printf("f1 = %f   f2 = %f\n", f1, f2);
#endif
	
	//----------------string-------------------
#if 0
	char str[32];
	scanf("%s", str);//数组名本身就是首地址  无需加 &
	puts(str);
#endif
	//scanf 直接使用%s 无法获取带有空格的字符串
	//可以使用 gets() 来获取
	
	//也可以使用下面的方式获取
	char str[32];
	scanf("%[^\n]", str);
	puts(str);

	return 0;
}

垃圾字符的处理:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	char a, b, c;

	//垃圾字符场景1 :scanf中连续使用多个%c
	//scanf("%c%c%c", &a, &b, &c);
	
	//处理方式1:多个%c 之间使用空格分隔
	//scanf("%c %c %c", &a, &b, &c);
	//处理方式2:使用 抑制符 来处理 
	//--这种方法 要谨慎使用 因为正常的字符也会被吃掉
	scanf("%c%*c%c%*c%c", &a, &b, &c);
	printf("a = %d [%c]\n", a, a);
	printf("b = %d [%c]\n", b, b);
	printf("c = %d [%c]\n", c, c);


	//垃圾字符场景2 :多个scanf %c 连续调用时
	scanf("%c", &a);
	getchar();
	scanf("%c", &b);
	getchar();
	scanf("%c", &c);

	//场景3:如果不知道前面输入了什么,而要获取一个字符时
	char d;
	%c 前面加一个 空格 来清空所有的垃圾字符
	scanf(" %c", &d);

	return 0;
}

二、分支控制语句

C语言的程序结构只有三种:顺序结构、分支结构(选择结构)、循环结构。

1.if..else 语句

1.1格式

1.简化格式:
    if(表达式){
        //代码块
    }
    执行逻辑:如果表达式为真 则执行代码块,否则不执行代码块
    
    if(表达式){
        //代码块1
    }else{
        //代码块2
    }
    执行逻辑:如果表达式为真 则执行代码块1,否则执行代码块2

2.阶梯格式
    if(表达式1){
        //代码块1
    }else if(表达式2){
        //代码块2
    }else if(表达式n){
        //代码块n
    }else{
        //其他分支
    }
    执行逻辑:如果表达式1为真 则执行代码块1,
        否则继续判断表达式2,如果表达式2为真 则执行代码块2
        ....依次类推
        之前else分支之前的所有表达式如果都为假,则执行else分支
        
3.嵌套格式
    if(表达式1){
        //代码块1
        if(表达式11){
            //代码块11
            if(表达式111){
                //代码块111
            }else{
                //代码块112
            }
        }else{
            //代码块12
        }
    }else if(表达式2){
        //代码块2
    }else if(表达式n){
        //代码块n
    }else{
        //其他分支
    }
    执行逻辑:阶梯形式的嵌套使用              

例:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int m = 10;
	int n = 20;
 //简化格式
	printf("-----start----\n");
	if(m > n){
		printf("yes\n");
	}
	printf("-----end----\n");

	printf("--------------------------------------\n");
 //简化格式
	printf("-----start----\n");
	if(m > n){
		printf("yes\n");
	}else{
		printf("no\n");
	}
	printf("-----end----\n");

	printf("--------------------------------------\n");
 //阶梯格式
	printf("-----start----\n");
	if(m < 0){
		printf("m<0\n");
	}else if(n < 0){
		printf("n<0\n");
	}else{
		printf("m>0 n>0\n");	
	}
	printf("-----end----\n");

	printf("--------------------------------------\n");
 //嵌套格式
	printf("-----start----\n");
	if(m > 0){
		printf("m>0\n");
		if(m>5){
			printf("m>5\n");
		}else{
			printf("m<5\n");
		}
	}else{
		printf("m<=0 n>0\n");	
	}
	printf("-----end----\n");

	return 0;
}

从终端输入一个字符

如果是大写的,转换成小写输出

如果是小写的,转换成大写输出

如果是0-9,输出对应的整型的 0-9

其他字符输出 #

#include <stdio.h>

int main(int argc, const char *argv[])
{
	char num = 0;
	printf("请输入一个字符:");
	scanf("%c", &num);
/*
	if(num 是大写){
		转换成小写
	}else if(num 是小写){
		转换成大写
	}else if(num  [0,9]){
		转换成整型 0-9
	}else{
		输出 #
	}
*/
	if(num >= 'A' && num <= 'Z'){
		num += 32;
		printf("%c\n", num);
	}else if(num >= 'a' && num <= 'z'){
		num -= 32;
		printf("%c\n", num);
	}else if(num >= '0' && num <= '9'){
		num -= '0';
		printf("%d\n", num);
	}else{
		printf("#\n");
	}

	return 0;
}

1.2 if..else语句注意事项

1.如果if..else语句对应代码块只有一行,那么后面的{}可以不加

如果有多行的时候,{}必须加,否则if只对下面的一行生效

2.else 必须有if与之对应,否则会报错

3.else 与同层次的前面与之最近的if结合

4.if 中的表达式一般是一个由关系运算符和逻辑运算符组成的表达式,

表达式的结果是一个bool类型,是能判断出真假的。

如果表达式是一个不正常的,要注意下面的用法

if(a) <==> if(a!=0)

if(!a) <==> if(a == 0)

if(a = b) 这种情况下,表达式的结果和 b 的值有关

b != 0 表达式为真

b == 0 表达式为假

if(10 == a) 变量和常量比较相等时,防止少写等号可以将常量写左边

因为 if(10 = a) 编译就过不去了

5. 同一层次的两个if..else语句是独立的,互不影响

if(){}

if(){}

思考:

下面的代码会输出什么?

int m = 10;
printf("start\n");
if(m > 0){
    printf("aa\n");
    m = -10;
}else if(m < 0){
    printf("bb\n");
}
printf("end\n");

bb不会输出,因为分支控制语句只能走一条分支

1.输入一个年份(如:2000 1999 1970 2022)

输出这个年份是 平年 还是 闰年。

闰年:能被4整除并且不能被100整除,或者能被400整除。

1999 --> 平年

2000 --> 闰年

1900 --> 平年

2022 --> 平年

2020 --> 闰年

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int year = 0;
	printf("输入一个年份:");
	scanf("%d", &year);
//闰年:能被4整除并且不能被100整除,或者能被400整除
	if((year%4==0 && year%100!=0) || year%400==0){
		printf("闰年\n");
	}else{
		printf("平年\n");
	}
	
	return 0;
}

输入三角形的三个边长(int),判断能否构成三角形

如果能:

判断是什么三角形

等边

等腰

直角

普通

如果不能:

输出不能构成

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int a = 0, b = 0, c = 0;
	scanf("%d%d%d", &a, &b, &c);

	if(a+b>c && b+c>a && a+c>b){
		printf("能构成\n");
		if(a==b && b==c){
			printf("等边三角形\n");
		}else if(a==b || b==c || a==c){
            printf("等腰三角形\n");
            if(a*a+b*b==c*c || b*b+c*c==a*a || a*a+c*c==b*b){
                printf("等腰直角三角形\n");
            }
		}else if(a*a+b*b==c*c || b*b+c*c==a*a || a*a+c*c==b*b){
			printf("直角三角形\n");
		}else{
			printf("普通三角形\n");
		}
	}else{
		printf("不能构成\n");
	}
	return 0;
}

输入一个成绩 [0,100],输出学生成绩的等级

[90,100] A

[80,90) B

[70,80) C

[60,70) D

[0,60) 不及格

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int score = 0;
	scanf("%d", &score);

	if(90<=score && score<=100){
		printf("A\n");
	}else if(80<=score && score<90){
		printf("B\n");
	}else if(70<=score && score<80){
		printf("C\n");
	}else if(60<=score && score<70){
		printf("D\n");
	}else{
		printf("不及格\n");
	}
	return 0;
}

2.switch..case 语句

2.1 格式

switch(表达式){
    case 常量表达式1:
        //代码块1
        break;
    case 常量表达式2:
        //代码块2
        break;
    case 常量表达式n:
        //代码块n
        break;
    default:
        //其他分支逻辑
        break;
}

2.2 注意事项

1.switch后面()里面一般是一个变量

2.case 后面的常量表达式就是 switch后面变量的所有可能值

3.case 后面的常量表达式一般是一个整型的或者字符型的,不能是浮点型的。

4.如果前面任意一个case都没有进,那么都走default分支,如果没有需要,default分支可以不写,default相当于if..else语句中的else

5.break 表示执行完某个分支后,就退出switch..case语句,如果不加break,那么程序会继续向下执行下面case中的代码块,直到遇到break 或者整个switch..case语句结束

#include <stdio.h>

int main(int argc, const char *argv[])
{
	char num = 0;
	scanf("%c", &num);

//switch后面的括号里也可以是一个表达式
//如 switch(num-1)
	switch(num){
		case 'a':
			printf("aaa\n");
			break;
		case 'b':
			printf("bbb\n");
			break;
		case 'c':
			printf("ccc\n");
			break;
		default:
			printf("other\n");
			break;
	}
	printf("end\n");

	return 0;
}

使用switch..case 语句 实现

输入一个成绩 [0,100],输出学生成绩的等级

[90,100] A

[80,90) B

[70,80) C

[60,70) D

[0,60) 不及格

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int score = 0;
	scanf("%d", &score);

	switch(score/10){
		case 10:
		case 9:
			printf("A\n");
			break;
		case 8:
			printf("B\n");
			break;
		case 7:
			printf("C\n");
			break;
		case 6:
			printf("D\n");
			break;
		default:
			printf("不及格\n");
			break;
	}
	return 0;
}

练习:

使用switch..case语句实现简易计算器的功能(+ - * /)

输入一个表达式 int char int

输出表达式的结果

如 输入 5+3

输出 8

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int v1 = 0;
	int v2 = 0;
	char operator = 0;
	scanf("%d%c%d", &v1, &operator, &v2);

	switch(operator){
		case '+':
			printf("%d %c %d = %d\n", v1, operator, v2, v1+v2);
			break;
		case '-':
			printf("%d %c %d = %d\n", v1, operator, v2, v1-v2);
			break;
		case '*':
			printf("%d %c %d = %d\n", v1, operator, v2, v1*v2);
			break;
		case '/':
			printf("%d %c %d = %f\n", v1, operator, v2, (float)v1/(float)v2);
			break;
	}
	return 0;
}

三、循环控制语句

1. goto实现循环

goto 本身是用来实现代码跳转的。

goto只能在同一个函数中完成跳转。

goto 会破坏代码的结构和可读性,所以,使用 goto 时要谨慎!!!

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("11111111\n");
	goto NEXT;//跳转到对应的标签运行
	printf("22222222\n");//这一行会被跳过
NEXT:
	printf("33333333\n");
	return 0;
}

使用goto实现循环

格式:

代码块1
标签:
循环体;--->会一直循环执行
goto 标签;
代码块3
#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int count = 1;
	printf("11111111\n");
NEXT:
	printf("22222222\n");
	//我们一般情况下使用的循环都是有条件的
	//否则 无条件的循环 我们叫做死循环 程序就出不去了
	if(count < 5){
		count++;
		goto NEXT;
	}
	printf("33333333\n");
	return 0;
}

练习:

使用 goto 循环,计算 1+2+3+...+100 的和

int sum = 0;
/*
sum = sum + 1;
sum = sum + 2;
。。。
sum = sum + 100;
*/

/*
int i = 1;
sum = sum + i;
i++;
sum = sum + i;
i++;
。。。
sum = sum + i;
i++;
*/

#include <stdio.h>

int main(){
    //sum 初始化成0 是必须的 否则可能会有随机值的影响
    int sum = 0;//使用来保存求和结果的
    int i = 1;//循环变量
LOOP:
    sum = sum + i;
    i++;
    if(i <= 100){
        goto LOOP; 
    }
    
    printf("sum = %d\n", sum);
    return 0;
}    

2.while 循环

格式:

while(表达式){
    //循环体
}
//循环后面的代码

执行流程:

先执行表达式,如果表达式为真,则执行循环体,

然后再执行表达式,如果还为真,则继续执行循环体,

直到表达式为假,循环立即结束,继续执行循环后面的代码

表达式:和 if 语句中 表达式的用法一样

一般而言,循环体要有能改变表达式结果的语句,否则就是死循环。

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	printf("start\n");
	while(i < 5){
		printf("hello world\n");
		i++;
	}
	printf("end\n");
	return 0;
}

练习:

1.使用 while 求 1~100 求和。

#include <stdio.h>

int main(){
    int sum = 0;
    int i = 1;
    //while后面的表达式 本质是决定循环的出口
    while(i<=100){
        sum = sum + i;
        i++;
    }
    printf("sum = %d\n", sum);
    return 0;
}

2.猴子吃桃问题

猴子第一天摘了若干了桃,

当即就吃了一半数量的桃,没吃过瘾,又多吃了一个

第二天,又将剩下桃吃了一半,没吃过瘾,又多吃了一个

依次类推,直到第十天想吃桃的时候,发现只剩下一个了。

问:猴子第一天摘了多少个桃?

第十天  1
第九天  4   (1+1)*2
第八天  10  (4+1)*2
第七天  22  (10+1)*2

n = 1;
循环执行的语句
    n = (n+1)*2;

#include <stdio.h>

int main(){
    int num = 1;//保存当天桃的数量 1 是第十天的数量
    int i = 0;//控制循环执行的次数的
    //第十天没吃 一共吃了9 天
    while(i < 9){
        num = (num+1)*2;
        i++;
    }
    //当循环结束的时候,num 里存储的就是 第一天的桃子的数量
    printf("num = %d\n", num);
}

把天数 和 每天吃之前桃子有多少个 输出出来

#include <stdio.h>

int main(){
    int num = 1;
    int i = 0;
    while(i < 9){
        printf("第 %d 天 有 %d 个桃\n", 10-i, num);
        num = (num+1)*2;
        i++;
    }
    printf("第 %d 天 有 %d 个桃\n", 10-i, num);
}

3. do..while 循环

格式:

do{
    代码块
}while(表达式); //后面要有一个分号!!!!

执行流程:

先执行代码块,然后执行表达式,如果表达式为真,

则继续执行代码块,直到表达式为假,循环立即结束。

#include <stdio.h>

int main(int argc, const char *argv[])
{
#if 0
	int i = 0;
	printf("start\n");
	do{
		printf("hello world\n");
		i++;
	}while(i < 5);
	printf("end\n");
#endif

	//while  和 do..while 的区别
	//while是先判断 后执行
	while(0){
		printf("while:hello world\n");//不会执行
	}
	
	//do..while是先执行 后判断
	do{
		printf("do..while:hello world\n");//会执行一次
	}while(0);
	
	return 0;
}

4. for循环

格式:

for(表达式1;表达式2;表达式3){  //表达式之间用 分号 分隔!!
    //代码块
}   

执行逻辑:

先执行表达式1,然后执行表达式2,如果表达式2为真,

则执行代码块,然后执行表达式3,

然后再执行表达式2,如果还为真,继续执行代码块和表达式3,

直到表达式2为假,循环立即结束。

表达式1:只执行一次,一般是用来给循环变量赋初值的

表达式2:和 if while 语句中的表达式是一样的

表达式3:是用来改变循环变量的值从而控制循环结束的,如 i++

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	printf("start\n");
	for(i = 0; i < 5; i++){
		printf("hello world\n");
	}
	printf("end\n");
	return 0;
}

练习:

使用 for 循环 求 1~100 的和。

#include <stdio.h>

int main(int argc, const char *argv[])
{
    int sum = 0;
	//for 循环的第一个表达式 是可以定义变量的
	//但是 定义的变量 只在for循环的 ()和{}里面生效
	//后面再使用就不行了
	//只有 C99 以上标准的编译器才支持
    for(int i = 1; i <= 100; i++){
        sum += i;
    }

	//printf("%d\n", i);//错误的 因为此时 i 所占用的空间已经被回收了
    printf("sum = %d\n", sum);
    return 0;
}

练习:

输出 (100,1000) 范围内所有的 水仙花 数

水仙花数:自身 == 个位*个位*个位 + 十位*十位*十位 + 百*百*百

例:

153 = 3*3*3 + 5*5*5 + 1*1*1 = 27 + 125 +1 = 153

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 101;
	int ge = 0;
	int shi = 0;
	int bai = 0;

	for(i = 101; i < 1000; i++){
		//在循环中 每次进循环 i 就表示当前这个三位数
		
		//获取这个三位数的个位 十位 百位
		//因为每次进循环时 i 都不同 所以每次要重新获取 i 的 个 十 百
		ge = i % 10;
		shi = i / 10 % 10;
		bai = i / 100;
		
		//判断是否是水仙花数
		if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i){
			printf("%d\n", i);
		}
	}
	return 0;
}

输入一个日期 年-月-日 %d-%d-%d

输出这个日期是这一年的第几天。(要考虑平年、闰年的问题)

闰年 二月 29天

平年 二月 28天

如:2020-3-1 ---> 2020年3月1日是2020年的第 61 天

#include <stdio.h>

//输入一个日期,输出当前日期是这一年的第几天

#define MONTH_1 31
#define MONTH_2 28
#define MONTH_3 31
#define MONTH_4 30
#define MONTH_5 31
#define MONTH_6 30
#define MONTH_7 31
#define MONTH_8 31
#define MONTH_9 30
#define MONTH_10 31
#define MONTH_11 30
#define MONTH_12 31

int main()
{
    int year, month, day;
    printf("请输入要查询的日期(年/月/日):");
    scanf("%d/%d/%d", &year, &month, &day);

    int leap = 0;//闰年 二月的增量

    //printf("%d/%d/%d\n", year, month, day);
	
    //判断输入的日期是否有误
    //判断年是闰年还是平年
    if(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
    {
        leap = 1;
    }

    //判断月份输入的是否有误
    if(month < 1 || month > 12)
    {
        printf("您输入的月份有误,请重新输入\n");
        //在main函数里面使用return,结束整个程序
        return -1;
    }

    //判断日是否有误
    //月份:1 3 5 7 8 10 12 最多31天
    if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
    {
        if(day < 1 || day > 31)
        {
            printf("您输入的日期有误,请重新输入\n");
            return -1;
        }
    }

    //月份:4 6 9 11 最多30天
    if(month==4 || month==6 || month==9 || month==11)
    {
        if(day < 1 || day > 30)
        {
            printf("您输入的日期有误,请重新输入\n");
            return -1;
        }
    }
    
    //月份:2 闰年最多29天 平年最多28天
    if(month == 2)
    {
        if(leap == 1) //闰年
        {
            if(day < 1 || day > 29)
            {
                printf("您输入的日期有误,请重新输入\n");
                return -1;
            } 
        }
        else if(leap == 0) //平年
        {
            if(day < 1 || day > 28)
            {
                printf("您输入的日期有误,请重新输入\n");
                return -1;
            }
        }
    }
    
    int days = 0;
    switch(month)
    {
    case 12:
        days += MONTH_11;
    case 11:
        days += MONTH_10;
    case 10:
        days += MONTH_9;
    case 9:
        days += MONTH_8;
    case 8:
        days += MONTH_7;
    case 7:
        days += MONTH_6;
    case 6:
        days += MONTH_5;
    case 5:
        days += MONTH_4;
    case 4:
        days += MONTH_3;
    case 3:
        days += MONTH_2 + leap;
    case 2:
        days += MONTH_1;
    case 1:
        days += day;
        break;
    }

    printf("%d年%d月%d日是%d年的第%d天\n", year, month, day, year, days);

    return 0;
}        

5. C语言中求次方和开平方的函数

5.1 pow()函数

功能:

计算x的y的方

头文件:

#include

//使用 math 库的函数,需要加编译选项 -lm

函数原型:

double pow(double x, double y);

参数:

x:底数

y:指数

返回值:

计算的结果

#include <stdio.h>
#include <math.h>

int main(int argc, const char *argv[])
{
	double x = 2;
	double y = 3;
	//计算x的y次方
	double ret = pow(x ,y);
	printf("%.1lf\n", ret);//8.0

	return 0;
}

5.2 sqrt()函数

功能:

计算x的非负平方根

头文件:

#include

//使用 math 库的函数,需要加编译选项 -lm

否则报错:

函数原型:

double sqrt(double x);

参数:

x:要开根号的数

返回值:

计算的结果

#include <stdio.h>
#include <math.h>

int main(int argc, const char *argv[])
{
	double a = 16;
	double ret = sqrt(a);
	printf("%.1lf\n", ret);//4
	return 0;
}

 

6. 死循环

所谓的死循环就是,判断条件恒为真,程序永远都在循环体里面执行的一种逻辑。

一般而言,我们使用的循环都是有结束条件的,

但是某些场景,也需要用到死循环,如 如后台的服务器程序,

需要一直等待客户端连接收发数据,这时就可以用死循环。

死循环的写法:

//一般while(1) 比较常用

while(1){

//循环体

}

for(;;){ //表达式可以不写,但是分号必须写

//循环体

}

四、辅助控制关键字

1. break

break语句可以用在switch..case语句中,表示执行完某个分支后,

跳出当前switch..case语句

break也可以用在循环中,表示结束本层循环。

2. continue

continue 只能用在循环语句中,用在其他位置会报错,

continue 表示退出本层的本次循环。

3. return

return 一般用在函数中,表示结束函数,并返回函数执行的结果。

return 如果用在主函数中,表示结束整个程序。

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	for(i = 1; i <= 5; i++){
		for(j = 1; j <= 5; j++){
			if(j == 3){
				//break;
				//continue;
				return 0;
			}
			printf("%d--%d\n", i, j);
		}
	}
	return 0;
}

.c文件补齐 设置:

vi .vim/snippets/c.snippets

在文件最后面的 snippet main 下面 加如两行(注意以table键开头, 空行也要有table键开头)

然后 :wq 保存退出即可

修改之后,打开任意的 .c 文件 输入main后按table键即可补齐

五、控制语句综合练习

1.练习:

使用C语言的控制语句输出下面的图案

 

F
_FE
__FED
___FEDC
____FEDCB
_____FEDCBA

答案:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	int k = 0;
	char value = 'F';
	//外层循环控制输出的行数
	for(i = 0; i < 6; i++){
		//内层循环控制输出 下划线 的个数
		for(j = 0; j < i; j++){
			printf("_");
		}
		value = 'F';//每次都从 F 开始输出
		//控制输出 字母 的个数
		for(k = 0; k <= i ; k++){
			printf("%c", value);
			value--;
		}
		//每行内容都输出完之后 再换行
		printf("\n");
	}
	return 0;
}

2.练习:

输入一个数,输出这个数的所有因子。

如:12 --> 1 2 3 4 6 12

6 --> 1 2 3 6

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	scanf("%d", &num);

	int i = 0;
	//因为 从1到num 的每一个数都有可能是 num 的因子
	//所以每一个数都要判断
	//这种每个数都访问的方式我们称之为  遍历
	for(i = 1; i <= num; i++){
		if(num%i == 0){
			printf("%d 是 %d 的因子\n", i, num);
		}
	}
	return 0;
}

3.练习:

输出 [1,1000] 范围内的所有完数,并输出完数的个数。

完数:除了自身之外所有因子之和还等于自身

如:6 ---> 1 2 3 1+2+3 == 6

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	int sum = 0;//统计因子和
	int count = 0;//统计个数

	//外层循环遍历 1-1000
	for(i = 1; i <= 1000; i++){
		sum = 0;//此处sum = 0是必须的,因为重新进入循环时
				//sum中还保存着上一个数的因子之和呢

		//内存循环是对每次的i计算因子值和
		//int j = 0; //一般不在循环内部定义变量
		for(j = 1; j < i ; j++){
			if(i%j == 0){
				sum += j;
			}
		}
		//当内层循环结束时,sum中保存的就是当前这个i所有的因子之和(不包括自身)
		if(sum == i){
			printf("%d 是一个完数\n", i);
			count++;//如果是完数 计数+1
		}
	}
	printf("一共有 %d 个完数\n", count);

	return 0;
}

4.练习:

输出 [100,1000] 范围内的所有质数,并输出质数的个数。

质数:只能被 1 和 自身 整除的数。

12 ---》不是质数

7 13 是质数

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	int count = 0;

	for(i = 100; i <= 1000; i++){
		for(j = 2; j < i; j++){
			if(i % j == 0){
				break;
			}
		}
		//内层循环有两种结束条件 一种是 break 结束的
		//另一中是  正常结束的(j==i)
		//如果是break结束的 说明再[2,i-1] 范围内找到了一个i的因子
		//说明i不是质数
		//
		//如果是 j==i 退出的,说明 [2,i-1] 范围内都没有 i 的因子
		//说明 i 是一个质数
		if(j == i){
			printf("质数:%d\n", i);
			count++;
		}
	}
	printf("共有 %d 个质数\n", count);

	return 0;
}

第二种处理方式,是用标志位。

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	int count = 0;

	//我们规定 flag 为 0 时,不是质数,为 1 时是质数
	int flag = 0;

	for(i = 100; i <= 1000; i++){
		flag = 1;//每次都默认是质数
		for(j = 2; j < i; j++){
			if(i % j == 0){
				flag = 0;//如果找到其他因子了,再将标志位置 0
				break;
			}
		}
		if(1 == flag){
			printf("%d 是质数\n", i);
			count++;
		}
	}
	printf("共有 %d 个质数\n", count);

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值