c#笔记-流程控制语句

news/2025/2/21 22:54:11/

随机数

为了展示流程控制的作用,需要每次执行程序时都使用不一样的值。
无论是每次都修改源码,还是从控制台读取输入都太麻烦了。
所以使用随机数进行测试。

随机数的使用方式如下,使用随机数类,获取一个默认的随机数工具,然后用这个工具生成随机数。

int r1 = Random.Shared.Next();//在0到int上限中随机
int r2 = Random.Shared.Next(10);//从0到这个值之间随机,不会取到上限值
int r3 = Random.Shared.Next(20, 30);//从20到30之间随机,不会取到30
double d1 = Random.Shared.NextDouble();//获取一个0到1之间的小数,永远不会取到1

变量储存值而不储存操作。这里的作用是把一个随机数的值储存到一个变量中。
除非修改这个变量的值,否则他会一直保持这个值。并不会每次访问都会发生变化。

一些特殊情况不详细说明。
例如int r2 = Random.Shared.Next(10);,随机数不会是负数,所以这个上限不能是负数。
但如果这里填0,那么不会取到上限值就是无效的,他能取到0而且每次都是0。

选择

if

if选择接收一个条件,如果条件为true才会执行

条件即指bool类型的值,只有true和false两个值。
除了直接声明变量外,还可以使用运算符进行运算。例如大于和小于。

int r4 = Random.Shared.Next(100);
if (r4 > 80)
{Console.WriteLine("触发暴击");
}
Console.WriteLine("随机数是" + r4);

所有流程控制语句中,如果跟随一个大括号,那么语句跟大括号之间不要用分号隔开

if-else if

在if的语句块后可以跟随else if语句。
当前面的if没有判中,就会由后面的else if处理。
else if后还能继续接else if,直到你不想接为止。
此外,最后一个else可以省略if,表示不用再判定,必定执行。

int r5 = Random.Shared.Next(100);
if (r5 > 98)
{Console.WriteLine("评分为SS");
}
else if (r5 > 95)
{Console.WriteLine("评分为S");
}
else if (r5 > 90)
{Console.WriteLine("评分为A");
}
else if (r5 > 80)
{Console.WriteLine("评分为B");
}
else if (r5 > 60)
{Console.WriteLine("评分为C");
}
else
{Console.WriteLine("未通过");
}Console.WriteLine("随机数是" + r5);

这一串判断都是对同一个值进行,不能使用Random.Shared.Next(100)代替所有的r5

switch

switch选择是用于配合模式匹配的选择。
它的使用场景类似于长if-else if,但更整洁。

int r5 = Random.Shared.Next(100);
switch (r5)//switch只会取值一次,这里可以不声明变量直接写Random.Shared.Next(100)
{case > 98:Console.WriteLine("评分为SS");break;case > 95:Console.WriteLine("评分为S");break;case > 90:Console.WriteLine("评分为A");break;case > 80:Console.WriteLine("评分为B");break;case > 60:Console.WriteLine("评分为C");break;default:Console.WriteLine("未通过");break;
}
  • 每一个case分支类似于if的条件。
  • default类似于无条件的else。
  • 每个分支的结尾都需要加上break来结束switch。
    除非一个分支后紧跟着另一个分支,中间没有任何执行语句。
switch (Random.Shared.Next(1, 13))
{case 1:case 3:case 5:case 7:case 8:case 10:case 12:Console.WriteLine("这月有31天");break;case 2:Console.WriteLine("这月有28天");break;default:Console.WriteLine("这月有30天");break;
}

但是现在有了模式匹配,可以在一个case中进行多个值的判断,这种联合判断已经没有意义了。

swtich的主判断只能使用模式匹配,而模式匹配只能使用常量。
switch的次判断可以使用变量,但即便只想使用次判断,也需要加一个无意义的主判断。
在主要判断后加上when来启动次要判断。

int r6 = Random.Shared.Next(100);
int r7 = Random.Shared.Next(100);switch (true)
{case true when r6 > r7:Console.WriteLine("r6更大");break;case true when r6 < r7:Console.WriteLine("r7更大");break;
}

循环

while

类似于if,条件满足才会执行。
但是,在执行完毕以后,会再判断条件,并决定是否再次执行。
直到条件不满足。

int r8 = Random.Shared.Next(100);
while (r8 > 4)
{Console.WriteLine("没有抽中SSR");r8 = Random.Shared.Next(100);
}
Console.WriteLine("抽中了SSR");

do-while

do-while循环的条件判断在循环结束而不是循环开始。
和普通while的区别在于,进入循环的时候没有条件判断,所以一定会执行第一次循环。
而普通while可能第一次条件就判断失败,完全不执行。而之后的流程是一样的。

