热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

所有奇数之和

本文主要介绍关于算法,c++,数据结构的知识点,对【分支与循环(1)】和【所有奇数之和】有兴趣的朋友可以看下由【菜菜求捞】投稿的技术文章,希望该技术和经验能帮到你解决你所遇的C语言相关技术问题。所有

本文主要介绍关于算法,c++,数据结构的知识点,对【分支与循环(1)】和【所有奇数之和】有兴趣的朋友可以看下由【菜菜求捞】投稿的技术文章,希望该技术和经验能帮到你解决你所遇的C语言相关技术问题。

所有奇数之和

分支与循环(1) 前言1. 什么是语句2. 分支语句(选择结构)2.1 if语句2.1.1 悬空else2.1.2 if书写形式的对比2.1.3 练习 2.2 switch语句2.2.1在switch语句中的break2.2.2 default子句2.2.3 练习 3. 循环语句3.1 while循环3.1.1 while语句中的break和continue 3.2 for循环3.2.1 for 语法3.2.2 break和continue在for循环中的使用3.2.3 for语句的循环控制变量3.2.4 一些for循环的变种3.2.5 笔试题

前言

在之前学习了初识C语言,只是对知识有一个初步的学习,但是很多细节还不够了解,所以从今天开始进行细致的学习。

c语言是结构化的程序设计语言

结构化指的是什么呢?

C语言中有三种结构,顺序结构,选择结构,循环结构。

顺序结构,从头走到尾(默认)

选择结构,生活中有很多选择,有人选择就业,有人选择考研

循环结构,重复做某一件事情就是循环

如果不是这三种结构,也是这三种结构的组合。

生活中的任意一件事情都可以拆分成三种结构。

选择结构在C语言中提供了if语句 switch语句

循环结构在C语言中提供了while循环 for循环 do while 循环。

分支语句与循环语句

分支语句对应的选择结构(if switch)

循环语句对应的循环结构(while for do…while)

1. 什么是语句

语句可以分为五类:

1表达式语句

2函数调用语句

3控制语句

4复合语句

5空语句

 int main()
{
	2+3;  //表达式语句
    Add(2,3);  //函数调用语句
    ;  //空语句
	return 0;
}

本章后面介绍的是控制语句。

控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。

可分成以下三类:

\1. 条件判断语句也叫分支语句:if语句、switch语句;

\2. 循环执行语句:do while语句、while语句、for语句;

\3. 转向语句:break语句、goto语句、continue语句、return语句。

像转向语句中的break语句、continue语句是在循环语句当中使用

return语句是放在函数当中使用的。

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

如果你好好学可以拿一个好offer

如果不好好学,回家卖红薯。

选择中可以有多个选择,可以有两个选择,也可以有多个选择。

2.1 if语句

if语句的语法结构

语法结构:

//单分支        
if(表达式)      //if后的表达式如果为真,执行语句。
    语句;   //C语言中0为假,非0为真,包括小数,负数,等非0数字。
    
//双分支    
if(表达式)    //表达式为真执行语句1,否则执行语句2
    语句1;
else
    语句2;
    
//多分支    
if(表达式1)         //表达式1为真,执行语句1
    语句1;
else if(表达式2)    //表达式1为假,表达式2为真,执行语句2
    语句2;
else               //如果表达式1,表达式2为假,执行语句3
    语句3;

补充:

if else 语句默认控制一条语句,若想控制多条语句,可以使用大括号{}

课堂演示代码:

单分支:

#include 
  
    int main() { int age = 20; if (age<18) printf("未成年\n"); return 0; } 
  

双分支:

#include 
  
    int main() { int age = 20; if (age<18) { printf("未成年\n"); printf("不能喝酒\n"); } else { printf("成年\n"); printf("可以适量饮酒\n"); } return 0; } 
  

多分支:

