for 循环性能比较 提高for循环的效率

for(int i=1,n=tempUser.length;i 复制代码 代码如下:class Program { static
void Main { string s; s = Console.ReadLine { Person p = new Person;
Console.WriteLine(“for(int i=0;i其中数据量越大,类越大,差别越明显。

for(int i=1,n=tempUser.length;i <n;i++)与
for(int i=1,;i
<tempUser.length;i++)相比较,性能有较大的区别吗,有必要采取这种写法吗,
习惯for(int i=1,;i
<tempUser.length;i++),而且并没有发现两者的性能有较大差别,
我当即就测试了一下,发现果然性能比较起来差别很小,甚至后者更高效一点。
虽然得出这样的结果,但和自己心里想的确完全相反的。所有当然就回复说差不多。
今天又发现一位前辈的blog中正好有对这个帖子的回应。他做了测试,内容大致是前面的帖子的问题应该是差不多的,但是他又更深入的进行测试,得出:在有情况for(int
i=0;i<a.b.c.length;i++)的情况的时候,使用for(int
i=0,n=a.b.c.length;i<n;i++)更加高效。
所有我也做了一下测试:

C#学习记录,

转眼几个月没更博了,把几个月前学C#的笔记发一下,就记录了点教重要的点子而已

 

1.打印

Console.WriteLine(); 打印

Console.ReadKey();
按一个按键继续执行

Console.ReadLine();
//用户输入文字的时候程序是暂停的,用户输入完毕点回车,把用户输入的东西做为返回值

例:

string s =  Console.ReadLine();
读取进去的是字符串,所以不能用其他类型接收

 

 

2.数据类型:

值类型:int、float、double、char、byte、Boolean、枚举

引用类型:DateTime、string、所有类

 

类型转换:

值类型:从小到大自动转,从大到小强制转,(类型),Convert.To***()

引用类型:需要有继承关系才可以转换

转换成字符串: ToString()

类型转换:cast
强转(位数有差,可能丢失)

      convert
考虑数据意义的转换

C#字符串与OC一致,与C不一致,不考虑最后的\0

 

 

‘a’   是char类型,”a”是string类型

@“\\\\”
@表示字符串中的\不当成转义符

 

 

3.字符串的处理

·C#中单个字符用单引号包含就是char类型,(‘a’),单引号中放且只能放一个字符。

·单个字符也可以表示为字符串,还可以有长度为0的字符串。

·使用s.Length属性可以来获得字符串中的字符个数

·string可以看做是char的只读数组。char c =
s[1];例子:遍历输出sting中的每个元素。

·c#中字符串有一个重要的特性:不可变性,字符串一旦声明就不再可以改变。所以只能通过索引来 
 

  读取指定位置的char进行修改。

·如果要对char进行修改,那么久必须创建一个新的字符串,用s.ToCharArray()方法得到字符串的

 char 数组,对数组进行修改后,调用new
string(char[])这个构造函数来创建char数组的字符串。一

 旦字符串被创建,那么char
数组的修改也不会造成字符串的变化。例子:将字符串中的A替换成a.

 

 

 

字符串不可变性(分配的内存块里的不可变)

string s1 = @“hello”;

char[] chars = s1.ToCharArray();

string s2 = new string(chars);

此时改变后s2为aello,而s1不变,所以只是复制了一份char数组数据,于源数据无关

 

如string s = “abc”; s = @“123”

最后值改变了,其实不是

要区分变量名和变量指向的值得区别。程序中可以有很多字符串,然后由字符串变量指向他们,变量可以指向其他的字符串,但是字符串本身没有变化。字符串不可变性指的是内存中的字符串不可变,而不是变量不变。

 

 

4.字符串类的常用函数

 

1)

·ToLower() 得到字符串的小写形式。

·注意字符串是不可变的,所以这些函数都不会直接改变字符串的内容,而是把修改后的值通过函数·返回值的形式返回。s.ToLower()与s
= s.ToLower()

·ToUpper():得到字符串的大写形式:Trim()去掉字符串两端的空白。

·s1.Equals(s2,StringComparison.OrdinallgnoreCase),两个字符串进行区分大小写的比较

Ignore:忽略,Case:大小写

==是区分大小写的比较,Equals()是忽略大小写的比较

 

 

2)分割字符串

string[] str = strings.Split(‘,’);
将字符串按照指定的分割符分割成字符串数组

 

将字符串按照指定的char分割符分割成字符串数组(options取RemoveEmptyEntries时,移除结果中的空白字符串)

string str1 = @“aa,bb,,cc,dd”;出现空字符串 

string[] str = strings.Split(new
char[]{’,’},StringSplitOptions.RemoveEmptyEntries);

 

将字符串按照指定的string分割符分割成字符串数组(同上)

string[] str = strings.Split(new
string[]{“aa”},StringSplitOptions.RemoveEmptyEntries);

 

 

3)替换字符串

string.Replace(“a”,”b”);
替换string里面的a全部成b

获取子字符串:

string.Substring(n);    
从第n位开始截取string的字符串到结束,包含n

string.Substring(n,m);    
从第n位开始截取string的字符串长度为m(m超过string长度会出错),包含n

 

 

4)返回bool值 使用:string.Contains

Contains(string value)判断字符串中是否含有子串value

StartsWith(string value)判断字符串中是否以子串value开始

EndsWith(string value)判断字符串中是否以子串value结束

返回int

IndexOf(string value)取子串value第一次出现的位置

 

 

 

 

 

 

枚举,跟其它语言没什么区别

枚举的意义就在于限定变量的取值范围

enum sender{a,b}

 

 

foreach (string name in names){};
遍历,还有for,见多了

 

 

static void function(params string[] values){};

params 可变参数 参数必须是形参表中的最后一个参数

 

 

函数重载:函数名一致,参数不一致,可做两个函数使用,与有无返回值无关(不严谨)

 

 

 

函数的ref和out参数

函数参数默认是值传递的,也就是”复制一份”

而ref是将本身传进去,非复制

 

static void Main(string[] args)

{

int age = 20;

1:
IncAge(age);

2: IncAge(ref
age);

Console.WriteLine(age);
//1打印结果为20,因为传进的只是形参值;2打印结果为21,

Console.ReadKey;

}

1:

static void IncAge(int age)

{

age++;

}

2:

static void IncAge(ref int age)

{

age++;

}

 

ref必须先初始化因为是引用,所以必须先“有”,才能引用,而out是内部为外部赋值,所以不需要初始化,而且外部初始化也没有用。

ref应用场景内部对外部的值进行改变,out则是内部为外部变量赋值,out一般用在函数有多个返回值的场所。

 

 

string str = Console.ReadLine();

int i;

int.TryParse(str,out i); //转换 返回值true  or false

 

ref应用,如交换两个数的值

 

 

5.构造函数

 

·构造函数用来创建对象,并且可以在构造函数中对对象进行初始化。

·构造函数是用来创建对象的特殊函数,函数名和类名一样,没返回值,连void都不用。

·构造函数可以有参数,new对象的时候传递函数参数即可

·构造函数可以重载,也就是有多个参数不同的构造函数。

·如果不指定构造函数,则类有一个默认的无参构造函数。

 如果指定了构造函数,则不再有默认的无参构造函数,如果需要无参构造函数,则需要自己来写。

如:

static void Main(string[] args)

{

Person p1 = new Person();

Person p2 = new Person(“a”);

Person p3 = new Person(“a”,2);

Console.ReadKey;

}

class Person

{

public Person()

{

 

}

public Person(string name)

{

 

}

public Person(string name,int age)

{

 

}

}

 

 

 

 

 

 

 

 

 

 

对面可以叫做类的实例,字段就是类的状态

面向对象的三个特性:封装、继承、多态。

 

 

 

 

 

 

 

 

 

6.属性(可公可私有)

惯用法:属性开头字母大写,字段开头字母小写

public字段和属性的区别,属性可以进行非法设置值的判断

 

class person

{

private int age;

public int Age

{

set
//赋值

    {

if(age>0)

{

return;
//如果return this.Age;造成死循环,自己给自己赋值

}

this.age = value; //value代表用户赋值过来的值

    }

get
//取值

    {

return this.age;

    }

 

}

}

 

 

 

 

 

7.异常

try{

执行到错误点后,不再往下执行

}

catch(Exception ex){

出错后执行,再跳到外面继续执行

Console.WriteLine(“数据错误:”+ex.Message+”。异常堆栈:”+ex.StackTrace);

}

 

throw:抛出   catch:抓住

//自定义报错异常声明

else{

throw new Exception(“自定义异常”);

}

 

 

const 常量:不会改变的量

 

静态变量:static
属于全局变量,无需new

在static成员中不能直接调用非static成员

例:

class Person

{

public static int TotalCount;

public int Age;

public static void number()

{

Console.WriteLine(@“{0}”,TotalCount);

//可调用TotalCount,但调不了Age

}

 

public void
Other()//非static成员中科院调用static成员

{

Console.WriteLine(@“{0},{1}”,TotalCount,Age);

}

}

 

 

 

 

 

 

8.静态类

static class Person

{}

无法被new的类是静态类,静态类一般用来实现一些函数库。

 

 

 

 

 

 

 

 

 

 

 

9.命名空间

 

当有多个类重名时,可放不同文件夹下,或namespace不一样,使用时写全路径就行

当前类文件里有Person类

另一个文件夹名为hr,或namespace不一致的类下面有个类Person

 

在当前类文件里使用hr文件夹里的Person类时如下:

如果要使用的类和当前的类不在同一个namespace,则需要添加using引用

导入该文件,在顶部

using 命名空间.hr;

命名空间.hr.Person p2 = new 命名空间.hr.Person();

//就像文件的全路径一样

 

 

10.索引

C#中提供了按照索引器进行访问的方法

定义索引器的方式:string this[int index]

{

get {

return “”;

}

set{}

}

string为索引器的类型,[]中是参数列表。进行索引器写操作就是调用

set代码块,在set内部使用value得到用户设置的值;进行读操作就是

执行get代码块。

索引器参数可以不止一个,类型也不限于int,几号可以是任意类型。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

11.

项目认识,从各个地方复制

 

 

String.Empty是string类的一个静态常量;

String.Empty和string=””区别不大

 

string s1 = “”;

string s2 = string.Empty;

if (s1 == s2)<br>{

    Console.WriteLine(“一模一样!”);

}   

// 结果都是True

 

String.Empty和string=””一样,同样需要占用内存空间,为什么推荐优先使用String.Empty
?

string.Empty只是让代码好读,防止代码产生歧义

 

 

 

 

 用于控制一个对象是否激活,一个对象激活当且本身active=true,并且它的父结点也都active。相当API有:

  1)GameObject.SetActive

  2)GameObject.activeSelf

  3)GameObjectd.activeInHierarchy

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Socket.BeginReceive 方法 (Byte[], Int32, Int32, SocketFlags,
AsyncCallback, Object)

 