string? s1;
do
{Console.WriteLine("初次启动或密码错误,请输入密码");s1 = Console.ReadLine();
} while (s1 == "123456");
Console.WriteLine("登录成功");

do-while循环的使用场景偏向于类似输入密码的场合,判断条件是根据执行内容判断,所以至少要执行一次才能判断。
而这种场合也是声明变量是分离声明和赋值的场合。在这里使用var并赋值初始值,初始值是会被覆盖的。

do-while的条件后面是不跟大括号的,所以while后面是要加分号的。

for

for循环有3个部分,临时变量声明条件判断迭代语句
for循环可以理解为东西更多的while循环。不过如果不需要临时变量声明迭代语句,那么while循环更加精简。

for (int i = 0; i < 10; i++)
{Console.WriteLine("第" + i + "次丢骰子,丢出来" + Random.Shared.Next(1, 7));
}

for循环括号内的三个部分都可以留空,只要保证存在两个分号就不会报错。

  • 条件部分留空会视为true,始终通过。
  • 临时变量声明部分可以省略,也可以声明多个同类型变量。
    但是因为语法问题,这里不能同时声明不同类型的变量。
  • 迭代部分和循环体的差别,是迭代部分不会与跳转语句continue交互。除此之外没有区别。

for循环的执行顺序是:临时变量声明->条件判断->循环体->迭代部分->条件判断->循环体->迭代部分

跳转

break

break用来中断当前的循环,或用于switch内终止switch。

for (int i = 1; i < 10; i++)
{for (int j = 1; j < 10; j++){Console.Write($"{i} * {j} = {i * j}\t");if (j > i - 1){break;}}Console.WriteLine();
}

可以调整循环条件和if来达到相同的效果。
但如果存在多层if嵌套,多条件判断。那么使用break可能更清晰和简单。

continue

continue用来重启当前循环。
重启循环会忽略循环的剩余部分,直接回到条件判断。
但对于for循环,会先进入他的迭代部分,再进行判断。

int ssr = 0;for (int i = 0; i < 100; i++)
{int number = Random.Shared.Next(1, 101);if (number > 4){Console.WriteLine("抽到r");continue;}Console.WriteLine("抽中了ssr!");ssr = ssr + 1;
}Console.WriteLine($"你抽到的ssr有" + ssr);

goto

break和continue的缺点是,只能控制当前所在的switch或循环。
goto语句可以做到更精细的跳转,包括跳出多层循环。