#include 
  
    int main() { int age = 0; scanf("%d", &age); if(age<18) { printf("少年\n"); } else if(age>=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.1 悬空else

当你写了这个代码:

#include 
  
    int main() { int a = 0; int b = 2; if(a == 1) if(b == 2) printf("hehe\n"); else printf("haha\n"); return 0; } //-------------------------- //输出结果为 //不输出 
  

else是与if的匹配原则为就近原则。

改正:

//适当的使用{}可以使代码的逻辑更加清楚。
//代码风格很重要
#include 
  
    int main() { int a = 0; int b = 2; if(a == 1) { if(b == 2) { printf("hehe\n"); } } else { printf("haha\n"); } return 0; } 
  

else的匹配:else是和它离的最近的if匹配的。

2.1.2 if书写形式的对比
//代码1
if (condition)
{
    return x;
}
return y;
//代码2
if(condition) 
{
    return x; 
}
else
{
    return y; 
}
//代码3
int num = 1;
if(num == 5) 
{
    printf("hehe\n");
}
//代码4
int num = 1;
if(5 == num)
{
    printf("hehe\n");
}

代码2和代码4更好,逻辑更加清晰,不容易出错。

2.1.3 练习

1判断一个数是否为奇数

2输出1-100之间的奇数

1

#include 
  
    int main() { int num = 0; scanf("%d",&num); if (num % 2 == 1) { printf("奇数\n"); } else { printf("偶数\n"); } return 0; } 
  

表达式不能被赋值,所以不需要 1 == num % 2

2方法一

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

2方法二

#include 
  
    int main() { int i = 1; while (i<=100) { printf("%d ",i); i += 2; } } 
  
2.2 switch语句

switch语句也是一种分支语句。

常常用于多分支的情况。

比如:

输入1,输出星期一

输入2,输出星期二

输入3,输出星期三

输入4,输出星期四

输入5,输出星期五

输入6,输出星期六

输入7,输出星期日

那我没写成 if...else if ...else if 的形式太复杂,那我们就得有不一样的语法形式。

2.2.1在switch语句中的break

在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。

#include 
  
    int main() { int day = 0; switch(day) { 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; } 
  

switch case 工作原理

case决定入口

break是出口

switch后面的表达式必须是整型表达式

case 后面的表达式必须是整型常量表达式

错误示范

int n = 0;
case n:                //错误的,会报错
                   //即使是const修饰的常变量,本质也属于变量

有时候我们的需求变了:

1输入1-5,输出的是“工作日”;

2输入6-7,输出“休息日”

#include 
  
    //switch代码演示 int main() { int day = 0; switch(day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default: printf("输入错误\n"); break; } return 0; } 
  

编程好习惯

在最后一个 case 语句的后面加上一条 break语句。

之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句。

2.2.2 default子句

当switch表达式的值

当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

2.2.3 练习
#include 
  
    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 
  

switch支持嵌套,在嵌套里面的break只会跳出嵌套中的switch,不会跳过整个大的switch。

3. 循环语句 whilefordo while 3.1 while循环
int main()
{
	while (1)
		printf("haha\n");
	return 0;
}

while语法结构

while (表达式)
	循环语句;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tNjZmHrE-1658845274898)(C:\Users\85989\AppData\Roaming\Typora\typora-user-images\image-20220724085614035.png)]

进行判断expr是否为真(!=0),为真执行stmt,再进行判断,反复执行,当有一天expr为假,退出循环。

在屏幕上打印1—10

int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d",i);
		i++;
	}
}
3.1.1 while语句中的break和continue
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if(i==5)
			break;
		printf("%d ",i);
		i++;
	}
}
//--------------------
//打印结果为
//1 2 3 4

break总结:

break在while循环中的作用:

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

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

break换成continue

int main()
{
	int i = 1;
	while (i <= 10)
	{
		if(i==5)
			continue;
		printf("%d ",i);
		i++;
	}
}
//--------------------
//打印结果为
//1 2 3 4 无限循环

continue会跳过本次循环continue后边的代码,直接去判断部分进行判断。由于i未发生变化,所以会陷入死循环中。

打印1-10除了5

int main()
{
	int i = 0;
	while (i <= 10)
	{
		i++;
		if(i==5)
			continue;
		printf("%d ",i);
	}
}
//--------------------
//打印结果为
//1 2 3 4 6 7 8 9 10

continue总结:

continue在while循环中的作用就是:

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

再看几个代码:

int main()
{
	int ch = getchar();//获取字符,因为字符对应的ASCII码值是整数,所以放int可以。并且eof本质是-1,无法存储在char类型里面。
	putchar(ch);
}
//输入一个字符,打印一个字符
//A
//A

int getchar (void);

如果成功,返回值就是读取到的字符,如果失败会返回EOF

EOF(end of file是文件结束标志)的本质是-1