语法

[HostProtectionAttribute(SecurityAction.LinkDemand, ExternalThreading =
true)]

public IAsyncResult BeginReceive(

byte[] buffer,

int offset,

int size,

SocketFlags socketFlags,

AsyncCallback callback,

object state

)

 

参数

buffer

Byte 类型的数组,它是存储接收到的数据的位置。

offset

buffer 参数中存储所接收数据的位置,该位置从零开始计数。

size

要接收的字节数。

socketFlags

SocketFlags 值的按位组合。

callback

一个 AsyncCallback 委托,它引用操作完成时要调用的方法。

state

一个用户定义对象,其中包含接收操作的相关信息。当操作完成时,此对象会被传递给 EndReceive 委托。

返回值

Type: System.IAsyncResult

引用异步读的 IAsyncResult。

 

 

 

 

 

 

异常

 

 

Exception

Condition

ArgumentNullException

buffer 为 null

SocketException

试图访问套接字时发生错误。有关更多信息,请参见备注部分。

ObjectDisposedException

Socket 已关闭。

ArgumentOutOfRangeException

offset 小于 0。

– 或 –

offset 大于 buffer 的长度。

– 或 –

size 小于 0。

– 或 –

size 大于 buffer 的长度减去 offset 参数的值。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Socket.BeginReceive 方法 (Byte[], Int32, Int32, SocketFlags,
AsyncCallback, Object)

