C#学习笔记3——数据类型

C#的数据类型可以分为3类:数值类型,引用类型,指针类型.指针类型仅在不安全代码中使用.
值类型包括简单类型(如字符型,浮点型和整数型等),集合类型和结构型.引用类型包括类类型,接口类型,代表类型和数组类型.
值类型和引用类型的不同之处是值类型的变量值直接包含数据,而引用类型的变量把它们的引用存储在对象中.对于引用类型的变量,完全有可能让两个不同的变量引用同一个对象,这样一来,对其中一个变量的操作就会影响到被另一个变量引用的对象.对于值类型的变量而言,每一个变量有它们自己的数值,因此对其中一个变 量的操作不可能影响到另外一个变量.


 

一、值类型
所有的值类型都隐含地声明了一个公共的无参数的构造函数,这个构造函数叫做默认构造函数.默认构造函数返回一个初始为零的值类型的实例,称之为默认值.
对于sbyte,byte,short,ushort,int,uint,long,ulong
,默认值为0.
对于char,默认值是'"x0000'
对于float,默认值是0.0F
对于double,默认值是0.0D
对于decimal,默认值是0.0M
对于bool,默认值是false
对于一个枚举类型,默认值是0
对于一个结构类型,默认值的设置就是把所有值类型的域都设置为它们各自的默认值,把所有的引用类型的域赋为空
简单类型
C#提供一套预定义的结构类型叫做简单类型.简单类型用保留字定义,这些保留字仅仅是在System名字空间里预定义的结构类型的化名.比如int是保留字,System.Int32是在System名字空间中预定义类型.一个简单类型和它化名的结构类型是完全一样的,也就是说写int和写System.Int32是一样的.
简单类型主要有整型,浮点类型,小数类型,布尔类型,字符型
整型
C#中支持9种整型:sbyte,byte,short,ushort,int,
uint,long,ulong和char.
Sbyte:代表有符号的8位整数,数值范围从-128 ~127
Byte:代表无符号的8位整数,数值范围从0~255
Short:代表有符号的16位整数,范围从-32768 ~32767
ushort:代表有符号的16位整数,范围从-32768 ~32767
Int:代表有符号的32位整数,范围从-2147483648 ~2147483648
uint:代表无符号的32位整数,范围从0 ~4294967295
Long:代表有符号的64位整数,范围从
-9223372036854775808 ~ 9223372036854775808
Ulong:代表无符号的64位整数,范围从
0 ~ 18446744073709551615
.
char:代表无符号的16位整数,数值范围从0~65535.
Char类型的可能值对应于统一字符编码标准(Unicode)的字符集.
Char类型与其他整数类型相比有以下两点不同之处:
1,没有其他类型到char类型的隐式转换.即使是对于sbyte,byte和ushort这样能完全使用char类型代表其值的类型, sbyte,byte和ushort到char的隐式转换也不存在.
2,char类型的常量必须被写为字符形式,如果用整数形式,则必须带有类型转换前缀.比如(char)10
赋值形式有三种:
char chsomechar=’A’;
char chsomechar=’\x0065’; 十六进制
char chsomechar=’\u0065’;unicode表示法
字符型中有下列转义符:
1,\'用来表示单引号
2,\"用来表示双引号
3,\\ 用来表示反斜杠
4, \0 表示空字符
5, \a 用来表示感叹号
6, \b 用来表示退格
7, \f 用来表示换页
8, \n 用来表示换行
9, \r 用来表示回车
10, \t 用来表示水平tab
11, \v 用来表示垂直tab
浮点类型
C#支持两种浮点类型:float和double.
Float型所能表示的值的范围大约可以从1.5*10 -45~3.4*10 38,精确到小数点后面7位.Double型所能表示的值的范围大约可以从5.0*10 -324~1.7* 10 308,精确到小数点后面15位或16位.
如果二元操作中的其中一个操作数为浮点类型,那么另外一个操作数是整型或浮点类型,运算规则如下:
1,如果其中一个操作数是整型,则操作数被转换为另一个操作数的浮点数类型;
2,如果操作数之一为double,则另一操作数也被转换成double类型,运算以double类型的精度和取值范围进行,并且所得结果也为double类型;
3,否则,运算至少将以float类型的取值范围和精度进行,并且所得结果也为float型.
小数(decimal)类型
小数类型非常适用于金融和货币运算.数值范围从1.0*10 -28~7.9*10 28,精确到小数点后面28位.
如果二元操作中的其中一个操作数是小数类型,那么另外一个从操作数是整型或小数类型.整型在运算前被转化为小数类型数.
如果一个小数类型的算术运算产生了一个对于小数类型的格式来说太小的值,操作的结果将会变成0.
如果一个小数类型的算术运算产生了一个对于小数类型的格式来说太大的值,就会触发溢出错误.小数类型较浮点类型而言,具有更大的精确度,但是数值范围相对小了很多.将浮点类型的数向小数类型的数转化时会产生溢出错误,将小数类型的数向浮点类型的数转化时会造成精确度的损失.因此,两种类型不存在隐式或显式转换.
布尔型:值为true或false.没有标准能实现布尔类型
和其他类型的转换.
枚举类型:枚举类型的元素使用的类型只能是long,
int,short,byte.默认类型是int.默认第一个元素的值是0,每一个连续的元素按1递增.可以给元素直接赋值.如:
enum monthnames {January=1,February, march=31};
可以强制定义其他类型,如:
enum monthnames : byte{January ,February,March};
结构类型
结构类型也是一种值类型,使用它的目的是用于创建小型的对象,用以节省内存.下面的例子表示一个使用byte类型的4个字段的IP地址.
using System;
Struct IP //声明结构
{ public byte b1,b2,b3,b4;}
Class test
{public static void Main()
{
IP myIP;
myIP.b1=192;
myIP.b2=168;
myIP.b3=1;
myIP.b4=101;
Console.Write("{0}.{1}.", myIP.b1, myIP.b2);
Console.Write("{0}.{1}", myIP.b3, myIP.b4);
}
}


二、引用类型
引用类型包括类类型,接口类型,代表类型和数组类型.
1,类类型
类 类型定义了一种数据结构,这个数据结构中包含了数据成员(如常量,字段和事件等),函数成员(如方法,属性,索引,操作,构造函数和析构函数等)和嵌套 类型.支持继承.
2,对象类型
对象类型是其他所有类型最终的基础类型.在C#中每一种类型都直接或者间接的源于object这个类类型.
3,字符串类型
字符串类型是直接从object中继承而来的密封类.String类型的值可以写成字符串文字的形式.
4,接口类型
一个接口声明一个只有抽象成员的引用类型,接口仅仅存在方法标志,但没有执行代码.当定义一个类时,如果类从接口派生,可以派生自多重接口;但是如果类从类派生,就只能从一个类派生.
声明方法如例:interface iface
{
void showmyface();
}
5,代表类型
代表引用一种静态的方法或者对象实例,引用该对象的实例方法.与其接近的是c/c++中的指针,但指针只能访问静态的函数,代表既能访问静态的方法,也能访问实例的方法.
6,数组
数组是包含一串变量的数据结构.数组变量也称做数组元素,它们具有相同的类型,这种类型也称做数组元素类型.数组的元素类型可以是任何类型,包括数组类型.数组用下标确定每一个数组元素的索引号.只有一个下标的数组称为一维数组,多于一个下标的数组称为多维数组.
例:int[]a={0,2,4,6,8}; 等价于int[] a=new int[] {0,2,4,6,8};
也可以这样初始化:a[0]=0; a[1]=2; a[2]=4; a[3]=6; a[4]=8;
int[] a; //int型的一维数组
int[,] a; //int型的二维数组
int[,,] a; //int型的三维数组
int[] []a; //int型的数组的数组
int[][][]a; //int型的数组的数组的数组
数组的每个维数的长度不是数组类型的一部分,维数的长度是在数组创建语句中指定的,而不是在数组类型中指定的,例如:
int[,,] a3=new int[10,20,30];
a3是是一个数组变量, int[,,] 没有指定数组的长度,数组创建语句new int[10,20,30]才指定.下面的例子创建一个数组的数组:
int[][] J=new int[3][];
J[0]=new int[] {1,2,3};
J[1]=new int[] {1,2,3,4,5,6};
J[2]=new int[] {1,2,3,4,5,6,7,8,9};


加框和消框
boxing和unboxing允许把任何值类型的值转化为对象(object)类型,或者把object类型转化为值类型,这样它就把值类型和引用类型紧密的结合起来了.简单的说,加框操作就是数值类型转换为类型对象,消框操作就是类型对象转换为数值类型.
1,加框操作
给一个值加框指隐式地把任何数值类型转换成类型对象.当一个数值类型被加框时,一个对象实例就被分配,而且数值类型的值复制给新的对象.
如:intn=200;
object o=n; //加框操作
o=201;
Console .WriteLine("{0}{1}",n,o);
改变o值,n的值不变
2,消框是显式操作-必须告诉编译器,想从对象中抽取出哪一种值类型.当执行消框操作时,C#检测所请求的值类型是否存储在对象实例中.
如:
int n=200;
object o=n;
int u=(int) u; //消框转化


操作符
1,括号操作符
格式()
2,点操作符
格式(E.I)
其中E是基本表达式或者预定义类型,I是一个标识符.C++里除了"."之外还有"::""->",C#里用点操作符来代替.比如一个类T有成员变量M,在C++里用T::M来引用,C#里用T.M来引用.
另一点不同的是,C#里预定义类型也是从Object类派生出来的,因此也定义了成员变量,比如,I是一个short类型的变量,那么I.ToInt()操作将返回一个Int类型的值.
3,后缀加减操作符
格式:p++;p--;++p; --p;
结果是给变量p加1或减1
4,new操作符
格式:a,new 类型(参数列表)
b,new 数组类型初始化列表
c,new 代表类型(表达式)
5,typeof操作符
该操作返回一个类型对应的system.type,如:typeof(int); typeof(System.Int32);typeof(string);各自的结果为int32,int32,string.typeof只对类型操作,不能对变量操作,例如,"int I;typeof(I);"是不合法的

6,sizeof操作符
该操作可获得一个类型所占用的空间大小,以字节为单位.该操作符用在unsafe模块中,如
Unsafe{
S=sizeof(int);
}
或者在调用该操作符的函数中使用该前缀.
7,单目操作符
(1)+-操作
(2)逻辑非:!(表达式)
(3)位非:~(表达式)
(4)强制类型转换: (T) 表达式
8,关系运算符
==,!=,,=, is
is用来判断一个变量是否是某一类型,例如,s is string
9,位逻辑操作符
&(位与),|(位或),^(异或).可以对整数,布尔,和枚
举类型进行这三种操作.
10,条件逻辑操作符
包括&&(与)和||(或)
11,条件运算符
b x:y
b为真,结果是x,否则是y
语句
1,语句块
格式:{语句列表}
2,空语句
格式:;
3,标签语句
格式:标识:语句
标签语句可以通过goto语句来引用.标签不会和变量混淆,例如:
int F(int x){
if (x>=0) goto x;
x=-x;
x: return x;
}
上面的代码中x既是一个标签也是一个变量,两者不会冲突.
4,if语句
格式:if(布尔表达式)嵌入语句[else嵌入语句]
5,switch语句
格式:switch(表达式){
case 常量表达式:嵌入语句
[default: 嵌入语句]}
必须用break强迫退出switch语句,另外如果企图执行完case 0语句后,继续执行后面的语句则须使用goto语句.
如:switch(i){
case 0:
casezero();
goto case1;
case1:
caseone();
goto default;
default:
caseothers();
break;
}
6,while语句
格式:while(布尔表达式)嵌入语句
7,do…while语句
格式:do嵌入语句while(布尔表达式)
8,for语句
格式:for([初始化];[布尔表达式];[重复语句])嵌入
语句
9,foreach语句
foreach语句列举出聚集的元素,并为每一个聚集的元素执行一条嵌入语句.
格式:foreach(类型 标识in 表达式)嵌入语句
using System;
public class foreachapp
{ public static void Main()
{ int odd=0,even=0;
int[] arr=new int[] {0,1,2,5,7,8,11};
foreach (int i in arr)
{ if (i%2==0)
even++;
else
odd++;
}
}
}
10,break语句
break语句用于退出最近的包含它的switch,while,do,
For或foreach语句.
11,continue语句
continue语句开始重复执行新的最近的包含它的
whilewhile,do,For或foreach语句.
12,goto语句
goto语句用于将控制权传递给由标号表明的语句.
13,return语句
Return语句将控制权返回给包含该return语句的函数成员的调用程序.

 14,C#之中参数类型分为4种:
  1).  无:默认的,普通参数
  2).  params:不定长参数
  3).  out:输出变量
  4).  ref:引用传递

