文章目录
C# 程序结构:
1.命名空间声明(Namespace declaration ,一个 namespace 里包含了一系列的类)
2.class (类一般包含多个方法。方法定义了类的行为。)
3.Class 方法
4.Class 属性
5.一个 Main 方法
6.语句(Statements)& 表达式(Expressions)
7.注释
注意:
1.C# 是大小写敏感的。
2.所有的语句和表达式必须以分号(;)结尾。
3.程序的执行从 Main 方法开始。
4.与 Java 不同的是,文件名可以不同于类的名称。
1. 接受来自用户的值
System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。
int num;
num = Convert.ToInt32(Console.ReadLine());
2. 类型转换
double d = 5673.74;
int i;
// 强制转换 double 为 int
i = (int)d;
Console.WriteLine(i);
Console.ReadKey();
//---结果:5673
内置的类型转换方法举例,把不同值的类型转换为字符串类型
int i = 75;
float f = 53.005f;
double d = 2345.7652;
bool b = true;
Console.WriteLine(i.ToString());
Console.WriteLine(f.ToString());
Console.WriteLine(d.ToString());
Console.WriteLine(b.ToString());
Console.ReadKey();
/*结果:
75
53.005
2345.7652
True
*/
3. 常量定义与使用
用 const 关键字来定义的
const <data_type> <constant_name> = value;
4. switch语法
switch(expression){
case constant-expression :
statement(s);
break;
case constant-expression :
statement(s);
break;
......
default : /* 可选的 */
statement(s);
break;
}
注意:
- expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
- C# 不允许从一个开关部分继续执行到下一个开关部分。如果 case 语句中有处理语句,则必须包含 break 或其他跳转语句。若不含break,则switch语句结束。
- C# 不支持从一个 case 标签显式贯穿到另一个 case 标签。如果要使 一个 case 标签显式贯穿到另一个 case 标签,可以使用 goto 一个 switch-case 或 goto default。
- 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
- switch 语句可嵌套使用。
5. foreach循环
使用foreach可以迭代数组或者一个集合对象
int[] fibarray = new int[] { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibarray)
{
System.Console.WriteLine(element);
}
System.Console.WriteLine();
/* 结果:
0
1
1
2
3
5
8
13
*/
6. 封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。
public:所有对象都可以访问;
private:对象本身在对象内部可以访问;
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型。
7. 方法
(1) 定义
<访问修饰符> <返回类型> <方法名>(参数列表)
{
方法主体,包含了完成任务所需的指令集
}
注意:方法名是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同
(2)调用(同JAVA)
- 方法名调用方法
- 使用类的实例从另一个类中调用其他类的公有方法
- 递归方法调用(但是耗内存)
(3)参数传递
-
按值传递参数
调用方法时,会为每个值参数创建一个新存储位置。 实参的值会复制给形参,实参和形参使用的是两个不同内存中的值。
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void swap(int x, int y)
{
int temp;
temp = x; /* 保存 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 temp 赋值给 y */
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* 局部变量定义 */
int a = 100;
int b = 200;
Console.WriteLine("在交换之前,a 的值: {0}", a);
Console.WriteLine("在交换之前,b 的值: {0}", b);
/* 调用函数来交换值 */
n.swap(a, b);
Console.WriteLine("在交换之后,a 的值: {0}", a);
Console.WriteLine("在交换之后,b 的值: {0}", b);
Console.ReadLine();
}
}
}
/* 结果:
在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:100
在交换之后,b 的值:200
*/
-
按引用传递参数
引用参数是一个对变量的内存位置的引用。按引用传递参数时,它不会为这些参数创建一个新的存储位置。 引用参数表示与提供给方法的实际参数具有相同的内存位置。 在 C# 中,使用 ref 关键字声明引用参数
public void swap(ref int x, ref int y)
{
int temp;
temp = x; /* 保存 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 temp 赋值给 y */
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* 局部变量定义 */
int a = 100;
int b = 200;
Console.WriteLine("在交换之前,a 的值: {0}", a);
Console.WriteLine("在交换之前,b 的值: {0}", b);
/* 调用函数来交换值 */
n.swap(ref a, ref b);
Console.WriteLine("在交换之后,a 的值: {0}", a);
Console.WriteLine("在交换之后,b 的值: {0}", b);
Console.ReadLine();
}
/* 结果:
在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:200
在交换之后,b 的值:100
*/
-
按输出传递参数
return 语句可用于只从函数中返回一个值。 但是,可以使用输出参数来从函数中返回两个值。 输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
class NumberManipulator
{
public void getValue(out int x )
{
int temp = 5;
x = temp;
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* 局部变量定义 */
int a = 100;
Console.WriteLine("在方法调用之前,a 的值: {0}", a);
/* 调用函数来获取值 */
n.getValue(out a);
Console.WriteLine("在方法调用之后,a 的值: {0}", a);
Console.ReadLine();
}
}
/*
结果:
在方法调用之前,a 的值: 100
在方法调用之后,a 的值: 5
*/
注意关键字 out (out关键字用法)
函数成员调用中,输出参数在传递之前不一定要明确赋值,但正常返回前都必须明确赋值。
提供给输出参数的变量不需要赋值。
class NumberManipulator
{
public void getValues(out int x, out int y )
{
Console.WriteLine("请输入第一个值: ");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("请输入第二个值: ");
y = Convert.ToInt32(Console.ReadLine());
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* 局部变量定义 */
int a , b;
/* 调用函数来获取值 */
n.getValues(out a, out b);
Console.WriteLine("在方法调用之后,a 的值: {0}", a);
Console.WriteLine("在方法调用之后,b 的值: {0}", b);
Console.ReadLine();
}
}
/*
请输入第一个值:
7
请输入第二个值:
8
在方法调用之后,a 的值: 7
在方法调用之后,b 的值: 8
*/
8. 可空类型(Nullable)
(1)单问号 ?
单问号用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是 Nullable 类型的。书写格式如下:
int? i = 3;
// 等同于 Nullable<int> i = new Nullable<int>(3);
int i; //默认值0
int? ii; //默认值null
(2)双问号 ??
用于判断??左边的对象是否为 null,如果不为 null 则使用 ?? 左边的对象,如果为 null 则使用 ?? 右边的对象
a = b ?? c
如果 b 为 null,则 a = c,如果 b 不为 null,则 a = b。
9. 数组
(1)声明
double[] balance;
(2)初始化
double[] balance = new double[10];
//长度为10的double类数组
(3)赋值
不赋值则根据数组类型隐式初始化每个数组元素为一个默认值
eg: int 数组的所有元素均初始化为0
1)使用索引号赋值
double[] balance = new double[10];
balance[0] = 4500.0;
2)声明数组的同时赋值
double[] balance = { 2340.0, 4523.69, 3421.0};
3)创建并初始化时赋值
其中数组的大小可省略
int [] marks = new int[5] { 99, 98, 92, 97, 95};
4)赋值一个数组变量到另一个目标数组变量
目标和源会<u>指向同一内存 </u>
int [] marks = new int[] { 99, 98, 92, 97, 95};
int[] score = marks;
(4)访问
按索引 double salary = balance[9];
(5)多维数组(矩形数组)
1)声明
string [,] names; // 二维
int [ , , ] m; // 三维
2)初始化并赋值
/* 一个带有 5 行 2 列的数组 */
int[,] a = new int[5, 2] {
{0,0}, {1,2}, {2,4}, {3,6}, {4,8}
};
(6)交错数组
交错数组是一维数组,是数组的数组。
1)声明
int [][] scores;
2)初始化
int[][] scores = new int[2][]
{
new int[]{92,93,94},
new int[]{85,66,87,88}
};
3)使用
static void Main(string[] args)
{
/* 一个由 5 个整型数组组成的交错数组 */
int[][] a = new int[][]{new int[]{0,0},new int[]{1,2},
new int[]{2,4},new int[]{ 3, 6 }, new int[]{ 4, 8 } };
int i, j;
/* 输出数组中每个元素的值 */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 2; j++)
{
Console.WriteLine("a[{0}][{1}] = {2}", i, j, a[i][j]);
}
}
Console.ReadKey();
}
/*
结果:
a[0][0] = 0
a[0][1] = 0
a[1][0] = 1
a[1][1] = 2
a[2][0] = 2
a[2][1] = 4
a[3][0] = 3
a[3][1] = 6
a[4][0] = 4
a[4][1] = 8
*/
(7)给函数传递数组
可通过指定不带索引的数组名给函数传一个指向数组的指针
class MyArray
{
double getAverage(int[] arr, int size)
{
int i;
double avg;
int sum = 0;
foreach(int member in arr)
{
sum += member;
}
avg = (double)sum / size;
return avg;
}
static void Main(string[] args)
{
MyArray app = new MyArray();
/* 一个带有 5 个元素的 int 数组 */
int [] balance = new int[]{1000, 2, 3, 17, 50};
//&&&&&&&&&&&&&&&&&&&&&&&
double avg;
/* 传递数组的指针作为参数 */
avg = app.getAverage(balance, 5 ) ;
//&&&&&&&&&&&&&&&&&&&&&&&
/* 输出返回值 */
Console.WriteLine( "平均值是: {0} ", avg );
Console.ReadKey();
}
}
/*
结果:
平均值是: 214.4
*/
(8)参数数组
参数数组通常用于传递未知数量的参数给函数。
params 关键字,使调用数组为形参的方法时,既可以传递数组实参,也可以传递一组数组元素。
使用格式如下:
public 返回类型 方法名称( params 类型名称[] 数组名称 )
// 示例:
class ParamArray
{
public int AddElements( params int[] arr )
{
int sum = 0;
foreach (int i in arr)
{
sum += i;
}
return sum;
}
}
class TestClass
{
static void Main(string[] args)
{
ParamArray app = new ParamArray();
int sum = app.AddElements(512, 720, 250, 567, 889);
Console.WriteLine("总和是: {0}", sum);
Console.ReadKey();
}
}
(9)Array 类常用方法
1)复制
① Copy(Array, Array, Int32)
从数组第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。
长度由一个 32 位整数指定。
② CopyTo(Array, Int32)
从当前一维数组中复制所有元素到另一个一维数组的指定索引位置。
索引由一个 32 位整数指定。
2)获取数组中的元素总数
① GetLength
获取一个 32 位整数,该值表示指定维度的数组中的元素总数。
②GetLongLength
获取一个 64 位整数,该值表示指定维度的数组中的元素总数。
3)获取数组上下界
① GetLowerBound
获取数组中指定维度的下界。
② GetUpperBound
获取数组中指定维度的上界。
4)获取数组指定位置的值,指定对象的索引
① GetValue(Int32)
获取一维数组中指定位置的值。索引由一个 32 位整数指定。
② IndexOf(Array, Object)
搜索指定的对象,返回整个一维数组中第一次出现的索引。
5)排序 & 逆序 (均仅支持一维数组)
① Sort(Array)
对整个一维数组中的元素进行排序,
会直接修改原数组。
② Reverse(Array)
逆转整个一维数组中元素的顺序。
6)转字符串
① ToString
返回一个表示当前对象的字符串。从对象(Object)继承。
10. 字符串(String)
(1)创建方式
转化值的格式化:
DateTime waiting = new DateTime(2012, 10, 10, 17, 58, 1);
string chat = String.Format("Message sent at {0:t} on {0:D}",
waiting);
Console.WriteLine("Message: {0}", chat);
Console.ReadKey() ;
/*
Message: Message sent at 17:58 on Wednesday, 10 October 2012
*/
(2)String 类的属性
1)Chars
获取当前 String 对象中 Char 对象的指定位置。
2)Length
获取当前的 String 对象中字符数目。
(3)String 类的方法
1)连接n个 string 对象
public static string Concat( string str0, string str1 ..., string strn )
2)判断对象是否出现在字符串中
public bool Contains( string value )
3)创建与指定字符串具有相同值的新的 String 对象
public static string Copy( string str )
4)从指定位置开始复制指定数量的字符到 Unicode 字符数组中的指定位置
public void CopyTo( int sourceIndex, char[] destination, int destinationIndex, int count )
5)判断 string 对象的结尾是否匹配指定的字符串
public bool EndsWith( string value )
6)判断两个string 对象的值是否相同
① 判断两个 指定 的 string 对象是否具有相同值
public static bool Equals( string a, string b )
② 判断当前的string 对象是否与指定的string 对象具有相同值
public bool Equals( string value )
7)插入字符串
返回一个新的字符串,其中,指定的字符串被插入在当前 string 对象的指定索引位置。
public string Insert( int startIndex, string value )
8)连接数组元素
连接一个字符串数组中所有元素,用指定分隔符分隔每个元素
public static string Join( string separator, string[] value )
9)转大小写并返回
public string ToUpper() ——转大写
public string ToLower() ——转小写
。。。。。