最最最详细的C语言教程笔记零起步(7)进阶必备 同笔者一起学习

本文主要是介绍最最最详细的C语言教程笔记零起步(7)进阶必备 同笔者一起学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C语言教程笔记

  • 十五. 分支结构
    • 1. 控制流
    • 2. C语言中的分支流程
    • 3. else关键词
    • 4. 复合语句
    • 5. 请不要在if或else后面加分号
    • 6. 嵌套if
    • 7. 避免无效的流程
    • 8. 省略花括号
    • 9. 条件运算符
  • 十六. 循环结构
    • 1. 高斯求和
    • 2. while循环
    • 3. C语言中的真与假
    • 4. 正确有限次数循环的3个条件
    • 5. for循环
    • 6. 请不要在while或for后面加分号
    • 7. do while循环
    • 8. 循环嵌套

十五. 分支结构

1. 控制流

一个完整的程序控制流包含下面三种控制流:

  1. 顺序流程
  2. 分支流程
  3. 循环流程

我们之前看过的程序都是顺序流程的。顺序流程至上而下,依次执行。

2. C语言中的分支流程

if (测试条件)
条件为真的流程

把输入的整数的变量命名为x,那么x应该满足条件 2<=x<=10 。将条件填入if语句中测试条件的括号内。

if (2<=x<=10)     
printf("yes\n");

这样的写法是不正确的。

例如,x的值为1。子表达式 2 <= 1 为假,即表达式结果为0。C语言中在计算表达式结果时,会使用0表示假,1表示真。 接着计算表达式, 0 <= 10 。条件满足,表达式结果为1。if的测试条件结果为1,即真。那么它将输出yes。

很显然,条件被写错了。我们的本意是要让子表达式 2 <= x 与 x <= 10 同时成立。因此,需要在两个表达式中间加上逻辑运算符与&&。

if (2<=x && x<=10)     
printf("yes\n");

当x为0时,子表达式 2 <= 0 为假,子表达式 0 <= 10 为真。整个表达式为假。
当x为5时,子表达式 2 <= 5 为真,子表达式 5 <= 10 为真。整个表达式为真。
完整代码如下:

#include <stdio.h>int main() 
{int x;     scanf("%d", &x);     if (2<=x && x<=10)         printf("Yes\n");     return 0; 
}

3. else关键词

现在我们将需求修改一下: 要求我们输入一个整数。如果这个数值在2到10之间,那么输出yes,否则输出no。

我们将代码修改如下:

#include <stdio.h>int main() 
{ int x;     scanf("%d", &x);     if (2<=x && x<=10)         printf("Yes\n");     printf("No\n");     return 0; 
}

我们再后面加上了一行语句,用于输出no。但是这样有个问题,无论测试条件是否满足,都会输出no。 我们只想要在测试条件不满足的时候输出no。应该怎样修改呢?
这时候就需要else关键词了。

if (测试条件) 条件为真的流程 else 条件为假的流程
#include <stdio.h>int main() 
{  int x;     scanf("%d", &x);     if (2<=x && x<=10)         printf("Yes\n");     else         printf("No\n");     return 0; 
}

4. 复合语句

if和else关键词只对它后面一条语句产生效果,并且if和else之间仅允许有一条语句。
如果我们将printf依次打印一个字符,那么if以及else将和它后面第一条语句配对。

#include <stdio.h>int main() 
{int x;     scanf("%d", &x);     if (2<=x && x<=10)         printf("Y");         printf("e");         printf("s");         printf("\n");     else         printf("N");         printf("o");         printf("\n");     return 0; 
}

这时将变成如下的奇怪流程,且由于if与else之间有多条语句,而无法编译成功。

if (测试条件) 条件为真的流程 printf("E"); printf("S"); printf("\n"); else     条件为假的流程 printf("O");

如果要使用多条语句,我们需要使用花括号将其包含起来,让它们组成复合语句。
我们将代码修改如下:

if (测试条件) 
{ 条件为真的流程1     条件为真的流程2     ... 
} 
else 
{ 条件为假的流程1     条件为假的流程2    ... 
}

我们将代码修改如下:

#include <stdio.h>int main() 
{int x;     scanf("%d", &x);     if (2<=x && x<=10) {        printf("Y");         printf("e");         printf("s");         printf("\n");}     else {        printf("N");         printf("o");         printf("\n"); }    return 0; 
}