int putchar (int character);

int main()
{
	int ch = 0;
	while((ch=getchar)!=EOF)
	{
		putchar(ch);
	}
	return 0;
}

可以实现多次输入和输出。

想要停止按ctrl+z

输入了一个A后回车,getchar读取了两次,第一次读取到A,A!=EOF,所以输出A,缓存区里面还有一个回车字符,!=EOF,所以输出一个回车

int main()
{
	char password[20]={0};
	printf("请输入密码:>");
    scanf("%s",password);    //数组名就是地址,所以不需要&
    printf("请确认密码(Y/N):");
    int ch = getchar();
    if(ch=='Y')
    {
    	printf("确认成功\n");
    }
    else
    {
    	printf("确认失败\n");
    }
}
//---------------------------
//测试结果为:
//请输入密码:>asd
//请确认密码(Y/N):确认失败

确认失败原因:

scanf需要读取数据,在scanf和键盘之间有一个区域叫输入缓冲区,

scanf读取数据,先去输入缓冲区查看,有数据就读取,如果没有就等待

键盘中敲击的数据想要进入输入缓冲区需要回车\n

这个时候缓冲区内不仅有敲击的数据还有\n。

scanf从缓冲区拿走的数据仅仅是敲击的数据,\n还在输入缓冲区

这个时候缓冲区有东西,getchar直接读取,不需要等待,于是\n放在了ch中进行后续if的判断。

处理办法:

int main()
{
	char password[20]={0};
	printf("请输入密码:>");
    scanf("%s",password);    //数组名就是地址,所以不需要&
    getchar();  //清理缓冲区的\n,只能清理掉一个字符
    printf("请确认密码(Y/N):");
    int ch = getchar();
    if(ch=='Y')
    {
    	printf("确认成功\n");
    }
    else
    {
    	printf("确认失败\n");
    }
}
//------------------------------
//请输入密码:>adsfas123
//请确认密码(Y/N):Y
//确认成功

缺点

请输入密码:>asd asda
请确认密码(Y/N):确认失败

scanf在读取信息的时候,遇到空格不再读取,读取到asd,所以缓冲区还剩下空格asda\n,getchar会读取空格

修正

int main()
{
	char password[20]={0};
	printf("请输入密码:>");
    scanf("%s",password);    //数组名就是地址,所以不需要&
    //清空缓存区,将\n以及之前的字符全部清空
    int tmp = 0;
    while((tmp = getchar())!='\n')
    {
    
    }
    printf("请确认密码(Y/N):");
    int ch = getchar();
    if(ch=='Y')
    {
    	printf("确认成功\n");
    }
    else
    {
    	printf("确认失败\n");
    }
}
while(getchar()!='\n')
{
}
//也可以直接进行读取,不用进行存储在tmp

补充

((ch=getchar)!=EOF)中里面的括号不能省略,省略后先判断getchar()!=EOF为真,ch赋值为1,循环始终为真

getchar的返回值为int 不能定义为char类型。

练习

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

这个代码的作用是:只打印数字字符,跳过其他字符的、

3.2 for循环

for循环的形式是更优于while

int main()
{
	int i =1; //初始化
	
	
	
	while (i<10)  //判断
	{




		i++;  //调整
	}
}

随着代码的逐渐增多,初始化,判断,调整三部分逐渐远离,容易出错。

3.2.1 for 语法
for(表达式1;表达式2;表达式3)
	循环语句;

表达式1

表达式1为初始化部分,用于初始化循环变量的。

表达式2

表达式2为条件判断部分,用于判断循环时候终止。

表达式3

表达式3为调整部分,用于循环条件的调整。

用for循环实现打印1—10

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

i=1为1 i<=10为2 代码块内部为3 i++为4

1执行一次后,2进行判断判断为真执行3,4进行调整,再次进行判断,是否为真,进行234步的循环

for循环的执行流程图

image-20220724110404732

先进行表达式1,对表达式2进行判断,如果为真,执行循环体,再进行表达式3,表达式2再次判断进行循环,如果某次表达式2结果为假,则退出判断。

3.2.2 break和continue在for循环中的使用

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

但是还是有些continue上的差异:

break

#include 
  
    int main() { int i = 0; for(i=1;i<=10;i++) { if(i==5) break; printf("%d ",i); } return 0; } //---------------- //打印结果为 //1 2 3 4 
  

