C#语言是运行在.NET框架之上的,.NET框架由类库(FCL)和虚拟机(CLR)两个部分组成。我们使用.NET提供的标准类库来开发应用程序,然后应用程序需要在虚拟机(CLR)上运行。.NET类库提供了丰富的功能来支持windows应用和web应用的开发。C#语言从C/C++发展而来,它吸取了包括C++,Java,Delphi多种语言的精华,是一种简单易学的面向对象开发的高级语言。随着微软对.NET平台的推广,C#语言已经成为.NET平台最流行的开发语言。同时,微软的集成开发环境Visual Studio也对.NET平台做了大力的支持。C++语言和C#语言的一些区别如下:
1. 命名空间 namespace
很多的高级语言都有命名空间的概念,包括C++,C#和Java语言,他们都是为了解决重复命名的问题。C++和C#语言都使用namespace关键字来定义自己的命名空间,而Java则是使用package关键字。当我们自定义命名空间后,在使用对应的类或方法的时候,我们都需要在类和方法的前面使用自定义的命名空间,如果觉得每次都加上这个命名空间的前缀比较麻烦的话,我们可以引入这个命名空间,C++和C#语言使用关键字using来引入,而Java使用import关键字。可以看出,C++和C#基本保持一致,Java略有不同,但原理都一样。
2. C++编译性语言(include)
C++语言是编译性语言,因此它在编译的时候,需要明确应用程序所依赖的标准库或者第三方库。所以,我们在开发C++语言的时候,经常使用include来引入库文件,这是必须的。但是C#和Java的应用程序是运行在各自的虚拟机上,虚拟机就是一个提供程序运行的环境。因此C#和Java不需要像C++那样,先引入库文件再进行对应功能的开发。这一点,C#和Java是一样的。
3. C++声明和定义
在C++程序中有两种文件:h文件和cpp文件,他们都是源代码文件,h文件侧重于函数和类的声明,而cpp文件侧重于函数和类的定义,之后在其他文件中需要先引入头文件,才能正常使用函数和类。在C#程序中,只有一种cs源文件,并且函数和类的声明和定义基本上是在一起的。C#属于面向对象编程的语言,因此函数也基本上在类中被定义。从源文件以及声明和定义两项来看,C#语言比C++语言更加简单。
4. 操作符new的使用
C++中的new用于分配变量到堆区(动态内存),后期配合delete来释放该内存。它可以应用在基本数据类型,数组和对象上。而C#的new操作符主要用于实例化对象(分配内存),包括数组在内,这是必须的。C#语言中的对象不能像C++是那样按照基本类型的方式使用,这一点和Java非常的相似。例如:Person person 只是声明一个引用对象变量,使用new运算符实例化类对象后,通过给这个对象分配内存并返回一个指向该内存的引用。另外,使用C++语言进行程序开发,需要开发人员时刻记得在堆区中数据变量不使用的情况下,要释放掉。而C#语言由于运行在虚拟机上,C#的虚拟机提供了垃圾回收器,当程序执行到对象的作用域以外或者没有任何变量引用到实例化对象的时候,对象会自动被系统垃圾回收,因此不需要开发人员显示的delete销毁。Java语言也提供了垃圾回收机制,和C#语言是一样的原理。
备注:以上四点区别对于我们跨语言程序开发非常的关键!
以下介绍C#的数据类型,基本上和C++语言非常的相似,当然也有一些区别。
整数类型(整型):
sbyte 字节型 1个字节 -128 到 127
byte 无符号字节型 1个字节 0 到 255
short 短整型 2个字节 -32768 到 32767
ushort 无符号短整型 2个字节 0 到 65535
int 整型 4个字节
uint 无符号整型 4个字节
long 长整型 8个字节
ulong 无符号长整型 8个字节
C#的整数类型分为有符号和无符号两种,而C++使用单独的关键字unsigned来区分有无符号。有符号就是存储正负数,无符号就只能存储正数,无符号要比有符号存储正数值增加一倍。虽然所有语言都定义了很多的整数类型,但是我们经常用的就是int类型。
小数类型(浮点型/实数型)
float 单精度实数 4个字节 -3.4 x 10e38 到 3.4 x 10e38
double 双精度实数 8个字节 -1.7 x 10e308 到 1.7 x 10e308
decimal 十进制实数 16个字节
C#语言的decimal的浮点类型,有点类似于C++语言的long double类型,他们更多的应用于需要高精度计算的特别行业领域。一般情况下,我们使用double类型足以,float也凑合。另外,浮点型的计算可能存在误差,这不是语言造成的,而是处理器造成的,处理的方式也比较简单,就是四舍五入的保留足够的精确的小数位,具体保留几位小数由业务需求决定。
字符类型
char 字符类型 2个字节
C#语言的char相当于C++语言的wchar_t,它既可以存储字母,也可以存储汉字。我们讲过,所有的字符(字母或汉字)都是使用对应的二进制存储的,而二进制可以转化成十进制。因此C#语言的char类型等同于ushort类型,例如大写字母A是一个char类型,如果把字母A作为ushort类型输出的话,就是字母A的ASCII码65(十进制)。
字符串类型
C#语言中String表示字符串类型,它将一组字符视为一个整体进行处理。这和C++语言的wstring是差不多的。字符用单引号表示,字符串用双引号表示。我们知道字符数组同样也能处理字符串,有时候字符数组比String更有优势。当然字符串和字符数组也可以相互转换。字符串的操作(长度,比较,拼接,截取)是程序开发中经常使用的,需要大家熟练的掌握。
char a = '国';
Console.WriteLine(a);
char[] b = {'中','国' };
Console.WriteLine(b);
string c = "中国";
Console.WriteLine(c);
在.NET的虚拟机CLR中的所有字符都是UFT16编码。Encoding类位于System.Text命名空间中,主要用于在不同的编码和Unicode之间进行转换。利用Encoding类的Convert方法可将字节数组从一种编码转换为另一种编码。以下代码将UFT16字符串转换为UTF8字符串:
using System;
using System.IO;
using System.Text;
// Unicode字符串(UTF16)
string unicodeString = "unicode字符串";
// 保存到文件,默认保存编码格式UTF8
File.WriteAllText("./test1.txt", unicodeString);
// Unicode字符串转换为Unicode字节数组
Encoding unicode = Encoding.Unicode;
byte[] unicodeBytes = unicode.GetBytes(unicodeString);
// 将Unicode字节数组转换为UTF8字节数组
Encoding utf8 = Encoding.UTF8;
byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, unicodeBytes);
// 将UTF8字节数组解码为UTF8字符串
string utf8String = utf8.GetString(utf8Bytes);
// 保存到文件
File.WriteAllText("./test2.txt", utf8String);
// 输出控制台
Console.WriteLine(utf8String);
Console.ReadKey();
备注:我们使用notepad++打开保存的文件,然后查看其编码格式就是utf-8。UTF8是文本存储和传输的默认格式,因为它对大多数语言都是相对紧凑的格式。UTF16用于内存中的字符串,因为每个字符解析和直接映射到Unicode字符类和其他表的速度更快。WriteAllText和ReadAllText的默认编码格式uft-8的编码格式。
布尔类型
bool 布尔类型 1个字节
布尔类型只有两只值:true或false。C++语言bool变量的值用数字1和0表示。但是实际上,在所有高级语言中,也都把true等价于1(非0即可),false等价于0来对待。
结构体类型
C#语言使用struct来定义结构体,这和C++语言是一样的,但是他们的使用方式还有一些区别,C#语言的结构体更加的灵活。Java语言中没有结构体类型。
枚举类型
C#语言使用enum来定义枚举类型,这和C++语言是一样的,Java语言也是一样。他们的使用方式也都大致相同。
引用类型
C#语言可以将数据类型分为值类型和引用类型。值类型就是上面介绍的基本类型byte、short、int、long、float、double、char、boolean、struct、enum这些。引用类型等效于内存地址,主要用于数据传递过程中的同步数据修改的操作,尤其是函数的参数传递,它比指针安全一些。C#和Java语言都使用了引用类型,没有指针类型。
C#语言中的引用类型包括类(class),数组(array),接口(interface),委托(delegate)四种,其中字符串(string)属于类的范围。我们可以理解除了值类型之外的都属于引用类型。值类型的默认值都有确定的值,例如整型是0,字符型是’’等等,而引用类型的默认值是NULL值。值类型和引用类型可以通过装箱/拆箱来进行转换,装箱转换是从值类型到引用类型的转换,拆箱则是引用类型到值类型的转换。C#语言和Java语言在引用类型的使用上比较相似,他们直接使用数据类型来区分是否引用类型,而C++语言中则使用操作符&来定义引用类型。
数组
数组是指同一类型的数据集合,使用下标访问数组中的每个元素成员,数组下标从0开始。数组在初始化之后长度就是固定的。基本上所有的高级语言的数组使用都是相似的。
// 定义一个数组
int[] d = new int[10];
d[0] = 1;
Console.WriteLine(d[0]);
// 定义一个数组,并初始化
int[] e = new int[] {1,2,3,4,5,6 };
Console.WriteLine(e[0]);
// 定义一个数组,并初始化
int[] f = { 1, 2, 3, 4, 5, 6 };
Console.WriteLine(f[0]);
// 定义多维数组
int[,] g = new int[2,3];
int[,] h = new int[,] { { 1,2,3 },{ 4,5,6 } };
int[,] i = { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine(i[0,0]);
备注:C#使用中括号加逗号的方式来使用多维数组,C++和Java则只使用中括号来使用多维数组。这一点有一些区分。这些区分其实不太会影响开发人员跨语言程序开发的。
C#数据类型转化有很多方式,也是需要我们掌握和使用的。
// 隐式转换,数据兼容
int _a = 10;
double _b = _a;
Console.WriteLine(_b);
// 显式转换,强制转换,数据可能丢失
float _c = 3.14f;
int _d = (int)_c;
Console.WriteLine(_d);
// 数值性转字符型
int _e = 100;
string _f = _e.ToString();
Console.WriteLine(_f);
// 字符型转数值型,可能存在异常
string _g = "200";
int _h = int.Parse(_g);
Console.WriteLine(_h);
// 字符型转数值型,不能转换返回0
int _i;
string _j = "abc";
int.TryParse(_j, out _i);
Console.WriteLine(_i);
// Convert类常用的类型转换方法
//Convert.ToInt32() 转换为整型(int)
//Convert.ToChar() 转换为字符型(char)
//Convert.ToString() 转换为字符串型(string)
//Convert.ToDateTime() 转换为日期型(datetime)
//Convert.ToDouble() 转换为双精度浮点型(double)
//Conert.ToSingle() 转换为单精度浮点型(float)
教学案例源代码下载:
https://download.csdn.net/download/konkon2012/23471862
备注:这是我们游戏开发系列教程的第一个课程,主要是编程语言的基础学习,优先学习C++编程语言,然后进行C#语言,最后才是Java语言,紧接着就是使用C++和DirectX来介绍游戏开发中的一些基础理论知识。我们游戏开发系列教程的第二个课程是Unity游戏引擎的学习。课程中如果有一些错误的地方,请大家留言指正,感激不尽!