for (int i = 1; i <= 10; i++)
{switch (i){case 1:Console.WriteLine("One");break;case 2:Console.WriteLine("Two");break;case 3:Console.WriteLine("Three");break;case 4:Console.WriteLine("Four");goto End; //跳转到End 标签处default:Console.WriteLine("Other");break;}
}
End://定义一个标签,用于goto语句的跳转
Console.WriteLine("结束");

使用goto首先要定义一个标签,并且这个标签后面必须再跟随一条语句。
也就是说goto不能直接结束代码。

作用域

每一个大括号都是一个范围。
定义的变量只有在范围内生效。
大括号可以不配合流程控制语句,单独放置。

{int a = 12;
}
Console.WriteLine(a);//错误,无法访问到a{int b = 6;Console.WriteLine(b);
}{int b = 6;//上面的b跟这里的b互不影响,变量可以同名Console.WriteLine(b);
}{int c = 2;{Console.WriteLine(c);//允许。因为这个代码也处于声明c的大括号范围内。}
}

而for循环的临时变量声明部分,作用域只限于循环内部。
所以多个并列的for循环可以都用同名的临时变量。

for (int i = 0; i < 5; i++)
{Console.WriteLine(i);
}
for (int i = 0; i < 5; i++)
{Console.WriteLine(i * i);
}

嵌入语句

如果if,else,while,do-while,for后面跟随的语句只有一条,那么可以省略大括号。

for (int i = 0; i < 10; i++)if (i > 5)Console.WriteLine(i + "大于5");elseConsole.WriteLine(i + "不比5大");

这是一种简写形式,有一定局限性。例如在多个if嵌套时,如果坚持省略掉大括号,就不能控制else跟随哪一个if。

int i1 = 12;
if (i1 > 4)if (i1 > 10)Console.WriteLine("通过");elseConsole.WriteLine("及格");

嵌入语句同样有作用域限制。所以不能是声明变量语句,因为无法使用。
但是完整的写大括号则没有这样的限制,甚至可以一条语句都没有。

int i2 = 66;
if (i2 > 50)
{int i3 = 60;
}
elseint i4 = 40;//报错

流程预测

如果用作流程控制语句的判断条件完全由常量构成,那么编译器可以判断不可达代码。

if (1 < 2)
{Console.WriteLine("1");
}
else
{Console.WriteLine(2);//检测到无法访问的代码
}while (true)//死循环
{
}
Console.WriteLine("结束");//检测到无法访问的代码

类似的,如果你声明了一个没有初始值的变量,
而它经过的流程控制语句不能保证它有初始值,那么你是无法使用他的。

int i5 = 0;
int i6;
if (i5 < 10)
{i6 = 10;
}
Console.WriteLine(i6);//尽管你认为一定会赋值初始值,但编译器不觉得。

如果你通过if-else,或者带有常量的条件(死循环),那么可以保证它在使用前必定赋值。

int i7 = 0;
int i8;
if (i7 < 10)
{i8 = 10;
}
else
{i8 = 20;
}
Console.WriteLine(i8);

常量

所有的字面量都是常量。此外,可以像定义变量一样定义常量。

  • 常量声明在类型前加上const
  • 常量必须写明类型,不能用var
  • 常量必须当场赋值,且之后不能再赋值。
  • 常量必须用常量赋值。所以追根溯源,所有的常量一定是通过字面量定义的。
    需要构造出来的值(包括变量)是无法为常量赋值的。
const double Pi = 3.1415926;

http://www.ppmy.cn/news/69449.html

相关文章

记一次SpringBoot应用性能调优过程

背景 使用SpringBoot、MyBatis-Plus开发一个接口转发的能&#xff0c;将第三方接口注册到平台中&#xff0c;由平台对外提供统一的地址&#xff0c;平台转发时记录接口的转发日志信息。开发完成后使用Jmeter进行性能测试&#xff0c;使用100个线程、持续压测180秒&#xff0c;…

20230517提升cv1826的打印等级

20230517提升cv1826的打印等级 2023/5/17 17:43 https://www.xitongjiaocheng.com/linux/2017/53494.html Linux内核log等级与printk打印消息控制 时间&#xff1a;2017-03-13 出处&#xff1a;系统之家复制分享人气(206次) 【大中小】 printk打印消息控制 // linux/includ…

Web 自动化笔记-第一章 Selenium 环境搭建

1.自动化测试能解决什么问题&#xff1f; 1. 解决-回归测试 2. 解决-压力测试 3. 解决-兼容性测试 4. 提高测试效率,保证产品质量 回归测试&#xff1a; 项目在发新版本之后对项目之前的功能进行验证 压力测试&#xff1a; 可以理解多用户同时去操作软件&#xff0c; 统计软件服…

蓝桥杯第十四届青少年Python组省赛试题--第4题

提示信息&#xff1a; 杨辉三角就是一个用数排列起来的三角形&#xff08;如下图&#xff09;&#xff0c;杨辉三角规则如下&#xff1a; 1&#xff09;每行第一个数和最后一个数都为1&#xff0c;其它每个数等于它左上方和右上方的两数之和&#xff1b; 2&#xff09;第n行有n…

功能测试4年,5月份被辞退,2023年的功能真的没有出路了

在测试行业摸爬滚打5年&#xff0c;以前经常听到开发对我说&#xff0c;天天的点点点有意思没&#xff1f; 和IT圈外的同学、朋友聊起自己的工作&#xff0c;往往一说自己是测试&#xff0c;无形中也会被大家轻视&#xff0c;总有人会问你&#xff0c;为啥干测试啊&#xff0c…

Go 语言指针

Go 语言指针 Go 语言中指针是很容易学习的&#xff0c;Go 语言中使用指针可以更简单的执行一些任务。 接下来让我们来一步步学习 Go 语言指针。 我们都知道&#xff0c;变量是一种使用方便的占位符&#xff0c;用于引用计算机内存地址。 Go 语言的取地址符是 &&#xf…

广告变现数据分析,提高媒体广告变现效果的关键指标!

​广告变现是一种极为普遍的商业化运营方式&#xff0c;其实质在于通过在不同媒体平台上投放广告&#xff0c;从而实现盈利&#xff0c;然而&#xff0c;广告变现的成败往往关乎于各种媒体基本信息类指标及广告变现相关指标的表现。 因此&#xff0c;在本文中&#xff0c;我们…

实验9 分类问题

1. 实验目的 ①掌握逻辑回归的基本原理&#xff0c;实现分类器&#xff0c;完成多分类任务&#xff1b; ②掌握逻辑回归中的平方损失函数、交叉熵损失函数以及平均交叉熵损失函数。 2. 实验内容 ①能够使用TensorFlow计算Sigmoid函数、准确率、交叉熵损失函数等&#xff0c;…