判断语句(if、switch-case):
if 语句
用于条件判断,其中包含一个布尔表达式,后面跟随着一段要执行的代码;当布尔表达式为true时,后面跟随的代码就会执行。
包括:
循环语句(for、while、do-while)
- if 语句:根据条件执行不同的代码块。
- if-else 语句:根据条件执行不同的代码块,还可以包含一个默认的代码块。
- if-else if-else 语句:根据多个条件依次判断执行不同的代码块。
cs
int num = 10;
if (num > 0)
{
Console.WriteLine("Positive number.");
}
else if (num < 0)
{
Console.WriteLine("Negative number.");
}
else
{
Console.WriteLine("Zero.");
}
需要注意的是,当布尔表达式为真,且成功执行它后面语句块中的代码后,会跳出 if else if 语句 ,语句中的其它部分不会再被执行 。
*
switch-case语句
-
C# 中的 switch 语句有些类似于if else if语句,都可以根据表达式执行某个的语句块,可能情况的值的数量,一般大于或等于3个情况,就可以使用switch,或者有具体的值判断,如日期,时间等。
cs
int dayOfWeek = 3;
switch (dayOfWeek)
{
case 1:
Console.WriteLine("Monday");
break;
case 2:
Console.WriteLine("Tuesday");
break;
case 3:
Console.WriteLine("Wednesday");
break;
default:
Console.WriteLine("Other day");
break;
}
使用 switch 语句时必须遵守以下规则:
-
switch 语句中表达式的值必须是一个整型 、字符串 或者枚举类型;
-
在一个 switch 语句中可以有任意数量的 case 语句,每个 case 关键字后面要跟一个值 和一个冒号;
-
case 关键字后面的值必须与 switch 中表达式的值具有相同的数据类型 ,并且必须是一个常量值;
-
当表达式的值等于某个 case 中的值时,就会执行 该case 后面的语句,在遇到 break 关键字时停止;
-
当遇到 break 关键字时,就会跳转到 switch 语句以外;
-
并不是每一个 case 语句后面都需要包含 break 关键字,如果 case 语句为空(case 语句后面没有要执行的代码),则可以不包含 break 关键字,这时程序会继续执行后续的 case 语句,直至遇到 break 关键字为止;
-
switch语句只会执行某个case语句中的代码块;
-
一个 switch 语句的末尾可以有一个可选的 default(默认选项),当所有 case 语句都不能与表达式相匹配时则会执行 default 部分中的代码;
-
C# 不支持从一个 case 语句跳转到另一个 case 语句。
for循环
for 循环可以重复执行 一段代码,而且重复的次数 是可以设定的,多用于确定重复次数的循环处理,其语法格式:
for (初始化语句; 判断条件; 迭代器)
{
// 循环主体代码
}
cs
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Iteration {i}");
}
string ss = Console.ReadLine();
for (int i =0; i < ss.Length; i++)
{
if (i > 0 && i < ss.Length)
Console.Write(" ");
Console.Write(ss[i]);
}
在 C# 中,循环语句还可以嵌套使用,也就是说我们可以在一个 for 循环内再使用一个或多个 for 循环。
例:99乘法表
cs
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
Console.Write($"{j} x {i} = {i * j}\t");
}
Console.WriteLine();
}
for 循环中,如果判断条件永远不会为假,那么循环将变成无限循环(也叫死循环),我们在定义循环语句时应尽量避免这种情况的出现,除非就是要用无限循环的情况,不过一般无限循环用while循环更简便。
cs
for (int i=0; ;i++ )
{
if (i < 20)
Console.WriteLine("执行中...");
else
break;
}
// 如果不设定退出条件,那么程序将会一直执行下去。
while循环和do-while
在 C# 中,while 循环用于多次迭代一段程序代码,特别是在迭代的次数不固定的情况下,建议使用 while 循环而不是 for 循环。
while 循环会在循环开始之前先判断表达式的结果 ,只有表达式结果为真时才会开始循环,
do while 循环会先执行一遍循环主体中的代码 ,然后再判断表达式的结果。
也就是说,不论表达式的结果如何,do while 循环至少会执行一次。
cs
int j = 0;
while (j < 3)
{
Console.WriteLine($"While loop, j = {j}");
j++;
}
int k = 0;
do
{
Console.WriteLine($"Do-while loop, k = {k}");
k++;
} while (k < 3);
与 for 循环相同,while 循环也可以嵌套使用,同样可以实现99乘法表:
cs
int i = 1;
while (i <= 9) {
int j = 1;
while (j<=i) {
Console.Write($"{j}*{i}={i*j}\t");
j++;
}
i++;
Console.WriteLine();
}
int i = 1;
do
{
int j = 1;
do
{
Console.Write($"{j} x {i} = {i * j}\t");
j++;
} while (j <= i);
Console.WriteLine();
i++;
} while (i <= 9);
foreach循环
C#中,往往使用 foreach 遍历数组或者集合对象中的每一个元素。
其语法格式:
foreach(数据类型 变量名 in 数组或集合对象)
{
语句块;
}
foreach 会在每次循环的过程中,依次从数组或集合对象中取出一个新的元素放到foreach( )
里定义的变量中,
直到所有元素都成功取出后退出循环。
cs
//遍历打印输出
string[] names = new string[] { "Lily","Lucy","Jason","Steven","White" };
foreach (string name in names)
{
Console.WriteLine("{0} ", name);
}
break/continue跳出循环
在使用循环语句时,并不是所有情况都要必须等待循环完成后才能退出循环,我们也可以主动退出循环。C#中提供了break和continue来跳出循环。
break(循环与switch中)
break 语句我们在学习switch 语句的时候已经见过了,它不仅可以用来终止 switch 语句,在循环语句中使用时还可以用来跳出当前循环。
如果是在嵌套循环中使用,在内层的循环中使用 break 语句,那么程序只会跳出内层的循环,并不会影响到外层循环的执行(跳出最内层循环所在的switch)。
cs
int total = 0;
for (int i = 1; i <= 100; i++)
{
if (i == 50)
break;
total+=i;//不执行,break跳出
}
continue(循环中)
C# 中 continue 语句的工作原理与 break 语句类似,但是 continue 语句并不会跳出当前的整个循环,而是跳过本次循环,继续执行下一次的循环。
cs
int total = 0;
for (int i = 1; i <= 100; i++)
{
if (i%10==0)
{
continue;整除10的数不会被累加,continue跳到for下一轮循环
}
total += i;
}
方法(函数)
方法声明:
C# 中声明方法的语法格式:
cs
//访问修饰符 返回值类型 方法名 (参数1,参数2)
public int Add(int num1,int num2)
{
int sum=num1 + num2; //方法主体
return sum; //返回值语句
}
需要注意的是,访问权限修饰符、参数列表和返回语句是可选的,可以省略
方法调用:
想要调用定义好的方法,首先需要将方法所在的类实例化为对象,然后通过**对象.方法名()
**的形式即可调用指定的方法,
这里有几点需要注意:
-
若方法在定义时参数列表中定义了若干参数,那么在调用时也应该在方法名后面的括号中传入相应数量的参数,并且与参数列表中的参数类型一一对应;
-
若方法在定义时没有定义参数列表,那么在调用方法时也不需要在方法名后面的括号内填入参数;
-
对于有返回值的方法,在调用方法时可以使用一个变量(可选)来接收方法的返回值,变量的类型要与方法返回值的类型相同
cs
调用方法
MethodClass method = new MethodClass();//实例化对象
//sum接收返回值 5,8是传入的参数值
int sum=method.Add(5, 8);
方法类型
根据方法的返回值和参数列表,方法可以分为:无参数和返回值方法、带参数无返回值方法、带参数有返回值方法、静态方法 。如果方法不需要传入任何数据,方法可以没有参数;如果不需要返回任何内容,则可以在定义方法时使用 void 来修饰返回值类型
-
静态方法(Static Method) :静态方法是属于类本身的方法,不依赖于类的实例,可以直接通过类名来调用,通过关键字static来声明。
cs
public class MyStaticClass
{
public static void StaticMethod()
{
Console.WriteLine("This is a static method.");
}
}
MyStaticClass.StaticMethod(); // 直接调用静态方法
方法的参数类型和传递方式
- 方法的参数分为值参数、引用参数、输出参数
- 参数列表中定义的参数 称之为形式参数,简称形参, 用来接收方法调用时传递过来的数据;对应值传递
- 实际参数:在方法被调用时传递给方法的参数 称之为实际参数,简称实参 ;对应引用传递
- 输出参数来在方法内部修改调用方传递的参数的值。输出参数用**
out
关键字** 声明,并且在调用方法时必须使用out
关键字来标识传递的参数 是输出参数。输出参数在方法执行完成后会被赋予新的值。
cs
//值传递,方法内部修改了值
public int AddNew(int num1, int num2)
{
num1 += 2;
Console.WriteLine("内部:a="+num1);
return num1+num2;
}
//调用
int a = 45,b=23;
Console.WriteLine("调用前:a="+a);
method.AddNew(a, b);
Console.WriteLine("调用后:a=" + a);
//输出: 修改形参的值,并不影响实参的值
调用前:a=45
内部:a=47
调用后:a=45
//引用传递,方法内部修改了值
public int AddRef(ref int num1, int num2)
{
num1 += 2;
Console.WriteLine("内部:a=" + num1);
return num1 + num2;
}
//调用
int a = 45,b=23;
Console.WriteLine("调用前:a="+a);
method.AddRef(ref a, b);
Console.WriteLine("调用后:a=" + a);
//输出: 修改形参的值,实参的值也改了
调用前:a=45
内部:a=47
调用后:a=47
//输出传递方法内部修改了num1的值
public int AddOut(out int num1, int num2)
{
num1 = num2+2;
Console.WriteLine("内部:a=" + num1);
return num1 + num2;
}
//调用
Console.WriteLine("调用前:a=" + a);
int sum= method.AddOut(out a, b);
Console.WriteLine("调用后:a=" + a);
//输出: 内部修改了输出参数的值,返回了修改后a的值
调用前:a=45
内部:a=25
调用后:a=25
方法参数组(params)
在有些情况下,我们在定义方法时并不能确定方法的参数的数量,这时可以使用 参数数组,参数数组通常用于为方法传递未知数量的参数。
如果使用参数数组,我们使用 params 关键字,语法如下:
cs
访问权限修饰符 返回值类型 函数名(params 类型名称[] 数组名称)
public void ShowMessage(params string[] infos)
使用参数数组时,调用方法时,既可以直接为方法传递一个数组作为参数,也可以使用函数名(参数1, 参数2, ..., 参数n)
的形式传递若干个具体的值。
cs
public static int AddNumbers(params int[] numbers)
{
int sum = 0;
foreach (int num in numbers)
{
sum += num;
}
return sum;
}
}
public class Program
{
public static void Main(string[] args)
{
int sum = AddNumbers(1, 2, 3, 4, 5);
Console.WriteLine($"Sum of numbers: {sum}");
}
数组
数组是一个用来存储相同类型数据的、固定大小的、具有连续内存位置 的顺序集合。数组中的每个元素都对应一个索引值,索引从 0 开始 依次递增,我们可以通过索引来访问数组中的指定元素。 所有数组都是由连续的内存位置 组成,最低的内存地址对应第一个元素,最高的内存地址对应最后一个元素。数组的长度是固定的,在创建时需要指定数组的长度,并且无法动态调整大小。
声明并初始化数组
cs
ushort[] usArr02=new ushort[10];//[10]代表数组的长度为10,未指定数据则存储默认数值
double[] dArr03=new double[15];
//可以使用索引为数组赋值,但是一个一个赋值太麻烦了
ushort[8]=2;
//可以在声明时直接为数组赋值,把元素值放在{}中,元素间用逗号(,)隔开。
float[] fArr={2.3f,66.9f,99.9f};//长度可写可不写
//数组与变量类似,所以也可以将一个数组赋值给另一个相同类型的数组,这样两个数组将指向同一个内存地址。
int[] intArr1=new int[]{1,23,45,10,55,90};
int[] intArr2=intArr1;
```
//还可以将一串用分隔符号连接字符串转换为数组。
string strArr = "Lee,Json,SQLServer,GitHub,School";
string[] items = strArr.Split(','); //这里用到了字符串的分割方法
//通过下标访问数组元素
int[] arr1 = new int[]{0, 11, 42,65,51, 76, 77, 98,19};
int val = arr1[5]; //访问第6个元素
//一般我们经常通过循环结构来访问数组中的元素。
//for循环遍历
int[] arr1 =new int[]{0, 11, 42,65,51, 76, 77, 98,19};
for(int i = 0; i < arr1.Length; i++) //一个数组的长度,用Length属性获取
{
Console.WriteLine("arr1[{0}] = {1}", i, arr[i]);
}
//foreach循环遍历
int[] arr1 =new int[]{43,32,11,67,100,97};
int i=0;
foreach(int item in arr1) //一个数组的长度,用Length属性获取
{
Console.WriteLine("arr[{0}] = {1}", i, item);
i++;
}
int[,] arr01=new int[3,4]; // 声明一个二维数组
short[,,] arr02=new short[2,3,2]; // 声明一个三维数组
int[,] arr = new int[3,2]{
{10,22},
{45,33},
{99,20}
};
int[,] arr = {
{0, 11, 12, 23},
{24, 35, 16, 37},
{18, 29, 30, 71}
};
//二维数组中的元素一样可以通过行和列索引来访问
int item=arr[1,2]; //表示取arr数组中第二行第3个元素的值。
int[,] arr = new int[3,4]
{
{0, 11, 12, 23},
{24, 35, 16, 37},
{18, 29, 30, 71}
};
//遍历数组
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.WriteLine("arr[{0},{1}] = {2}", i, j, arr[i, j]);
}
}
//**GetLength(i)** 获取指定维中的元素数,i表示维度
Array类操作数组的方法
cs
int[] intArr01 = { 22, 55, 64, 89, 90, 67 };
int[] intArr02 = { 20, 30, 40, 50 };
Array.Clear(intArr02, 2, 2);//清除指定范围元素的值为该类型的默认值
int[] intArr03=new int[2];
Array.Copy(intArr01, intArr03, 2);//复制指定数目的元素到目标数组
int[] intArr04 = new int[8];
intArr01.CopyTo(intArr04, 2);//从目标数组的指定处开始复制源数组中的所有元素
//获取指定维度中的元素数
int length= intArr03.GetLength(0);
//获取数组中指定维度第一个元素的索引
int findex = intArr01.GetLowerBound(0);
//获取指定位置处的值
var val= intArr02.GetValue(2);
//获取指定元素在数组中的索引
int index = Array.IndexOf(intArr02, 30);
Array.Reverse(intArr04);//翻转
intArr04.SetValue(99, 5);//设置指定位置的值
Array.Sort(intArr01);//排序