5. 请不要在if或else后面加分号

初学者很容易出现的一个问题,就是认为if的测试条件或else也要以分号结尾。
如下面所示的,在if和else后都加了分号。

#include <stdio.h>int main() 
{ int x;     scanf("%d", &x);     if (2<=x && x<=10);     //  这里加了分号 printf("Yes\n");     else;                   //  这里加了分号 printf("No\n");     return 0; 
}

if与else将会对其后第一条语句产生影响,而单纯的一个分号将构成空语句。 这时将变成如下的奇怪流 程,且无法编译成功。

if (测试条件)条件为真的流程(空语句) 
printf("Yes"); 
else  条件为假的流程(空语句) 
printf("No");

6. 嵌套if

我们再修改一下需求:

要求我们输入一个整数。如果这个数值小于2,则输出Left。如果数值在2到10之间,则输出In。如果数值大于10,则输出Right。

x < 2, 输出Left
2 <= x <= 10,输出In。
x > 10,输出Right。

我们观察一下流程图,第一个分支流程中,嵌套了另外的分支流程。

if (小于2) 
{     
输出Left 
} 
else 
{     if (210之间)     { 输出In     }     else     { if(大于10)         { 输出Right         }     } }

事实上,我们可以发现大于10这个分支可以省略掉。由于测试条件是互斥的,如果一个数值即不小于 2,又不在2到10之间,那么它必然大于10。
完整代码如下:

if (小于2) 
{输出Left 
} else 
{if (210之间)     { 输出In     }    else     { 输出Right     } 
}

完整代码如下:

#include <stdio.h>int main() 
{ int x;     scanf("%d", &x);     if (x < 2)     { printf("Left\n");     }     else     { if (2<=x && x<=10)         {  printf("In\n");         }         else         {          printf("Right\n");    }     }     return 0; 
}

7. 避免无效的流程

我们考虑一下将程序写成下面这样可以吗?

#include <stdio.h>int main() 
{ int x;scanf("%d", &x);     if (x < 2)     {    printf("Left\n");     }     if (2<=x && x<=10)     {         printf("In\n");     }     if (x > 10)     {         printf("Right\n");     }     return 0; 
}

这样虽然结果上没有问题。但是,在最坏情况下,x满足小于2的条件,并完成了输出。那么程序没必要在继续测试后面的条件了。由于我们的测试条件具有互斥性,只要一个测试条件中满足了,就可以输出并结束了

8. 省略花括号

if语句由复合语句构成,但是整个if结构仍然被看做一条语句。我们可以省略包括它的一对花括号,将代码写成如下形式。else后面直接跟一条if语句。

#include <stdio.h>int main() 
{  int x;     scanf("%d", &x);     if (x < 2)     {         printf("Left\n");     }     else if (2<=x && x<=10)     {        printf("In\n");     }     else     {         printf("Right\n");     }     return 0; }

接下来,我们再看一个更复杂的例子。这个例子里面将有更多的分支。

输入一个学生的分数x
x < 60,输出不及格
60 <= x < 70,输出及格
70 <= x < 80,输出一般
80 <= x < 90,输出良好
90 <= x <= 100,输出优秀

if (x < 60) 
{  printf("不及格"\n); 
} 
else 
{     
if (x >= 60 && x < 70)     
{         printf("及格"\n);     
}     
else     
{         
if (x >= 70 && x < 80)         
{             printf("一般"\n);         
}         
else         
{             
if (x >= 80 && x < 90)             
{                 printf("良好"\n);             
}             
else             
{                 printf("优秀"\n);             
}         
}     
} 
}

上面代码中的嵌套层次较多,花括号层层叠叠,不易理解。 这时,就可以体现省略嵌套花括号的if else形式的优势了。 我们可以将代码简化成如下形式:

if (x < 60) 
{ printf("不及格"\n); 
} 
else if (x >= 60 && x < 70) 
{ printf("及格"\n); 
} 
else if (x >= 70 && x < 80) 
{ printf("一般"\n); 
} 
else if (x >= 80 && x < 90) 
{ printf("良好"\n); 
} 
else 
{printf("优秀"\n); 
}

是不是更加清晰明了了呢?

9. 条件运算符