开始从连接的 Socket 中异步接收数据。

命名空间:   System.Net.Sockets

程序集:  System(System.dll 中)

 

语法

 

[HostProtectionAttribute(SecurityAction.LinkDemand, ExternalThreading =
true)]

public IAsyncResult BeginReceive(

byte[] buffer,

int offset,

int size,

SocketFlags socketFlags,

AsyncCallback callback,

object state

)

 

参数

buffer

Byte 类型的数组,它是存储接收到的数据的位置。

offset

buffer 参数中存储所接收数据的位置,该位置从零开始计数。

size

要接收的字节数。

socketFlags

SocketFlags 值的按位组合。

callback

一个 AsyncCallback 委托,它引用操作完成时要调用的方法。

state

一个用户定义对象,其中包含接收操作的相关信息。当操作完成时,此对象会被传递给 EndReceive 委托。

返回值

Type: System.IAsyncResult

引用异步读的 IAsyncResult。

异常

 

 

Exception

Condition

ArgumentNullException

buffer 为 null

SocketException

试图访问套接字时发生错误。有关更多信息,请参见备注部分。

ObjectDisposedException

Socket 已关闭。

ArgumentOutOfRangeException

offset 小于 0。

– 或 –

offset 大于 buffer 的长度。

– 或 –

size 小于 0。