普通参数,当参数是值类型时传值,当参数为引用类型时传址,这个由于各类C#的书都一定会讲,此处略过。

params类型的参数搭配数组使用,实现一个不定长的数组参数
最常用的应该是Console.WriteLine,其中有一个重载如下:
public static void WriteLine(string FormatString, params object[] values);
常见的调用方式:Console.WriteLine("宽:{0},高:{1}",this.Width,this.Height);
前面的"宽:{0},高:{1}"被装入FormatString
this.Width,this.Height被装入values[0]和values[1]之中,如果我们再加几个参数上去,那将按下标继续存入数组中。

out类型的参数做为输出参数使用,用于一个方法返回多个值类型的变量,一般对值类型使用。

若要使用 out参数,则方法定义和调用方法都必须显式使用 out关键字。 
定义方法:
void Test(out int v1,out float v2)
{
    v1 = 1;
    v2 = 0.5f;
}
调用方法:
   int a;
   float b;
   Test(out a,out b);


ref类型的参数是指在将一个变量做为一个参数传递给某个方法的时候,使用引用传递。
如果变量是值类型的话,ref和out起的效果是一样,只是ref参数在使用前必须先赋值,而out不用。 若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
定义方法:
void Test(ref int v1,ref float v2)
{
     v1 = 1;
     v2 = 0.5f;
}
调用方法:
  int a = 0;
  float b = 0;
  Test(ref a,ref b);

ref比较容易混淆的地方在于如果参数是引用类型的变量时,处理的结果与直接传一个引用类型变量有什么区别?
测试类:
public class Class1
{
  public int X = 0;
  public int Y = 5;
}
定义方法:
private void Test(Class1 c)
{  //直接传引用类型
    c.Y = 10;
    c.X = 10;
    //非ref传递,这句改不了引用的内存空间
    c = new Class1();
}
private void Test(ref Class1 c)
{  //通过ref传引用,允许被调用的方法修改 该引用 所 引用的对象,因为引用本身是按引用来传递的。
    c.Y = 10;
    c.X = 10;   
    //c通过ref传递,这里c会变成一个新的Class1
    c = new Class1();
}
调用方法:
  Class1 a = new Class1();
  Test(a);
  Console.WriteLine("X:{0},Y:{1}",a.X,a.Y);
  Class1 b = new Class1();
  Test(ref b);
  Console.WriteLine("X:{0},Y:{1}",b.X,b.Y);
输出结果:
  X:10,Y:10
  X:0,Y:5
通过输出结果我们可以看到使不使用ref的区别
用ref的话,c可以更改指向,从而放弃它原来所引用的那块内存空间 ;如果不用的话,只能改c内存空间中的数据,不可以更改指向。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byxdaz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值