C语言中提供条件表达式作为if else语句的一种便捷形式。

char x, c; 
if (x >= 10) 
{     
c = 'Y'; 
} 
else 
{     
c = 'N'; 
}

可以被写作如下形式:

char x, c; 
c = x >= 10 ? 'Y' : 'N';

条件表达式的范式如下:
测试条件 ? 表达式1 : 表达式2;

条件表达式的表达式结果为:

  1. 若测试条件为真,那么条件表达式结果为表达式1的结果。
  2. 若测试条件为假,那么条件表达式结果为表达式2的结果。

回到例子当中,表达式 x >= 10 ? ‘Y’ : ‘N’ 的测试条件为表达式 x >= 10 。
若 x >= 10 为真,那么整个表达式的结果为’Y’。
若 x >= 10 为假,那么整个表达式的结果为’N’。
条件表达式有3个运算对象,是C语言中唯一一个三元运算符

十六. 循环结构

一个完整的程序控制流包含下面三种控制流:

  1. 顺序流程
  2. 分支流程
  3. 循环流程

1. 高斯求和

现在有一个需求: 计算1 + 2 + 3 + 4 … + 99 + 100 = ?

使用高斯求和公式轻松得计算其结果。 (首项 + 末项) x 项数 / 2

(1 + 100) x 100 / 2 = 5050 现在来验证一下求和公式计算的是不是准确的吧。让计算机用最原始的办法一项一项累加起来,一直从1累加到100。
请添加图片描述

首先,先准备一个变量 sum 值为0,用来存放每一次累加的结果。
i 从1开始,计算 i + sum ,将结果赋值给 sum 。此时, sum 为1 + 0。
i 自增1,为2。再次计算 i + sum ,将结果赋值给 sum 。此时, sum 为2 + 1 + 0。
i 自增1,为3。再次计算 i + sum ,将结果赋值给 sum 。此时, sum 为3 + 2 + 1 + 0。
i 自增1,为4。再次计算 i + sum ,将结果赋值给 sum 。此时, sum 为4 + 3 + 2 + 1 + 0。
直到 i 为101,停止循环。输出 sum 的结果。

2. while循环

C语言中, while 语句可以实现循环。
while(测试条件) 循环行为

和 if 一样, while 也仅对其后一条语句产生效果。如果要循环多条语句,请使用花括号将它们组合成 一条复合语句。

while(测试条件) { 循环行为1 循环行为2 循环行为3 … }
使用 while 语句来尝试实现一下上面的求和过程。

#include <stdio.h>int main() { int i = 1, sum = 0;     while(i <= 100)     {  sum = i + sum;         i++;     }    printf("%d %d\n", i, sum);     return 0;
}

在这里插入图片描述

int i = 1, sum = 0; 声明变量 i , sum 。并初始化为1和0。
while语句的测试条件为 i <= 100 ,只要i在1到100的区间内,表达式为真,都能进入循环。
循环内,计算i + sum,将结果赋值给sum,并且i每次将自增1。

i 为1时,表达式 1 <= 100 为真,可以进入循环。 sum 的值为1 + 0。i变为2。
i 为2时,表达式 2 <= 100 为真,可以进入循环。 sum 的值为2 + (1 + 0)。i变为3。
i 为3时,表达式 3 <= 100 为真,可以进入循环。 sum 的值为3 + (2 + 1 + 0)。i变为4。
直到i的值为101,表达式 101 <= 100 为假,测试条件不成立,停止循环。

3. C语言中的真与假

在表达式求值过程中: 真将用1表示,假将用0表示
那么如果我们故意将测试条件结果改为1或0以外的数值呢?

#include <stdio.h>int main() {  while(2)     {    printf("Hello");     }     return 0;
}

在这里插入图片描述while将2看做了真,并且进行无限次数的循环。

在C语言中:非零即为真。 如果你的程序陷入了死循环,或者你想打断程序的执行,可以按组合键 Ctrl + C 让程序停止运行。

4. 正确有限次数循环的3个条件

#include <stdio.h>int main() { int i = 1, sum = 0;     while(i <= 100)     {    sum = i + sum;         i++;     }  printf("%d %d\n", i, sum);     return 0; 
}

在这里插入图片描述

