C#
coding online: https://repl.it/
Monte Carlo in C
using System;
class MainClass {
public static void Main (string[] args) {
// Construct a random number generator that generates random number greater than or equal to 0.0, and less than 1.0
Random rand = new Random();
// Approximate pi to within 5 digits.
double tolerance = 1e-5;
double piApproximation = 0;
int total = 0;
int numInCircle = 0;
double x, y; // Coordinates of the random point.
// Generate random points until our approximation within the desired tolerance.
while ( Math.Abs( Math.PI - piApproximation ) > tolerance )
{
x = rand.NextDouble();
y = rand.NextDouble();
if ( x * x + y * y <= 1.0 ) // Is the point in the circle?
{
++numInCircle;
}
++total;
piApproximation = 4.0 * ( (double) numInCircle / (double) total );
}
Console.WriteLine();
Console.WriteLine( "Pi calculated to within {0} digits with {1} random points.",
-Math.Log10( tolerance ), total );
Console.WriteLine( "Approximated Pi = {0}", piApproximation );
}
}
方法/函数
调用方法/函数时, 有三种参数传递的方式:
- 按值传递参数(默认). 它复制参数的实际值给函数的形式参数,实参(实际传入函数的参数)和形参(实际函数使用的参数)使用的是两个不同内存中的值. (形参的值发生改变时,不会影响实参的值)
- 按引用传递参数. 复制参数的内存位置的引用给形式参数. 即当形参的值发生改变时,同时也改变实参的值.
- 按输出传递参数. 输出参数会把方法输出的数据赋给自己 (这样可以返回多个值, return只能返回一个值)
code
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
// public void swap(ref int x, ref int y)
public void swap(int x, int y)
// public void swap(out int x, out 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);
/* 调用函数来交换值, 方式1, 交换后的值不变 */
// n.swap(a, b);
/* 调用函数来交换值, 方式2, 成功交换 */
n.swap(ref a, ref b);
/* 调用函数来交换值, 方式3 */
// n.swap(out a, out b);
Console.WriteLine("在交换之后,a 的值: {0}", a);
Console.WriteLine("在交换之后,b 的值: {0}", b);
Console.ReadLine();
}
}
}
可空类型 (Nullable)
一个特殊的数据类型. 例如,Nullable< Int32 >,读作”可空的 Int32”,可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也可以被赋值为 null 值.
int? num1 = null;
int? num2 = 45;
Null 合并运算符( ?? ):
int num3;
num3 = num1 ?? 5; // print 5
num3 = num2 ?? 5; // print 45
Array
初始化:
double[] balance = new double[10];
赋值:
balance[0] = 4500.0;
在声明数组的同时给数组赋值:
double[] balance = { 2340.0, 4523.69, 3421.0};
创建并初始化一个数组:
int [] marks = new int[5] { 99, 98, 92, 97, 95}; // 5是数组大小, 可以省略
访问:
double salary = balance[9];
使用 foreach 循环:
int count = 0;
foreach (double i in balance){
Console.WriteLine("Balance[{0}] = {1}", count,i);
count ++;
}
多维数组:
int [,] a = int [3,4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
访问多维数组:
int val = a[2,3];
交错数组(数组的数组):
int[][] scores = new int[2][]{new int[]{92,93,94},new int[]{85,66,87,88}};
访问交错数组:
int s = scores[0][0]
传递数组给函数:
code
using System;
namespace ArrayApplication
{
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 [] temp = new int[]{1000, 2, 3, 17, 50};
// int sum = app.AddElements(temp);
int sum = app.AddElements(512, 720, 250, 567, 889); // !!!
Console.WriteLine("总和是: {0}", sum);
Console.ReadKey();
}
}
}
params 关键字, 使调用数组为形参的方法时,既可以传递数组实参,也可以只传递一组数组
Array 类: https://www.w3cschool.cn/csharp/csharp-array-class.html
List VS ArrayList VS List
String
https://www.w3cschool.cn/csharp/csharp-string.html
Dictionary
Dictionary
2 | 2 | |
---|---|---|
3 | 4 |
属性/方法 | 说明 |
---|---|
Comparer | 获取用于确定字典中的键是否相等的 IEqualityComparer |
Count | 获取包含在 Dictionary中的键/值对的数目 |
Item | 获取或设置与指定的键相关联的值 |
Keys | 获取包含 Dictionary中的键的集合 |
Values | 获取包含 Dictionary中的值的集合 |
Add() | 将指定的键和值添加到字典中 |
Clear | 从 Dictionary中移除所有的键和值 |
ContainsKey() | 确定 Dictionary是否包含指定的键 |
ContainsValue | 确定 Dictionary是否包含特定值 |
GetEnumerator | 返回循环访问 Dictionary的枚举数 |
GetType | 获取当前实例的 Type (从 Object 继承) |
Remove() | 从 Dictionary中移除所指定的键的值 |
ToString | 返回表示当前 Object的 String (从 Object 继承) |
TryGetValue | 获取与指定的键相关联的值 |
https://www.w3cschool.cn/csharp/csharp-86c42por.html
Struct
使得一个单一变量可以存储各种数据类型的相关数据. 与类不同,结构可以不使用 New 操作符即可被实例化. 类是引用类型,结构是值类型; 结构不支持继承; 结构不能声明默认的构造函数;
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
Books Book1; /* 声明 Book1,类型为 Book */
/* book 1 赋值 */
Book1.title = "C Programming";
Book1.author = "Nuha Ali";
Book1.subject = "C Programming Tutorial";
Book1.book_id = 6495407;
/* Book1 读取 */
Console.WriteLine( "Book 1 title : {0}", Book1.title);
Console.WriteLine("Book 1 author : {0}", Book1.author);
Console.WriteLine("Book 1 subject : {0}", Book1.subject);
Console.WriteLine("Book 1 book_id :{0}", Book1.book_id);
Enum
一组命名整型常量.
enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };
int WeekdayStart = (int)Days.Mon;
Console.WriteLine("Monday: {0}", WeekdayStart);
Class
一个数据类型的蓝图.
code
using System;
namespace BoxApplication{
class Box{
public static int num; // 静态成员; 无论有多少个类的对象被创建,只会有一个该静态成员的副本
private double length;
private double breadth;
private double height;
/* 构造函数 */
public Box(double len){
Console.WriteLine("对象已创建");
length = len;
}
/* 析构函数, 当类的对象超出范围时执行, 它不返回值,也不带任何参数
用于在结束程序(比如关闭文件、释放内存等)之前释放资源
*/
~Box(){
Console.WriteLine("对象已删除");
}
/* 成员函数和封装 */
public void setLength(double len){
length = len;
}
public void setBreadth(double bre){
breadth = len;
}
public void setHeight(double hei){
height = hei;
}
public double getVolume(){
return length * breadth * height;
}
}
}
继承
OOP feature. 允许根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易. 同时也有利于重用代码和节省开发时间.
基类和派生类. 一个基类可以有多个直接派生类. 派生类会隐式获得基类的所有成员(所有变量跟函数, 除了其构造函数和终结器). 派生类因而可以重用基类中的代码,而无需重新实现, 也可以在派生类中添加更多成员.
code
//派生类
class Rectangle: Box{
public int getArea(){
return (length * height);
}
public void Display(){
Console.WriteLine("长度: {0}", length);
Console.WriteLine("高度: {0}", height);
Console.WriteLine("面积: {0}", GetArea());
}
}
基类的初始化 - 父类对象应在子类对象创建之前被创建, 可以在成员初始化列表中进行父类的初始化:
code
class Tabletop : Rectangle{
private double cost;
public Tabletop(double l, double h) : base(l, h){ } // !!!!!!
public double GetCost(){
double cost;
cost = GetArea() * 70;
return cost;
}
public void Display(){
base.Display(); // !!!!!!
Console.WriteLine("成本: {0}", GetCost());
}
}
C# 不支持多重继承. 但是, 可以使用接口来实现多重继承
code
using System;
namespace InheritanceApplication
{
class Shape {
public void setWidth(int w){
width = w;
}
public void setHeight(int h){
height = h;
}
protected int width;
protected int height;
}
// 基类 PaintCost
public interface PaintCost {
int getCost(int area);
}
// 派生类
class Rectangle : Shape, PaintCost{
public int getArea(){
return (width * height);
}
public int getCost(int area){
return area * 70;
}
}
class RectangleTester{
static void Main(string[] args){
Rectangle Rect = new Rectangle();
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// 打印对象的面积
Console.WriteLine("总面积: {0}", Rect.getArea());
Console.WriteLine("油漆总成本: ${0}" , Rect.getCost(area));
Console.ReadKey();
}
}
}
多态性
意味着有多重形式 —> 一个接口, 多个功能. 可以是静态(函数的响应是在编译时发生的) 或 动态(函数的响应是在运行时发生的)的
两种技术来实现静态多态性, 分别为:
- 函数重载
- 运算符重载
函数重载 - 在同一个范围内对相同的函数名有多个定义 (函数的定义必须彼此不同, 可以是参数类型不同 或者参数个数不同):
code
using System;
namespace PolymorphismApplication
{
class Printdata{
void print(int i){
Console.WriteLine("Printing int: {0}", i );
}
void print(double f){
Console.WriteLine("Printing float: {0}" , f);
}
void print(string s){
Console.WriteLine("Printing string: {0}", s);
}
void print(string s, string s1){
Console.WriteLine("Printing string: {0} and {1}", s,s1);
}
static void Main(string[] args){
Printdata p = new Printdata();
// 调用 print 来打印整数
p.print(5);
// 调用 print 来打印浮点数
p.print(500.263);
// 调用 print 来打印字符串
p.print("Hello C++");
// 调用 print 来打印字符串
p.print("Hello C++","Hello Charon");
Console.ReadKey();
}
}
}
动态多态性 - 用关键字 abstract 创建抽象类,用于提供接口的部分类的实现.当一个派生类继承自该抽象类时,实现即完成. 抽象类包含抽象方法,抽象方法可被派生类实现. 有关抽象类的一些规则:
- 不能创建一个抽象类的实例
- 不能在一个抽象类外部声明一个抽象方法
- 通过在类定义前面放置关键字 sealed,可以将类声明为密封类. 当一个类被声明为 sealed 时,它不能被继承.(抽象类不能被声明为 sealed)
code
using System;
namespace PolymorphismApplication
{
abstract class Shape{
public abstract int area();
}
class Rectangle: Shape{
private int length;
private int width;
public Rectangle( int a=0, int b=0){
length = a;
width = b;
}
public override int area (){ //!!!!
Console.WriteLine("Rectangle 类的面积:");
return (width * length);
}
}
class RectangleTester{
static void Main(string[] args){
Rectangle r = new Rectangle(10, 7);
double a = r.area();
Console.WriteLine("面积: {0}",a);
Console.ReadKey();
}
}
}
虚方法 - 实现在继承类中一个定义在类中的函数. 动态多态性是通过 抽象类 和 虚方法 实现的.
接口
接口(interface)定义了所有类继承接口时应遵循的语法合同. 接口定义了语法合同 “是什么” 部分(属性、方法和事件), 派生类定义了语法合同 “怎么做” 部分(成员的定义). (接口提供了派生类应遵循的标准结构)
code
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace InterfaceApplication{
// 接口
public interface ITransactions{
// 接口成员
void showTransaction();
double getAmount();
}
public class Transaction : ITransactions { // 继承接口
private string tCode;
private string date;
private double amount;
public Transaction(){
tCode = " ";
date = " ";
amount = 0.0;
}
public Transaction(string c, string d, double a){
tCode = c;
date = d;
amount = a;
}
// 必须实现接口的所有方法, 必须和接口的格式一致
public double getAmount(){
return amount;
}
// 必须实现接口的所有方法, 必须和接口的格式一致
public void showTransaction(){
Console.WriteLine("Transaction: {0}", tCode);
Console.WriteLine("Date: {0}", date);
Console.WriteLine("Amount: {0}", getAmount());
}
}
class Tester{
static void Main(string[] args){
Transaction t1 = new Transaction("001", "8/10/2012", 78900.00);
Transaction t2 = new Transaction("002", "9/10/2012", 451900.00);
t1.showTransaction();
t2.showTransaction();
Console.ReadKey();
}
}
}
命名空间
命名空间(Namespace)的设计目的是为了提供一种让一组名称与其他名称分隔开的方式. 一个 namespace 是一系列的类.
using 关键字表明程序使用的是给定命名空间中的名称, 这样在使用的时候就不用在前面加上命名空间名称.
code
using System;
using first_space;
namespace first_space{
class abc{
public void func(){
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space{
class efg{
public void func(){
Console.WriteLine("Inside second_space");
}
}
}
class TestClass{
static void Main(string[] args){
abc fc = new abc(); // first_space用了using, 所以不需要指定命名空间中的名称
second_space.efg sc = new efg(); // seconde_space没用using, 所以需要指定命名空间中的名称
fc.func();
sc.func();
Console.ReadKey();
}
}
异常处理
try, catch, finally, throw
code
using System;
namespace ErrorHandlingApplication
{
class DivNumbers{
int result;
DivNumbers(){
result = 0;
}
public void division(int num1, int num2){
try{
result = num1 / num2;
}
catch (DivideByZeroException e){
Console.WriteLine("Exception caught: {0}", e);
}
finally{
Console.WriteLine("Result: {0}", result);
}
}
static void Main(string[] args){
DivNumbers d = new DivNumbers();
d.division(25, 0);
temperature = Console.ReadLine();
if(temperature == 0){
throw (new TempIsZeroException("Zero Temperature found"));
}
Console.ReadKey();
}
}
}
bubble sort
code
int[] array = new int[*];
for (int i=0; i < array.Length; i++){
for(int j = i+1; j < array.Length; j++){
if (array[j] < array[i]){
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}