锦州网站建设品牌,企业信息查询网站查询,如何修改wordpress的域名,注册境外服务公司文章目录 前言一、什么是语句#xff1f;1.1 表达式语句1.2 函数调用语句1.3 控制语句1.4 复合语句1.5 空语句 二、分支语句#xff08;选择结构#xff09;2.1 if语句2.1.1 悬空else2.1.2 练习#xff08;1. 判断一个数是否为奇数 2. 输出1-100之间的奇数#xff09; 2.2… 文章目录 前言一、什么是语句1.1 表达式语句1.2 函数调用语句1.3 控制语句1.4 复合语句1.5 空语句 二、分支语句选择结构2.1 if语句2.1.1 悬空else2.1.2 练习1. 判断一个数是否为奇数 2. 输出1-100之间的奇数 2.2 switch语句2.3 switch语句中的break:2.4 switch语句中的default子句2.5 练习 三、循环语句3.1 while循环3.1.1 while语句中的break和continue 3.2 for循环3.2.1 语法3.2.2 练习使用for循环 在屏幕上打印1-10的数字。 3.3 do......while()循环3.3.1 do语句的语法3.3.2 do...while语句的特点 四、goto语句4.1 goto语句的作用4.2 goto语句的使用场景4.3 goto语句的例子 五、作业练习1、 计算 n的阶乘2、 计算 1!2!3!……10!3、 在一个有序数组中查找具体的某个数字n4、演示多个字符从两端移动向中间汇聚5、密码校验6、猜数字游戏【经典】 前言 C语言是结构化的程序设计语言这里的结构指的是顺序结构、选择结构、循环结构C语⾔是能够实现这三种结构的其实我们如果仔细分析我们⽇常所⻅的事情都可以拆分为这三种结构或者这三种结构的组合。我们可以使⽤if 、 switch 实现分⽀结构使⽤ for 、 while 、 do while 实现循环结构。 一、什么是语句
在我们平时写字中一句话的结尾是句号然而正在C语言中一句话的结尾是;
语句可以分为以下五类 1表达式语句 2函数调用语句 3控制语句 4复合语句 5空语句
1.1 表达式语句
下面这个就是表达式语句
3 5; 1.2 函数调用语句
函数调用语句就是将函数进行使用时调用的语句。
printf(%d\n, a);
ADD(3, 5); 1.3 控制语句
控制语句用于控制程序的执行流程以实现程序的各种结构方式它们由特定的语句定义符组成C语言有九种控制语句。C语言是由三种结构组成的有顺序结构选择结构和循环结构
可分成以下三类 条件判断语句也叫分支语句if语句、switch语句循环执行语句do while语句、while语句、for语句转向语句break语句、goto语句、continue语句、return语句。 1.4 复合语句
复合语句就是被多个扩号括起来的语句
{int a 0;int b 0;printf(%d\n, a b);return 0;
}1.5 空语句
空语句虽然很简单但是其用途很大有时候需要一条语句但这条语句什么都不需要做例如下面这段代码我们会后面在字符章节也会详细讲解
while(*dest *src)
{;
}二、分支语句选择结构
分支语句可以为双分支或者多分支。在C语言中需要知道真假两个概念非0为真0为假注意正数和负数都是真分支语句分为两类if语句switch语句。
2.1 if语句
那么if语句的语法结构是怎么样的
if(表达式//表达式为真执行下面的语句语句
//单分支语句
if(表达式语句1
else语句2
//多分支语句
if(表达式1)语句1
else if(表达式2)语句2
else语句3单分支练习输入大于等于18输出为成年人否则不输出
#include stdio.h
int main()
{int age 0;scanf(%d, age);if (age 18){printf(成年人\n);}
}单分支练习输入大于等于18输出为成年人否则输出未成年人
#include stdio.h
int main()
{int age 0;scanf(%d, age);if (age 18){printf(成年人\n);}else{printf(未成年\n);}
}多分支练习
#include stdio.h
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 stdio.h
int main()
{int a 0;int b 2;if(a 1)if(b 2)printf(hehe\n);elseprintf(haha\n);return 0;
}上面那个代码虽然可以运行但是风格不是很好
#include stdio.h
int main()
{int a 0;int b 2;if(a 1){if(b 2){printf(hehe\n);}}else{printf(haha\n);} return 0;
}这段代码加上了{}使代码变得逻辑更加清楚要养成更好的代码分格如何写出一个好的代码呢 这里我推荐《高质量C/C编程》而这本书就写了如何写出好的风格大家可以看一下 在我们判断是否等于一个变量或者数的时候我们有可能少一个等于号那么我们怎么避免呢
//代码1
int num 1;
if(num 5)
{printf(hehe\n);
}
//代码2
int num 1;
if(5 num)
{printf(hehe\n);
}上面的代码哪个比较好
肯定是代码2因为在判断是否相等时用两个等于号写这样反过来写就会避免只写一个等于号只写一个等于号的话会编译错误可以及时发现。
2.1.2 练习1. 判断一个数是否为奇数 2. 输出1-100之间的奇数
判断一个数是否为奇数
思路要判断是不是奇数那么我们就可以看一个数的余数是不是等于1如果等于1那么这个数就是奇数否则就是偶数了
int main()
{int n 0;scanf(%d, n);if (n % 2 1){printf(YES\n);}else{printf(NO\n);}return 0;
}输出1-100之间的奇数
思路要输出1-100之间的奇数就要产生1~100的数然后将每个数进行判断是不是奇数然后再输出我们目前学了while循环那么我们就用while循环来解决这道题~后面学到了for循环也可以很简便的写出来
方法一
#includestdio.h
int main()
{int i 1;while (i 100)//产生1~100的数字{if(i % 2 1)//进行判断是否奇数printf(%d , i);i;}return 0;
}方法二
这个方法的话就有点投机取巧了~~
#includestdio.h
int main()
{int i 1;while (i 100)//产生1~100的数字{printf(%d , i);//i2;i i 2;//也可以这样写}return 0;
}2.2 switch语句
switch语句也是一种分支语句常常用于多分支情况~~
比如 输入1输出星期一 输入2输出星期二 输入3输出星期三 输入4输出星期四 输入5输出星期五 输入6输出星期六 输入7输出星期七。 如果写成if…else if…else if…else的情况就很复杂那我们需要有不一样的语法形式。 switch语句支持嵌套使用
switch(整形表达式)
{语句项;
}而语句项是什么呢
//是一些case语句
//如下
case 整形常量表达式:语句;2.3 switch语句中的break:
在switch语句中我们没办法直接实现分支搭配break使用才能实现真正的分支。
#include stdio.h
int main()
{int day 0;switch(day){case 1printf(星期一\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
//switch代码演示
int main()
{int day 0;switch (day){case 1:case 2:case 3:case 4:case 5:printf(weekday\n);break;case 6:case 7:printf(weekend\n);break;}return 0;
}其中break语句的实际效果是把语句列表划分为不同的分支部分。
在这里我推荐一个编程好习惯
在最后一个 case 语句的后面加上一条 break语句。 之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句~~
2.4 switch语句中的default子句
如果表达的值与所有的case标签的值都不匹配怎么办
default
写在任何一个 case 标签可以出现的位置。 当 switch 表达式的值并不匹配所有 case 标签的值时这个 default 子句后面的语句就会执行。所以每个switch语句中只能出现一条default子句。 但是它可以出现在语句列表的任何位置而且语句流会像执行一个case标签一样执行default子句。
推荐编程好习惯
在每一个switch语句中都放入一条default语句是一个好习惯甚至可以在后面加一个break。
2.5 练习
#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;
}
上面这段代码的结果是什么呢
三、循环语句
循环语句分为三类while循环for循环do…while循环。
3.1 while循环
我们已经掌握了if语句
if(条件) 语句;当条件满足的情况下if语句后的语句执行否则不执行。 但是这个语句只会执行一次。 由于我们发现生活中很多的实际的例子是同一件事情我们需要完成很多次。那我们怎么做呢 C语言中给我们引入了 while 语句可以实现循环。
while(表达式)循环语句;while循环的执行流程 3.1.1 while语句中的break和continue
break介绍
#include stdio.h
int main()
{int i 1;while (i 10){if (i 5)break;printf(%d , i);i i 1;}return 0;
}这里代码输出的结果是什么
总结
break在while循环中的作用 其实在循环中只要遇到break就停止后期的所有的循环直接终止循环。 所以while中的break是用于永久终止循环的。
continue介绍
continue 代码实例1
#include stdio.h
int main()
{int i 1;while (i 10){if (i 5)continue;printf(%d , i);i i 1;}return 0;
}输出1 2 3 4...
continue 代码实例2
#include stdio.h
int main()
{int i 1;while (i 10){i i 1; if (i 5)continue;printf(%d , i);}return 0;
}输出2 3 4 6 7 8 9 10 11
总结:
continue在while循环中的作用就是 continue是用于终止本次循环的也就是本次循环中continue后边的代码不会再执行 而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
那么我们在看几个代码~~
getchar介绍
#include stdio.h
int main()
{int ch 0;while ((ch getchar()) ! EOF)putchar(ch);return 0;
}这里的getchar函数不接收任何的参数返回类型是int 从stdin键盘上读取一个字符返回读取到字符的ASCLL码值,如果读取失败或者读取到文件末尾就会返回EOF这里可以打开msdn或者cplusplus网站进行搜索 选中EOF转到定义就可以看到那么EOF是什么呢EOF是-1在一次证明了返回值是int的。 putchar介绍
接收一个字符输出到屏幕也就是从键盘上获取一个字符打印到屏幕上 现在代码运行结果是什么呢
输入q 输出q
输入什么就会输出什么
那么我们这个程序怎么停止下来呢
只需要ctrlz然后回车就可以了目的是让读取到EOF这样程序就会终止。
那么这里的代码还有什么用呢
可以用来清理缓冲区的
列如
int main()
{char password[20];scanf(%s, password);printf(请确认Y/N);int ch getchar();if (Y ch)printf(确认成功\n);elseprintf(确认失败\n);return 0;
}输入abcde 输出请确认Y/N确认失败
怎么回事呢还没确认就是确认失败了为什么呢
scanf会从键盘上读取一些你输入的数据但你不输入的时候它就一直等一直等直等到你输入为止。在计算机中使用scanf时并不会直接获取键盘上输入的数据。相反存在一个输入缓冲区用户输入的数据首先会被放入这个缓冲区。当用户输入完数据例如abcde为了将这些数据送入缓冲区用户需要按下回车键。 举例来说如果用户输入abcde并按下回车键整个输入会被存储为abcde\n其中\n表示回车符。这时scanf会从缓冲区读取数据直到遇到换行符为止。所以用户的输入实际上是被缓冲并在程序请求时才被获取的。 通过scanf函数将数据输入到缓冲区并检查是否有可读取的数据。如果有数据可读取它会一直读取直到遇到换行符\n。随后将这些数据作为密码赋给变量password。此时getchar()函数也开始读取数据其工作原理与scanf()相似检查缓冲区是否有数据。一旦发现换行符\n就将对应的数据存储到变量ch中。然后程序判断ch是否为‘Y’由于不满足这个条件进入else分支并输出“确认失败”。这就是编译器在等待我们输入确认密码时却直接结束程序的原因。
再看一个代码
#include stdio.h
int main()
{char ch \0;while ((ch getchar()) ! EOF){if (ch 0 || ch 9)continue;putchar(ch);}return 0;
}那么这段代码就要对ASCLL码表要熟悉 这段代码只打印0~9的字符
3.2 for循环
3.2.1 语法
首先来看看for循环的语法
for(表达式1; 表达式2; 表达式3)循环语句;表达式1表达式1为初始化部分用于初始化循环变量的表达式2表达式2为条件判断部分用于判断循环时候终止表达式3表达式3为调整部分用于循环条件的调整。
for循环的执行流程
3.2.2 练习使用for循环 在屏幕上打印1-10的数字。
#include stdio.h
int main()
{int i 0;//for(i1/*初始化*/; i10/*判断部分*/; i/*调整部分*/)for (i 1; i 10; i){printf(%d , i);}return 0;
}输出1 2 3 4 5 6 7 8 9 10 就像我们这里去打印1-10的数字使用for循环的话就会很清晰直观代码也比较简练 现在我们学习完了while循环和for循环后让我们进行对比一下这两个循环
int i 0;
//实现相同的功能使用while
i 1; //初始化部分
while(i 10) //判断部分
{printf(hehe\n);i i 1; //调整部分
}//实现相同的功能使用for
for(i 1; i 10; i)
{printf(hehe\n);
}通过上面的代码可以发现在while循环中依然存在循环的三个必须条件但是由于风格问题使得三个部分很可能偏离较远这样查找修改不够集中和方便。 3.3 do…while()循环
do…while()执行流程 3.3.1 do语句的语法
首先来看一下它的语法格式和while循环很类似
do
{循环语句;
}while(表达式);3.3.2 do…while语句的特点
循环体内至少执行一次使用的场景有限所以不是经常使用。但是我们下面的猜数字游戏会有一个案例我们可以来看一下
四、goto语句
在大多数现代编程语言中goto语句通常被认为是一种不良的编程实践因为它可能导致程序难以理解和维护。然而在某些情况下它仍然是一种有用的控制流工具。在C语言中goto语句可以用来无条件地将程序控制转移到指定的标签处 如果goto语句用的不好会导致程序跳来跳去的。 4.1 goto语句的作用
C语言提供了⼀种非常特别的语法就是 goto 语句和跳转标号goto语句可以实现在同⼀个函数 内跳转到设置好的标号处。
4.2 goto语句的使用场景
for (...)
for (...)
{for (...){if (disaster)goto error;}
}
…
error :
if (disaster)
// 处理错误情况4.3 goto语句的例子
下面这是一个关机程序的例子学会后可以拿去恶搞同学一下~~
#include stdio.h
#include windows.h
#include string.h
int main()
{char input[10] {0};system(shutdown -s -t 60);
again:printf(电脑将在1分钟内关机如果输入我是猪就取消关机\n请输入:);scanf(%s, input);if(0 strcmp(input, 我是猪)){printf(shutdown -a);}else{goto again;}return 0;
}使用goto通常容易导致程序结构混乱使得代码难以理解和维护。因此除非有充分的理由推荐使用其他控制流结构如for、while、do-while、if等来替代goto语句。
五、作业练习
1、 计算 n的阶乘 计算一个n的阶乘那只要定义一个变量去存放这个阶乘的结果然后通过循环去遍历即可 这里需要注意的一点就是ret初始值为1
int main()
{//n的阶乘int n 0;scanf(%d, n);int ret 1;for (int i 1; i n; i){ret * i;}printf(ret %d\n, ret);return 0;
}2、 计算 1!2!3!……10! 第二小题又是一道计算阶乘的题然后把计算出的阶乘再相加~~ 假设我们要计算1! 2! 3! 这一小规模的阶乘之和。首先让我们审视解题思路。由于只需计算到数字3的阶乘我们需要一个外层循环从1迭代到3表示我们要求解的是这三个数字的阶乘之和。 接下来内层循环用于计算每个数字的阶乘从1迭代到该数字即可。我们使用一个累乘变量来存储计算结果。在完成每个数字的阶乘计算后我们需要累加这些阶乘的和因此还需要定义一个sum变量来存储这个累加和。最终sum变量就是我们所需的结果。 正确答案应该是1 2 6 9
int ret 1;
int sum 0;
for (int i 1; i 3; i)
{for (int j 1; j i; j){ret * j;}sum ret;
}
printf(sum %d\n, sum);可以看到sum的结果并非为9。这里涉及到一个常见的错误很多同学容易犯这个错。因为我们正在计算不同数字的阶乘但是使用的累乘变量是同一个ret。因此当计算下一个数字的阶乘时ret仍然保留了上一次数字累乘后的结果。这导致了阶乘计算的不准确因此结果也会有所不同。在计算3!时可能多乘了一个2留下了额外的2导致3 12比实际结果多了6。因此最终的计算结果也就多了6。
int ret 1;
int sum 0;
for (int i 1; i 3; i)
{ret 1;//这里要把ret掷为1for (int j 1; j i; j){ret * j;}sum ret;
}
printf(sum %d\n, sum);我们应该加上ret 1;在每一次更新需要求阶乘的数时都将这个累乘变量ret重置
int ret 1;
int sum 0;
for (int i 1; i 3; i)
{ret * i;sum ret;
}3、 在一个有序数组中查找具体的某个数字n 在数组的两端分别设定左右两个指针然后计算它们的中间值。将欲查找的数字与中间值比较若小于中间值则舍弃后半段区间只需在前半段继续查找若大于中间值则舍弃前半段区间继续在后半段查找。将此逻辑嵌入一个循环中不断更新中间值进行比较。最终左右两指针会相遇表示区间即将结束。若左指针大于右指针表示已找到目标元素或未找到此时退出循环并进行相应打印说明。 接下来我们就看看代码~~
int main()
{ //二分查找法int a[10] { 1,2,3,4,5,6,7,8,9,10 };int sz sizeof(a) / sizeof(a[0]);int key 7;//要查找的数字kint left 0;int right sz - 1;while (left right){int mid (left right) / 2;if (key a[mid])right mid - 1;else if (key a[mid])left mid 1;else{printf(找到了下标是%d\n, mid);break; //找到了便跳出循环}}if (left right)printf(没找到此元素\n);return 0;
}4、演示多个字符从两端移动向中间汇聚 我们要展示多个字符从两端向中间汇聚的效果需要实现一种覆盖的动画效果。我定义了两个数组最终要打印的是第一个数组的内容但在打印过程中我们通过左右指针实现覆盖效果。 首先初始化左指针为0右指针不能直接取末尾值需要使用strlen()库函数求解数组1的长度然后减1得到右指针位置。 将逻辑放入循环中通过左右指针将第一个数组的内容赋给第二个数组然后不断移动这两个指针直至左指针大于右指针。 为了慢慢显示出效果使用了Sleep()睡眠函数需要引入头文件#include Windows.h。这个函数的参数是毫秒值比如1秒执行一次就传入10000.5秒执行一次就传入500。这样可以创建一个动画效果。
int main()
{char arr1[] { welcome to bit!!! };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(500);left;right--;}return 0;
}为了让其在一行打印不需要一行行地打印我们可以使用这样一个命令
system(cls); //清屏一行打印但是这个system()函数要加上头文件#include stdlib.h大家不要忘了~~
5、密码校验
这题的要求是输入一串字符然后与正确密码进行比较如果相同就立即跳出循环如果不同继续输入但只有3次机会用完后强制跳出循环不允许再次输入。我们来看一下代码~~
int main()
{int i 0;char password[20] { 0 };for (i 0; i 3; i){printf(请输入密码);scanf(%s, password);if (strcmp(password, bitbit) 0){printf(密码输入正确\n);break;}else{printf(密码输入错误\n);}}if (i 3){printf(输入机会用完请30分钟后再试\n);}return 0;
} 在这方面需要注意的一个问题是字符串比较时可能出现的挂字符串问题。我们不能直接使用运算符进行比较而应该利用字符串库函数strcmp来实现比较。关于strcmp的返回值我们可以通过查阅cplusplus来获取详细信息。 简而言之strcmp函数的返回值取决于第一个字符串的首字母与第二个字符串的首字母的ASCII码值大小关系。如果第一个字符串的首字母大于第二个字符串的首字母那么返回一个大于0的数字反之如果小于则返回一个小于0的数字。如果两个字符串相同返回值则为0。这里实际上进行的是ASCII码值的大小比较。
6、猜数字游戏【经典】
首先我们来实现一个整体的逻辑也就是当你输入的时候通过我们上面学习的switch语句进行一个分支的判断是要继续猜数字还是退出游戏
void menu()
{printf(\n);printf(********************************\n);printf(********** 1.play ************\n);printf(********** 0.exit ************\n);printf(********************************\n);printf(\n);
}
void game()
{printf(猜数字\n);
}
int main()
{int input 0;srand((unsigned int)time(NULL));do{menu();printf(请选择:);scanf(%d, input);switch (input){case 1:game();break;case 0:break;default:printf(选择错误,请重新输入!\n);break;}} while (input);return 0;
}可以看到整体的逻辑已经实现了按下【1】时启动猜数字功能。如果一直按下1就能一直进行猜数字直到按下0为止。 接下来我们就要实现猜数字内部的逻辑了我们首先要产生一个随机数然后我们输入一个数字比较要猜的数字如果输入的大了就提示猜的数字打了相反输入的小了就提示小了要么就一直继续知道猜成功为止 那么就要用到一个函数rand()可以在cplusplus网站上找到~~ 我们要生成1~100内的数字我们使用下面这段代码官方文档上面也有写
//生成随机数
int ret rand() % 100 1; //1 ~ 100但是我们这里又有一个问题这个rand是一个伪随机数在C语言中rand() 函数用于生成伪随机数。伪随机数是由一个算法生成的数字序列其看似随机但实际上是可预测的因为它们是根据一个称为种子的初始值计算的。这个时候我们就要使用到一个C语言中的另一个函数叫做随机种子srand()我们通过cplusplus我们再来看看 这个时候我们有了这个函数是不够的一般还要再配合使用一个时间戳函数time()不会使用的话也可以在cplusplus中查看 我们可以这样直接使用下面我们来详细介绍一下这段代码
srand((unsigned int)time(NULL));time(NULL) 返回当前的系统时间表示从某个固定时间点通常是1970年1月1日午夜到现在的秒数。 (unsigned int) 是将时间转换为无符号整数。srand 函数的参数应该是一个无符号整数因此这里进行了强制类型转换。 最终srand((unsigned int)time(NULL)); 将当前时间作为种子传递给 srand 函数以初始化伪随机数生成器。 这个time()函数是要包含头文件的#include time.h 还可以加上一个猜数字的次数如果只能猜10次次数用完了就结束了并告知要猜的数字~~
while (1)
{printf(次数还有%d\n, flag);printf(请输入猜的数字:);scanf(%d, input);if (input random_num){printf(猜大了\n);flag--;}else if (input random_num){printf(猜小了\n);flag--;}else{printf(恭喜你猜对了\n);break;}if (flag 0) {printf(次数用完了数字是%d, random_num);break;}
}完整的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include stdlib.h
#include stdio.h
#include time.h//设置猜的数字次数多少
#define NUM 10 void menu()
{printf(**********************\n);printf(****** 1.play *******\n);printf(****** 0.exit *******\n);printf(**********************\n);
}void game()
{int guess 0;int ret rand() % 100 1;int count NUM;while (1){printf(你还有%d次机会\n, count);printf(请猜数字:);scanf(%d, guess);if (guess ret){printf(猜大了\n);}else if (guess ret){printf(猜小了\n);}else{printf(恭喜你猜对了\n);break;}count--;if (count 0){printf(次数用完正确的数字是%d\n, ret);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;
}我们最后增加了一个次数限制这样我们对一个猜数字游戏有更有游戏体验感~~ 好了分支与循环到这里就结束了感谢大家的阅读希望新的一年大家都有学有所成感谢阅读