在上面的求和代码中,首先将计数器 i 设置为1。
接着, i 与一个有限值比较为循环条件。 并且,每一次循环计数器将改变。
这3个条件让循环运行特定的次数并在正确时候退出:

  1. 开始时,为计数器设置初始值。
  2. 计数器与一个有限值比较作为循环条件。
  3. 更新计数器。

这3个条件对应代码中的:

  1. int i = 1;
  2. i <= 100;
  3. i++;

若不正确设置计数器初始值,将循环错误的次数。 循环条件设置错误,将无法开始循环或无法结束循环。 不更新计数器将无法结束循环。

5. for循环

for 关键词,提供另一种紧凑的循环写法。我们将上面的求和代码,用 for 循环改写。

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

for 循环的结构如下:
请添加图片描述

for (计数器设置初始值; 循环条件; 计数器更新) 循环行为

和 while 一样, for 也仅对其后一条语句产生效果。如果要循环多条语句,请使用花括号将它们组合成 一条符合语句

for (计数器设置初始值; 循环条件; 计数器更新)
{
循环行为1
循环行为2
循环行为3

}

for 循环中的计数器设置初始值仅在开始时执行一次。 运行完一次所有的循环行为后,将执行一次计数器更新。 循环条件成立将进入循环,否则将结束循环。

若 i 仅作为计数器使用,并在循环结束后,并不关心 i 的值。可以将 i 放在计数器初始化时声明。

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

这样 i 仅仅在循环体内有效,结束循环后, i 将失效。 再举一个简单的例子,我们用 for 循环来打印0-100内的所有偶数。

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

在这里插入图片描述

值得注意的是, for 循环括号内的3个部分,都是可以写在别的地方的。

1.计数器初始化为空

#include <stdio.h>int main() { int i = 0;  //  在这初始化计数器     for(; i <= 100; i = i + 2)     {  printf("%d ", i);     }     return 0; 
}

2.计数器更新为空

#include <stdio.h>int main() { for(int i = 0; i <= 100; )     {    printf("%d ", i);         i = i + 2;  //  在这更新计数器     } return 0; 
}     

3.循环条件为空,这将导致死循环

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

如果仅仅想写一个死循环,可以将3个条件都不写。或者写一个永远为真的表达式。 以下3个均为死循环。但是while循环不能省略循环条件。

for(;;)        循环行为
for(;100;)     循环行为
while(100)     循环行为

6. 请不要在while或for后面加分号

初学者很容易出现的一个问题,就是认为 while 的循环条件或 for 也要以分号结尾。

for(int i = 0;i <= 100; i++);     
循环行为1
while(i <= 100);     
循环行为2

while 和 for 将会对其后第一条语句产生影响,而单纯的一个分号将构成空语句。
这时虽然可以编译成功,但是每次循环仅执行了空语句。而循环结束后,才会执行一次循环行为。

7. do while循环

除了 while ,C语言还提供了 do while 循环。

请添加图片描述
while 循环将在循环进入时,检查循环条件是否满足。若不满足,则一次都不执行。
do while 将先执行一次循环行为,再检查循环条件。至少会执行一次循环条件。

do while的范式:

do循环行为 
while(循环条件);    //  注意do while有分号结尾
do
{ 循环行为1     循环行为2     循环行为3     ... }
while(循环条件);   //  注意do while有分号结尾

请注意,do while需要有分号结尾
下面这段代码会让你先输入一个数,如果不是一个正数或0。它会一直让你输入,直到你输入了正数或0 为止。

#include <stdio.h>int main() {  int x;     do     {   scanf("%d", &x);     }while(x < 0); printf("%d\n", x);    return 0; 
}

8. 循环嵌套

#include <stdio.h>int main() {  for (char c = 'A'; c <= 'E'; c++)     {   for (int i = 0; i < 10; i++)         {       printf("%c%d ", c, i);         }         printf("\n");     }     return 0; 
}

在这里插入图片描述外层循环将从字母’A’到’E’。
内层循环将从数字0到9。

外层循环计数器初始值为’A’。进入循环后,将开始内层循环从0到9,打印的结果为A0到A9。这时,内 层循环执行完毕,输出换行。外层循环计数器更新为’B’。再次重复上述过程。

这篇关于最最最详细的C语言教程笔记零起步(7)进阶必备 同笔者一起学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/392125

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss