C#的数据类型可以分为两类:值类型和引用类型。
值类型直接存放真正的数据,每个值类型都有自己固定的长度,比如int类型占用4个字节。值类型的变量保存在堆栈中,因此对一个变量的操作不会影响其他变量。值类型可以分为3大类:基本型、结构型、枚举型。
引用类型存储的是数据的内存地址,位于受管制的堆上。堆用于存储可变长度的数据,比如字符串类型。作为引用类型的变量可以引用同一个对象,因此对一个变量的操作会影响引用相同对象的另一个变量。引用类型包括:类、接口、数组、委托等。
值类型和引用类型的区别
特性 | 值类型 | 引用类型 |
变量中存放 | 真正的数据 | 指向数据的引用指针 |
内存空间配置 | 堆栈 | 受管制的堆 |
内存需求 | 较少 | 较多 |
执行效率 | 较快 | 较慢 |
内存释放时间点 | 执行超过定义变量的作用域时 | 由垃圾回收机制负责回收 |
是否可以为null | 不可以 | 可以 |
1 值类型
C#的值类型可以分为3大类:
基本型:包括整型、浮点型、小数型、布尔型,这些类型与其他语言的基本数据类型相似。
结构型:适用于创建小型对象。
枚举型:除char类型以外的其他常数组成的列表类型。
1.1整型
C#中有9个整型。
1.1.1 int型
int型为32位有符号整数。取值范围在-2,147,483,648~2,147,483,647之间。如:
int i=123;
int j
也可以写为:
System.Int32 i=123;
int j;
注意:如果定义时未进行初始化,就必须在使用前先赋值,因为C#不允许使用未初始化的变量,否则会在编译时报错。
1.1.2 long型
long型为64位有符号整数,范围在-9,223,372,036,854,775,808~9,223,372,036,854,775,807之间。例如:long myLong=123L;
或者:
long myLong=123; //int型隐式转换为long型
1.1.3 char型
char型为单一的Unicode字符(16位),可以用来表示世界上大部分文字。例如:char myChar='A'; //用单引号括起来
char myChar='\x0041' //字母A的十六进制表示
char myChar='\u0041' //字母A的Unicode表示
C#中也可以使用转义符,常用的有:
\' 单引号 0x0027 \" 双引号 0x0022
\\ 反斜线 0x005C \0 Null 0x0000
\a 发出一声警告0x0007 \b 退格 0x0008
\n 新的一行(换行) 0x000A \r 回车 0x000D
1.1.4 sbyte 型
sbyte型为8位有符号整数。取值范围在-128~127之间。1.1.5 byte型
byte型为8位无符号整数,取值范围在0~255之间。1.1.6 short型
short型为16位有符号整数,取值范围在-32,768~32,767之间。1.1.7 ushort型
ushort型为16位无符号整数,取值范围在0~65,535之间。1.1.8 uint型
uint型为32位无符号整数,取值范围在0~4,294,967,295之间。
1.1.9 ulong型
ulong型为64位无符号整数,取值范围在0~18,446,744,073,709,551,615之间。
1.2 浮点型
C#中有两种浮点型,float型和double型。
1.2.1 float型
fkoat型为32位浮点数,取值范围在1.5×10
-45~3.4×10
38之间,精度为7位数。例如:
float myFloat=2.3F;
1.2.2 double 型
double型为64位浮点数,取值范围在5.0×10 -324~1.7×10 308之间,精度为15~16位数。例如:double myDouble=2.7E+23; //2.7×1023
1.3小数型
小数型即decimal型,共128位,它所表示的范围大约为1.0×10 -28~7.9×10 28,具有28~29位有效数字,特别适用于金融、货币等领域。例如:decimal myMoney=300.5m;
decimal y=99999999999999999999999999999m;
decimal x=123.123456789123456789m;
1.4布尔型
布尔型用bool表示,bool型只有两个值:true和false。例如:bool myBool=false;
bool b=(i>0 && i<10);
注意:布尔型的true并不像c/c++中表示de非零值。在C#的条件表达式中,结果必须是bool型。例如:
int i=5;
if(i) {......}
是错误的用法,正确的用法应该是:
if(i==0) {......}
1.5struct型
结构(struct)是一种符合类型,它是由许多不同类型组织在一起而成的,如:int、string等。结构和类的区别在于,结构是一个值类型(在栈上),而类是一个引用类型(在堆上)。结构中可以包含构造函数、常数、字段、方法、属性、索引、操作符和嵌套类型。声明struct型的语法形式为:
[附加声明] [访问修饰符] struct 结构名称[:实现的接口] 结构体[;]
[ ]表示其中的内容为可选项。
【例】声明和使用struct
输出结果:
using System;
namespace ConsoleTest
{
public struct Point
{
public int x;
public int y;
public string s;
}
public struct Point1
{
public static int x;
public static int y;
public static string s;
}
class TestStruct
{
public static void Main()
{
Point p;
p.x=3;
p.y=4;
p.s="ok";
Console.WriteLine("The result is {0},{1},{2}",p.x,p.y,p.s);
Point1.x=1;
Point1.y=2;
Point1.s="good";
Console.WriteLine("The result is {0},{1},{2}",Point1.x,Point1.y,Point1.s);
}
}
}
The result is 3,4,ok
The result is 1,2,good
1.6 enum型
枚举(enum)是一组命名常量的聚合,称为枚举成员列表。每一种枚举类型都有一种基本类型,除char外的所有整型均可作为枚举型的基本类型。可以使用枚举给值指定易于记忆的名称,从而使代码更清晰,也易于维护。
声明enum类型变量的语法为:
[附加声明] [访问修饰符] enum 变量名称[:数据类型]{ 枚举列表 }
[ ]表示其中的内容为可选项。如果不指明数据类型,则默认为整型。常用形式:
enum days {Sun,Mon,Tue,Wed,Thu,Fri,Sat}; //Sun:0,Mon:1,Tue:2...
enum days {Mon=1,Tue,Wed,Thu,Fri,Sat,Sun} //第一个成员值从1开始
enum days {mon=1,wed=3,sun,thu=8} //mon:1,wed:3,sun:4,thu:8
注意,下列写法是错误的:
enum num:byte{x1=255,x2}
这是因为x1=255,x2应该是256,而byte型的范围是0~255.
但是可以这样写:
enum num:byte{x1=254,x2}
【例】使用enum型。
using System;
class Test
{
enum days{Sun,Mon,Tue,Wed,Thu,Fri,Sat};
static void Main()
{
Console.WriteLine(days.Wed);
days myday=days.Fri;
Console.WriteLine(myday);
}
}
Wed
Fri
2 数组
数组和结构不同,结构一般用于存储多种类型的数据,而数组则用于存储同一种类型的数据。数组是一种引用类型,而不是值类型。C#中可以有一维数组、多维数组、锯齿数组等。
声明一维数组的语法为:
数据类型[ ] 数组变量;
例如:
int[] myArray;
声明二维数组的语法为:
数据类型[,] 数组变量;
例如:
例如:
int[,] myArray;
声明三维数组的语法为:
数据类型[,,] 数组变量;
例如:
例如:
int[,,] myArray;
声明锯齿数组的常用形式为:
数据类型[ ] [ ] 数组变量;
例如:
例如:
int[][] myArray;
【例】数组的常用形式和使用方法。
using System;
namespace ConsoleTest
{
class TestArray
{
public static void Main()
{
//一维数组
string[] strArray1 = {"C","C++","C#"};
string[] strArray2=new string[3];
int[] intArr1 = new int[4]{0,1,2,3};
int[] intArr2={5,6,7};
int nVar = 5;
int[] arrToo = new int[nVar];
//二维数组
int[,] myArr1 = {{0,1},{2,3},{4,5}};
int[,] myArr2 = new int[2,3]{{11,12,13},{21,22,23}};
//锯齿数组锯齿shuzu锯齿数组数组
string[][] stra = new string[3][];
stra[0] = new string[2]{"a11","a12"};
stra[1] = new string[3]{"b11","b12","b13"};
stra[2] = new string[5]{"a","e","i","o","u"};
//输出一维数组的元素
for(int i=0;i
输出结果为:
strArry1[0]=C strArray1[1]=C++ strArray1[2]=C#
myArr1[0,0]=0 myArr1[0,1]=1
myArr1[1,0]=2 myArr1[1,1]=3
myArr1[2,0]=4 myArr1[2,1]=5
stra[0][0]=a11 stra[0][1]=a12
stra[1][0]=b11 stra[1][1]=b12 stra[1][2]=b13
stra[2][0]=a stra[2][1]=e stra[2][2]=i stra[2][3]=o stra[2][4]=u
3 数据类型之间的转换
数据类型可以相互转换,比如将int型的变量转换为long型,C#可以使用两种转换方式:显式转换与隐式转换。
书写一个常数时(如23),默认为整数,若要表示非整型,可以用显式转换。例如:
sbyte k=1;
int i=2;
k=(sbyte)i; //显式转换
i=k; //隐式转换
在整型之间进行转换时,小范围类型可以隐式转换为大范围类型,但大范围类型转换为小范围类型时需要使用显式转换。
注意:把大范围类型de数据转换为小范围类型的数据时,必须特别谨慎,因为此时有丢失数据的危险。而把小范围类型的数据赋给大范围类型变量一般没有问题,这是因为大范围类型的变量具有足够的空间存放小范围类型de数据。
也可以使用Convert类进行转换。
【例】显式转换和隐式转换。
using System;
class Test
{
public static void Main()
{
int i=10;
long j=20;
double k=30D;
//隐式转换
j=i;
k=j;
Console.WriteLine("{0},{1},{2}",i,j,k);
k=30.6D;
//显式转换
j=(long)k;
i=(int)j;
Console.WriteLine("{0},{1},{2}",i,j,k)
}
}
输出结果为:
10,10,10
30,30,30.6