c,c++,c#,java?这些有什么区别?java
C语言:linux
目前最著名、最有影响、应用最普遍的windows、linux和UNIX三个操做系统都是用C语言编写的。0S是计算机系统(由软硬件两个子系统构成)的核心和灵魂,它是软件中最庞大最复杂的系统软件。既然如此庞大复杂的0S均可以用c语言编写,从狭义而言,还有什么系统软件和应用软件不能用c语言编写呢?由此能够确定的说,c语言是一门十分优秀而又重要的语言。c++
c语言程序设计是过程性程序设计语言,它的发展贯穿了计算机发展的历程,它蕴含了程序设计的基本思想,囊括了程序设计的基本概念,因此它是理工科高等院校的一门基础课程。算法
从市面上有关c语言的书籍和高等院校采用的教材来看,它们有一个共性,那就是:脱离了实际应用(全是小打小闹的小例子),纯粹的过程性程序设计,没有软件工程思想的体现,没有必定程序设计风格,仅仅是为了让你们明白什么是c语言而已。编程
高等院校开设c语言程序设计的目的是让学生对程序设计有个入门,有个直观的理解,同时为其余后续课程做铺垫。c#
C++:windows
C++语言是在C语言的基础是扩展而成的.因此两种语言的基本语法和语义是相同。C++中加入了面向对程序设计(OOP)的特征。数组
下面的三个主要性质刻划OOP语言的特色:安全
封装性:把一个数据结构同操做的函数(行为或方法)组合在一块儿。封装性是借助于一种新的结构和数据类型机制——类实现的。网络
继承性:创建一个新的派生类,它从一个或多个先前定义的基类中继承函数和数据,并且可能从新定义或加进新的数据行为,这样就创建了类的层次。
多态性:给行为取一个名字或符号,它共享一个类的层次,在这个层次中的每一个类都以适合本身的方式实现这个行为。
C#:
C#(读作 "C sharp",中文译音“夏普”)是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言,并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新成果.C#看起来与Java有着惊人的类似;它包括了诸如单一继承,界面,与Java几乎一样的语法,和编译成中间代码再运行的过程.可是C#与Java有着明显的不一样,它借鉴了Delphi的一个特色,与COM(组件对象模型)是直接集成的,并且它是微软公司.NET windows网络框架的主角.
Java:
Java是一种能够编写跨平台应用软件的面向对象的程序设计语言,由升阳(太阳微电子,Sun Microsystems)公司的James Gosling等人于1990年代初开发的.具备如下特征的高级程序语言:
简单面向对象可分布可解释强壮安全性结构化轻便功能强大多线程动态...
Java既能够被编译,也能够被解释。经过编译器,能够把Java程序翻译成一种中间代码 -称为字节码 -能够被Java解释器解释的独立于平台的代码。经过解释器,每条Java字节指令被分析,而后在计算机上运行。只需编译一次,程序运行时解释执行。
C语言与VC++的区别有不少:
1,全新的程序程序思惟,C语言是面向过程的,而VC++是面向对象的。
2,C语言有标准的函数库,它们松散的,只是把功能相同的函数放在一个头文件中;而VC++对于大多数的函数都是有集成的很紧密,特别是C语言中没有的VC++6.0中的API是对Window系统的大多数API有机的组合,是一个集体。但你也可能单独调用API。
3,特别是VC++中的图形处理,它和语言的图形有很大的区别。C语言中的图形处理函数基本上是不能用在中VC++中的。主持人注:C语言标准中不包括图形处理。这里的C语言的图形处理指的是DOS下的C语言。
4,C和VC++中都有结构的概念,可是在C语言中结构只有成员变量,而没成员方法,而在VC++中结构中,它能够有本身的成员变量和成员函数。可是在C语言中结构的成员是公共的,什么想访问它的均可以访问;而在VC++中它没有加限定符的为私有的。
4,C语言能够写不少方面的程序,可是VC++能够写得更多更好,VC++能够写基于DOSr程序,写DLL,写控件,写系统。
5,C语言对程序的文件的组织是松散的,几乎是全要程序处理;而vc++对文件的组织是以工程,各文件分类明确。
6,VC++中的IDE很智能,和VB同样,有的功能可能比VB还强。
7,VC++对能够自动生成你想要的程序结构使你能够省了不少时间。有不少可用的工具如加入MFC中的类的时候,加入变量的时候等等。
8,VC++中的附加工具也有不少,能够进行系统的分析,能够查看API;能够查看控件。
9,调试功能强大,而且方法多样。
首先我先回答你关于“面向对象”和“面向过程”的区别。
他们主要是编程的思想的不一样。。。
举个例子:好比你想作一个模型飞机,利用“面向过程”的思想,你所想的就是,先作头再作身体,再作尾巴。。它是一个比较顺着的概念。而若是利用“面向对象”的思想,你所想的就是,你要作飞机的话,它有翅膀,头部,身体,尾巴等各个部件,你先把各个部分作好,再考虑他们的直接的接口怎么连。。。这就是区别。你能够发现“面向对象”的优点。
再就是C,C++,C#的问题。。因为我是先学的C语言再学的C++,因此,个人想法就是,光是从C语言和C++这个方向上说的话,而不从他们的编程程序VC6.0以及turboC来讲,C++是在C语言的思想上引入了关键性的“类(class)”的问题。而从编程的整体思想上即算法上区别不大。因此,我建议你先把C语言学好,学通。。再去学C++,最后学VC++。学C语言主要学算法,C++则主要掌握关于类,封装,虚函数,继承等。。再去学VC++,必定不能乱了顺序,又或者学的不精就转下一个,否则。。。你就知道什么真正的叫“困难”了。。
C#与Java的比较
C#(C-Sharp)是Microsoft的新编程语言,被誉为“C/C++家族中第一种面向组件的语言”。然而,无论它本身宣称的是什么,许多人认为C#更像是Java的一种克隆,或者是Microsoft用来替代Java的产品。事实是不是这样的呢?
本文的比较结果代表,C#不止是Java的同胞那么简单。若是你是一个Java开发者,想要学习C#或者了解更多有关C#的知识,那么本文就是你必须把最初10分钟投入于其中的所在。
C#的语言规范由Microsoft的Anders Hejlsberg与Scott Wiltamuth编写。在当前Microsoft天花乱坠的宣传中,对C#和C++、Java做一番比较老是颇有趣的。考虑到当前IT媒体的舆论倾向,若是你早就知道C#更接近Java而不是C++,事情也不值得大惊小怪。对于刚刚加入这场讨论的读者,下面的表1让你本身做出判断。显然,结论应该是:Java和C#虽然不是孪生子,但C#最主要的特点却更接近Java而不是C++。
了解表1总结的重要语言功能以后,请继续往下阅读,了解C#和Java的一些重要区别。
简单数据类型(Primitive)在C#中称为值类型,C#预约义的简单数据类型比Java多。例如,C#有unit,即无符号整数。表2列出了全部C#的预约义数据类型:
2.二、常量
忘掉Java中的static final修饰符。在C#中,常量能够用const关键词声明。
1 public const int x = 55;
此外,C#的设计者还增长了readonly关键词。若是编译器编译时未能肯定常量值,你可使用readonly关键词。readonly域只能经过初始化器或类的构造函数设置。
2.三、公用类的入口点
在Java中,公用类的入口点是一个名为main的公用静态方法。main方法的参数是String对象数组,它没有返回值。在C#中,main方法变成了公用静态方法Main(大写的M),Main方法的参数也是一个String对象数组,并且也没有返回值,以下面的原型声明所示:
public static void Main(String[] args)
可是,C#的Main方法不局限于此。若是不向Main方法传递任何参数,你可使用上述Main方法的一个重载版本,即不带参数列表的版本。也就是说,下面的Main方法也是一个合法的入口点:
public static void Main()
另外,若是你认为有必要的话,Main方法还能够返回一个int。例如,下面代码中的Main方法返回1:
1 using System; 2 public class Hello { 3 public static int Main() { 4 Console.WriteLine("Done"); 5 return 1; 6 }
与此相对,在Java中重载main方法是不合法的。
2.四、switch语句
在Java中,switch语句只能处理整数。但C#中的switch语句不一样,它还可以处理字符变量。请考虑下面用switch语句处理字符串变量的C#代码:
1 using System; 2 public class Hello { 3 public static void Main(String[] args) { 4 switch (args[0]) { 5 case "老板": 6 Console.WriteLine("早上好!咱们随时准备为您效劳!"); 7 break; 8 case "雇员": 9 Console.WriteLine("早上好!你能够开始工做了!"); 10 break; 11 default: 12 Console.WriteLine("早上好!祝你好运!"); 13 break; 14 } 15 } 16 }
与Java中的switch不一样,C#的switch语句要求每个case块或者在块的末尾提供一个break语句,或者用goto转到switch内的其余case标签。
2.五、foreach语句
foreach语句枚举集合中的各个元素,为集合中的每个元素执行一次代码块。请参见下面的例子。
1 using System; 2 public class Hello { 3 public static void Main(String[] args) { 4 foreach (String arg in args) 5 Console.WriteLine(arg); 6 } 7 }
若是在运行这个执行文件的时候指定了参数,好比“Hello Peter Kevin Richard”,则程序的输出将是下面几行文字:
1 Peter 2 Kevin 3 Richard
2.六、C#没有>>>移位操做符
C#支持uint和ulong之类的无符号变量类型。所以,在C#中,右移操做符(即“>>”)对于无符号变量类型和带符号变量类型(好比int和long)的处理方式不一样。右移uint和ulong丢弃低位并把空出的高位设置为零;但对于int和long类型的变量,“>>”操做符丢弃低位,同时,只有当变量值是正数时,“>>”才把空出的高位设置成零;若是“>>”操做的是一个负数,空出的高位被设置成为1。
Java中不存在无符号的变量类型。所以,咱们用“>>>”操做符在右移时引入负号位;不然,使用“>>”操做符。
2.七、goto关键词
Java不用goto关键词。在C#中,goto容许你转到指定的标签。不过,C#以特别谨慎的态度对待goto,好比它不容许goto转入到语句块的内部。在Java中,你能够用带标签的语句加上break或continue取代C#中的goto。
2.八、声明数组
在Java中,数组的声明方法很是灵活,实际上有许多种声明方法都属于合法的方法。例如,下面的几行代码是等价的:
1 int[] x = { 0, 1, 2, 3 }; 2 int x[] = { 0, 1, 2, 3 };
但在C#中,只有第一行代码合法,[]不能放到变量名字以后。
2.九、包
在C#中,包(Package)被称为名称空间。把名称空间引入C#程序的关键词是“using”。例如,“using System;”这个语句引入了System名称空间。
然而,与Java不一样的是,C#容许为名称空间或者名称空间中的类指定别名:
1 using TheConsole = System.Console; 2 public class Hello { 3 public static void Main() { 4 TheConsole.WriteLine("使用别名"); 5 } 6 }
虽然从概念上看,Java的包相似于.NET的名称空间。然而,二者的实现方式不一样。在Java中,包的名字同时也是实际存在的实体,它决定了放置.java文件的目录结构。在C#中,物理的包和逻辑的名称之间是彻底分离的,也就是说,名称空间的名字不会对物理的打包方式产生任何影响。在C#中,每个源代码文件能够从属于多个名称空间,并且它能够容纳多个公共类。
.NET中包的实体称为程序集(Assembly)。每个程序集包含一个manifest结构。manifest列举程序集所包含的文件,控制哪些类型和资源被显露到程序集以外,并把对这些类型和资源的引用映射到包含这些类型与资源的文件。程序集是自包含的,一个程序集能够放置到单一的文件以内,也能够分割成多个文件。.NET的这种封装机制解决了DLL文件所面临的问题,即臭名昭著的DLL Hell问题。
2.十、默认包
在Java中,java.lang包是默认的包,它无需显式导入就已经自动包含。例如,要把一些文本输出到控制台,你可使用下面的代码:
1 System.out.println("Hello world from Java");
C#中不存在默认的包。若是要向控制台输出文本,你使用System名称空间Console对象的WriteLine方法。可是,你必须显式导入全部的类。代码以下:
1 using System; 2 public class Hello { 3 public static void Main() { 4 Console.WriteLine("Hello world from C#"); 5 } 6 }
2.十一、面向对象
Java和C#都是彻底面向对象的语言。在面向对象编程的三大原则方面,这两种语言接近得不能再接近。
继承:这两种语言都支持类的单一继承,但类能够实现多个接口。全部类都从一个公共的基类继承。
封装与可见性:不管是在Java仍是C#中,你均可以决定类成员是否可见。除了C#的internal访问修饰符以外,二者的可见性机制很是类似。
多态性:Java和C#都支持某些形式的多态性机制,且二者实现方法很是相似。
2.十二、可访问性
类的每一个成员都有特定类型的可访问性。C#中的访问修饰符与Java中的基本对应,但多出了一个internal。简而言之,C#有5种类型的可访问性,以下所示:
public:成员能够从任何代码访问。
protected:成员只能从派生类访问。
internal:成员只能从同一程序集的内部访问。
protected internal:成员只能从同一程序集内的派生类访问。
private:成员只能在当前类的内部访问。
2.1三、派生类
在Java中,咱们用关键词“extends”实现继承。C#采用了C++的类派生语法。例如,下面的代码显示了如何派生父类Control从而建立出新类Button:
1 public class Button: Control { . . }
2.1四、最终类
因为C#中不存在final关键词,若是想要某个类再也不被派生,你可使用sealed关键词,以下例所示:
sealed class FinalClass { . . }
2.1五、接口
接口这个概念在C#和Java中很是类似。接口的关键词是interface,一个接口能够扩展一个或者多个其余接口。按照惯例,接口的名字以大写字母“I”开头。下面的代码是C#接口的一个例子,它与Java中的接口彻底同样:
1 interface IShape { void Draw(); }
扩展接口的语法与扩展类的语法同样。例如,下例的IRectangularShape接口扩展IShape接口(即,从IShape接口派生出IRectangularShape接口)
1 interface IRectangularShape: IShape { int GetWidth(); }
若是你从两个或者两个以上的接口派生,父接口的名字列表用逗号分隔,以下面的代码所示:
1 interface INewInterface: IParent1, IParent2 { }
然而,与Java不一样,C#中的接口不能包含域(Field)。
另外还要注意,在C#中,接口内的全部方法默认都是公用方法。在Java中,方法声明能够带有public修饰符(即便这并不是必要),但在C#中,显式为接口的方法指定public修饰符是非法的。例如,下面的C#接口将产生一个编译错误。
1 interface IShape { public void Draw(); }
2.1六、is和as操做符
C#中的is操做符与Java中的instanceof操做符同样,二者均可以用来测试某个对象的实例是否属于特定的类型。在Java中没有与C#中的as操做符等价的操做符。as操做符与is操做符很是类似,但它更富有“进取心”:若是类型正确的话,as操做符会尝试把被测试的对象引用转换成目标类型;不然,它把变量引用设置成null。
为正确理解as操做符,首先请考虑下面这个例子中is操做符的运用。这个例子包含一个IShape接口,以及两个实现了IShape接口的类Rectangle和Circle。
1 using System; 2 interface IShape { 3 void draw(); 4 } 5 public class Rectangle: IShape { 6 public void draw() { 7 } 8 public int GetWidth() { 9 return 6; 10 } 11 } 12 public class Circle: IShape { 13 public void draw() { 14 } 15 public int GetRadius() { 16 return 5; 17 } 18 } 19 public class LetsDraw { 20 public static void Main(String[] args) { 21 IShape shape = null; 22 if (args[0] == "rectangle") { 23 shape = new Rectangle(); 24 } 25 else if (args[0] == "circle") { 26 shape = new Circle(); 27 } 28 if (shape is Rectangle) { 29 Rectangle rectangle = (Rectangle) shape; 30 Console.WriteLine("Width : " + rectangle.GetWidth()); 31 } 32 if (shape is Circle) { 33 Circle circle = (Circle) shape; 34 Console.WriteLine("Radius : " + circle.GetRadius()); 35 } 36 } 37 }
编译好代码以后,用户能够输入“rectangle”或者“circle”做为Main方法的参数。若是用户输入的是“circle”,则shape被实例化成为一个Circle类型的对象;反之,若是用户输入的是“rectangle”,则shape被实例化成为Rectangle类型的对象。随后,程序用is操做符测试shape的变量类型:若是shape是一个矩形,则shape被转换成为Rectangle对象,咱们调用它的GetWidth方法;若是shape是一个圆,则shape被转换成为一个Circle对象,咱们调用它的GetRadius方法。
若是使用as操做符,则上述代码能够改为以下形式:
1 using System; 2 interface IShape { 3 void draw(); 4 } 5 public class Rectangle: IShape { 6 public void draw() { 7 } 8 public int GetWidth() { 9 return 6; 10 } 11 } 12 public class Circle: IShape { 13 public void draw() { 14 } 15 public int GetRadius() { 16 return 5; 17 } 18 } 19 public class LetsDraw { 20 public static void Main(String[] args) { 21 IShape shape = null; 22 if (args[0] == "rectangle") { 23 shape = new Rectangle(); 24 } 25 else if (args[0] == "circle") { 26 shape = new Circle(); 27 } 28 Rectangle rectangle = shape as Rectangle; 29 if (rectangle != null) { 30 Console.WriteLine("Width : " + rectangle.GetWidth()); 31 } 32 else { 33 Circle circle = shape as Circle; 34 if (circle != null) 35 Console.WriteLine("Radius : " + circle.GetRadius()); 36 } 37 } 38 }
在上面代码的粗体部分中,咱们在没有测试shape对象类型的状况下,就用as操做符把shape转换成Rectangle类型的对象。若是shape正好是一个Rectangle,则shape被转换成为Rectangle类型的对象并保存到rectangle变量,而后咱们调用它的GetWidth方法。若是这种转换失败,则咱们进行第二次尝试。这一次,shape被转换成为Circle类型的对象并保存到circle变量。若是shape确实是一个Circle对象,则circle如今引用了一个Circle对象,咱们调用它的GetRadius方法。
2.1七、库
C#没有本身的类库。可是,C#共享了.NET的类库。固然,.NET类库也能够用于其余.NET语言,好比VB.NET或者JScript.NET。值得一提的是StringBuilder类,它是对String类的补充。StringBuilder类与Java的StringBuffer类很是类似。
2.1八、垃圾收集
C++已经让咱们认识到手工管理内存是多么缺少效率和浪费时间。当你在C++中建立了一个对象,你就必须手工地拆除这个对象。代码越复杂,这个任务也越困难。Java用垃圾收集器来解决这个问题,由垃圾收集器搜集再也不使用的对象并释放内存。C#一样采用了这种方法。应该说,若是你也在开发一种新的OOP语言,追随这条道路是一种很是天然的选择。C#仍旧保留了C++的内存手工管理方法,它适合在速度极端重要的场合使用,而在Java中这是不容许的。
2.1九、异常处理
若是你据说C#使用与Java类似的异常处理机制,你不会为此而惊讶,对吧?在C#中,全部的异常都从一个名为Exception的类派生(听起来很熟悉?)另外,正如在Java中同样,你还有熟悉的try和catch语句。Exception类属于.NET System名称空间的一部分。
3、Java没有的功能
C#出生在Java成熟以后,所以,C#拥有一些Java(目前)尚未的绝妙功能也就不足为奇。
3.一、枚举器
枚举器即enum类型(Enumerator,或称为计数器),它是一个相关常量的集合。精确地说,enum类型声明为一组相关的符号常量定义了一个类型名字。例如,你能够建立一个名为Fruit(水果)的枚举器,把它做为一个变量值的类型使用,从而把变量可能的取值范围
1 public class Demo { 2 public enum Fruit { 3 Apple, Banana, Cherry, Durian 4 } 5 public void Process(Fruit fruit) { 6 switch (fruit) { 7 case Fruit.Apple: 8 ... 9 break; 10 case Fruit.Banana: 11 ... 12 break; 13 case Fruit.Cherry: 14 ... 15 break; 16 case Fruit.Durian: 17 ... 18 break; 19 } 20 } 21 }
在上例的Process方法中,虽然你能够用int做为myVar变量的类型,可是,使用枚举器Fruit以后,变量的取值范围限制到了Applet、Banana、Cherry和Durian这几个值以内。与int相比,enum的可读性更好,自我说明能力更强。
3.二、结构
结构(Struct)与类很类似。然而,类是做为一种引用类型在堆中建立,而结构是一种值类型,它存储在栈中或者是嵌入式的。所以,只要谨慎运用,结构要比类快。结构能够实现接口,能够象类同样拥有成员,但结构不支持继承。
然而,简单地用结构来取代类可能致使惨重损失。这是由于,结构是以值的方式传递,因为这种传递方式要把值复制到新的位置,因此传递一个“肥胖的”结构须要较大的开销。而对于类,传递的时候只需传递它的引用。
下面是一个结构的例子。注意它与类很是类似,只要把单词“struct”替换成“class”,你就获得了一个类。
1 struct Point { 2 public int x, y; 3 public Point(int x, int y) { 4 this.x = x; 5 this.y = y; 6 } 7 }
3.三、属性
C#类除了能够拥有域(Field)以外,它还能够拥有属性(Property)。属性是一个与类或对象关联的命名的特征。属性是域的一种天然扩展——二者都是有类型、有名字的类成员。然而,和域不一样的是,属性不表示存储位置;相反,属性拥有存取器(accessor),存取器定义了读取或者写入属性值时必须执行的代码。所以,属性提供了一种把动做和读取、写入对象属性值的操做关联起来的机制,并且它们容许属性值经过计算获得。
在C#中,属性经过属性声明语法定义。属性声明语法的第一部分与域声明很类似,第二部分包括一个set过程和/或一个get过程。例如,在下面的例子中,PropertyDemo类定义了一个Prop属性。
1 public class PropertyDemo { 2 private string prop; 3 public string Prop { 4 get { 5 return prop; 6 } 7 set { 8 prop = value; 9 } 10 } 11 }
若是属性既容许读取也容许写入,如PropertyDemo类的Prop属性,则它同时拥有get和set存取过程。当咱们读取属性的值时,get存取过程被调用;当咱们写入属性值时,set存取过程被调用。在set存取过程当中,属性的新值在一个隐含的value参数中给出。
与读取和写入域的方法同样,属性也能够用一样的语法读取和写入。例如,下面的代码实例化了一个PropertyDemo类,而后写入、读取它的Prop属性。
1 PropertyDemo pd = new PropertyDemo(); 2 pd.Prop = "123"; // set 3 string s = pd.Prop; // get
3.四、以引用方式传递简单数据类型的参数
在Java中,当你把一个简单数据类型的值做为参数传递给方法时,参数老是以值的方式传递——即,系统将为被调用的方法建立一个参数值的副本。在C#中,你能够用引用的方式传递一个简单数据类型的值。此时,被调用的方法将直接使用传递给它的那个值——也就是说,若是在被调用方法内部修改了参数的值,则原来的变量值也随之改变。
在C#中以引用方式传递值时,咱们使用ref关键词。例如,若是编译并运行下面的代码,你将在控制台上看到输出结果16。注意i值被传递给ProcessNumber以后是如何被改变的。
1 using System; 2 public class PassByReference { 3 public static void Main(String[] args) { 4 int i = 8; 5 ProcessNumber(ref i); 6 Console.WriteLine(i); 7 } 8 public static void ProcessNumber(ref int j) { 9 j = 16; 10 } 11 }
C#中还有一个容许以引用方式传递参数的关键词out,它与ref类似。可是,使用out时,做为参数传递的变量在传递以前没必要具备已知的值。在上例中,若是整数i在传递给ProcessNumber方法以前没有初始化,则代码将出错。若是用out来取代ref,你就能够传递一个未经初始化的值,以下面这个修改后的例子所示。
1 using System; 2 public class PassByReference { 3 public static void Main(String[] args) { 4 int i; 5 ProcessNumber(out i); 6 Console.WriteLine(i); 7 } 8 public static void ProcessNumber(out int j) { 9 j = 16; 10 } 11 }
通过修改以后,虽然i值在传递给ProcessNumber方法以前没有初始化,但PassByReference类可以顺利经过编译。
3.五、C#保留了指针
对于那些以为本身可以恰到好处地运用指针并乐意手工进行内存管理的开发者来讲,在C#中,他们仍旧能够用既不安全也不容易使用的“古老的”指针来提升程序的性能。C#提供了支持“不安全”(unsafe)代码的能力,这种代码可以直接操做指针,可以“固定”对象以便临时地阻止垃圾收集器移动对象。不管从开发者仍是用户的眼光来看,这种对“不安全”代码的支持实际上是一种安全功能。“不安全”的代码必须用unsafe关键词显式地标明,所以开发者不可能在无心之中使用“不安全”的代码。同时,C#编译器又和执行引擎协做,保证了“不安全”的代码不能假装成为安全代码。
1 using System; 2 class UsePointer { 3 unsafe static void PointerDemo(byte[] arr) { 4 . 5 . 6 } 7 }
C#中的unsafe代码适合在下列情形下使用:当速度极端重要时,或者当对象须要与现有的软件(好比COM对象或者DLL形式的C代码)交互时。
3.六、代理
代理(delegate)能够看做C++或者其余语言中的函数指针。然而,与函数指针不一样的是,C#中的代理是面向对象的、类型安全的、可靠的。并且,函数指针只能用来引用静态函数,但代理既可以引用静态方法,也可以引用实例方法。代理用来封装可调用方法。你能够在类里面编写方法并在该方法上建立代理,此后这个代理就能够被传递到第二个方法。这样,第二个方法就能够调用第一个方法。
代理是从公共基类System.Delegate派生的引用类型。定义和使用代理包括三个步骤:声明,建立实例,调用。代理用delegate声明语法声明。例如,一个不须要参数且没有返回值的代理能够用以下代码声明:
1 delegate void TheDelegate();
建立代理实例的语法是:使用new关键词,并引用一个实例或类方法,该方法必须符合代理指定的特征。一旦建立了代理的实例,咱们就能够用调用方法的语法调用它。
3.七、包装和解除包装
在面向对象的编程语言中,咱们一般使用的是对象。但为了提升速度,C#也提供了简单数据类型。所以,C#程序既包含一大堆的对象,又有大量的值。在这种环境下,让这二者协同工做始终是一个不可回避的问题,你必需要有一种让引用和值进行通讯的方法。
在C#以及.NET运行时环境中,这个“通讯”问题经过包装(Boxing)和解除包装(Unboxing)解决。包装是一种让值类型看起来象引用类型的处理过程。当一个值类型(简单数据类型)被用于一个要求或者可使用对象的场合时,包装操做自动进行。包装一个value-type值的步骤包括:分配一个对象实例,而后把value-type值复制到对象实例。
解除包装所执行的动做与包装相反,它把一个引用类型转换成值类型。解除包装操做的步骤包括:首先检查并确认对象实例确实是给定value-type的一个通过包装的值,而后从对象实例复制出值。
Java对该问题的处理方式略有不一样。Java为每一种简单数据类型提供了一个对应的类封装器。例如,用Integer类封装int类型,用Byte类封装byte类型。
【结束语】本文为你比较了C#和Java。这两种语言很类似,然而,说C#是Java的克隆或许已经大大地言过其实。面向对象、中间语言这类概念并非什么新东西。若是你准备设计一种面向对象的新语言,并且它必须在一个受管理的安全环境内运行,你难道不会搞出与C#差很少的东西吗?