– 或 –

size 大于 buffer 的长度减去 offset 参数的值。

 

 

 

备注

 

 

将 count 个字节从 src 复制到 dst,前者开始于 srcOffset 而后者开始于
dstOffset。

开发人员应谨记 BlockCopy 方法使用偏移量访问 src
参数,而不是使用索引或数组上下限等编程构造。例如,如果使用应用程序的编程语言声明一个上限为零,下限为
-50 的 Int32 数组,然后将该数组和偏移量 5 传递给 BlockCopy
方法,则该方法将访问的第一个数组元素是该数组的第二个元素(位于索引 -49
处)。此外,首先访问数组元素 -49 的哪个字节取决于执行应用程序的计算机的
Edian 设置。

 

 

 

 

 

 

 

 

 

 

Add和AddRange

 

Add:将指定的对象添加到……中

AddRange:向……末尾,添加数组

在群体操作时,使用AddRange取代Add 

 

用AddRange可以让我们要加入的东西一次性加入,而不要每次都加一次,这样显然可以加快速度。几乎所有的windows
control都支持Add和AddRange两种方法。

转眼几个月没更博了,把几个月前学C#的笔记发一下,就记录了点教重要的点子而已
1.打印 Console.WriteLine(); 打印 Console.ReadKe…

结论:影响应该在,变量在每次循环都要访问下一级变量的原因。如果只是简单的a.length可能编译器对这样的循环操作有优化,将a.length保存到了内存或一个比内存更块的地方,而多级就没有这么幸运了。我们都知道for(int
i=0;i

复制代码 代码如下:

class Program {
static void Main(string[] args) {
string s;
s = Console.ReadLine();

while(s != “0”) {
Person p = new Person(10000000);

Console.WriteLine(“for(int i=0;i<lenArray.length;i++)”);
Console.WriteLine(“Starting…”);
long l1 = DateTime.Now.Ticks;