continue

#include 
  
    int main() { int i = 0; for(i=1;i<=10;i++) { if(i==5) continue; printf("%d ",i); } return 0; } //---------------- //打印结果为 //1 2 3 4 6 7 8 9 10 
  

i==5时跳过代码块的中的内容,进入调整部分,进行下一次循环。

在while循环中如果调整部分在continue后面的话可能会导致死循环。

但是for循环会进入调整部分,再进行判断。

3.2.3 for语句的循环控制变量

建议:

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

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

1

int main()
{
	int i = 0;
	for(i=1;i<=10;i++)
	{
		i = 5;
		printf("%d ",i);
	}
	return 0;
}
//-------------------
//循环打印5,所以不建议在循环体内修改循环变量。

2有时候建议采用前闭后开的方式

int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int i = 0;
	for(i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}
3.2.4 一些for循环的变种

for循环语句中三个表达式可以省略,但是分号不可以省略

#include 
  
    int main() { //代码1 for(;;) { printf("hehe\n"); } //for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。 //但是省略但判断部分,则意味着判断恒为真 //代码2 int i = 0; int j = 0; //这里打印多少个hehe? for(i=0; i<10; i++) { for(j=0; j<10; j++) { printf("hehe\n"); } } //代码3 int i = 0; int j = 0; //如果省略掉初始化部分,这里打印多少个hehe? for(; i<10; i++) { for(; j<10; j++) { printf("hehe\n"); } } //代码4-使用多余一个变量控制循环 int x, y; for (x = 0, y = 0; x<2 && y<5; ++x, y++) { printf("hehe\n"); } return 0; } 
  
 //代码2
   int main()
{
	 //代码2
    int i = 0;
    int j = 0;
    //这里打印多少个hehe?
    for(i=0; i<10; i++)
   {
        for(j=0; j<10; j++)
       {
		 printf("hehe\n");
       }
   }
}
//打印100个hehe
 //代码3
   int main()
{
	 //代码3
    int i = 0;
    int j = 0;
    //如果省略掉初始化这里打印多少个hehe?
    for(; i<10; i++)
   {
        for(; j<10; j++)
       {
		 printf("hehe\n");
       }
   }
}
//打印10个hehe
//当i=0 j=10的时候由于j没有初始化,不再进行内部循环
//代码4-使用多余一个变量控制循环,循环变量可以是多个,不止一个。
 int main()
 {
	int x, y;
    for (x = 0, y = 0; x<2 && y<5; ++x, y++)
   {
        printf("hehe\n");
   }
 	return 0; 
}
//-----------------
//打印结果为
//hehe
//hehe
3.2.5 笔试题
//请问循环要循环多少次?
#include 
  
    int main() { int i = 0; int k = 0; for(i =0,k=0; k=0; i++,k++) k++; return 0; } //循环了0次,因为在判断部分k被赋值为0,为假。 
  

本文《分支与循环(1)》版权归菜菜求捞所有,引用分支与循环(1)需遵循CC 4.0 BY-SA版权协议。


推荐阅读
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • C语言的经典程序有哪些
    本篇内容介绍了“C语言的经典程序有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何 ... [详细]
  • 1关于字符串相邻的两个或多个字符串字面值(引号引起来的字符)将会自动连接到一起:str_catpython!str_cat输出:python!把很长 ... [详细]
  • c语言 怎么访问64位地址_C语言调动硬件的原理是什么?
    大家都知道我们可以使用C语言写一段程序来控制硬件工作,但你知道其工作原理吗?1c语言在实际运行中,都是以汇编指令的方式运行的,由编译器把C ... [详细]
  • 一,关于C语言的问卷调查【作业3】1.你对自己的未来有什么规划?做了哪些准备?没有明确的规划,在学习教材知识的同时准备了解其他知识。2.你认为什么是学 ... [详细]
  • 文件上传漏洞利用介绍
    目录文件上传漏洞利用介绍1.绕过js验证2.绕过MIME-TYPE验证3.绕过基于黑名单验证基于文件后缀名验证介绍基于文件后缀名验证方式的分类基于黑名单验证代码分析利 ... [详细]
  • AtonepointIhadlookedatimplementingaclasstemplateinC++thatwouldsupportanEnumthatwo ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
author-avatar
大爱仅有的财产丶_468
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有